Base URL
https://app.dmu.email/api/v1
Authentication
Bearer dmk_… API key
Rate limit
120 requests a minute per key

Bulk update contacts

POST/contacts/bulk

Creates or changes up to 1,000 contacts by their address in one call, each on its own.

Needs the permissioncontacts:write

Each item is written as Update a contact by email would write it, and the answer has one result per item, in the order sent. One item failing doesn’t stop the others.

Items are saved 100 at a time. If a batch couldn’t be saved, its items answer not_done, and you can simply send them again.

Every item counts against 5,000 a minute per key. One bulk call runs at a time per person and two per organisation, imports in the app included. Otherwise the answer is 429 busy with Retry-After: 30.

The body can be up to 8 MB. An item with a custom field your organisation doesn’t have answers error with unknown_field, and the others are still written.

Body

contactslistrequired
Up to 1,000 contacts, each with its email and the other fields Create a contact takes.

Returns

A list with a result for each item:

indexnumber
Its place in what you sent, from 0.
statusstring
created, updated, unchanged or error.
idstring
The contact, unless status is error.
codestring
With error: why, as the errors below, or not_done for an item to send again. message says it in words.

Errors

400bad_request
The body isn’t { "contacts": [ … ] }.
400too_many
More than 1,000 items.
401invalid_key
The key is wrong, expired or revoked. With no Authorization header at all, the code is missing_credentials.
403missing_scope
The key doesn’t have contacts:write. The X-Required-Scope header names what’s missing.
413too_large
The request body is over 8 MB.
429rate_limited
More than 120 requests a minute from this key. Wait for Retry-After seconds.
429rate_limited
More than 5,000 items this minute. Retry-After says when to try again.
429busy
Another bulk call or import is running. Try again after Retry-After, 30 seconds.
curl https://app.dmu.email/api/v1/contacts/bulk \
  -X POST \
  -H "Authorization: Bearer dmk_7f3a9c2e1b4d_Xq8v…" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      {
        "email": "anna@papadakis-acc.gr",
        "fields": { "customer_number": "ΠΕΛ-0412" }
      },
      {
        "email": "giorgos@kyma-logistics.gr",
        "firstName": "Γιώργος",
        "company": "Kyma Logistics"
      }
    ]
  }'

Response

200 OK

{
  "data": [
    {
      "index": 0,
      "status": "unchanged",
      "id": "3d7a51c2"
    },
    {
      "index": 1,
      "status": "created",
      "id": "6b02e9d4"
    }
  ]
}

Every response wraps its result in data. A page of threads adds nextCursor, which is null on the last page.