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

Create a contact

POST/contacts

Adds a contact. What a key writes is your CRM’s: the app shows those fields read only.

Needs the permissioncontacts:write

To keep a CRM in step without first asking whether a contact exists, use Update a contact by email instead.

A field you leave out is untouched, and null or an empty string clears it. Text is put on one line and trimmed. A custom text field holds up to 1,000 characters.

Custom fields by kind: a Number takes a comma as the decimal point too; a Date starts YYYY-MM-DD, and anything after is dropped; a Choice matches one of its choices, ignoring case; a Person takes a colleague’s address or user id and is returned as their address. A key your organisation doesn’t have fails the whole item.

What the API writes is locked in the app, which shows it read only: the CRM is the source of truth. Sending the value a field already has doesn’t lock it, and clearing a field with null unlocks it.

Shared and personal contacts are kept apart, so the same address can be one shared contact and one personal one.

Notes aren’t in the API. They never leave DMU Mail.

Body

emailstringrequired
Its address, unless you send emails.
emailslist of stringsoptional
Replaces every address, up to 10. Repeats are dropped, ignoring case. The first is its key.
phonestringoptional
Replaces the first phone number only.
phoneslist of stringsoptional
Replaces every phone number, up to 10, each up to 50 characters of digits, spaces and + ( ) - . / # * x.
firstNamestringoptional
Or lastName, company, jobTitle: up to 200 characters each.
fieldsobjectoptional
Custom fields by key, merged one by one: a key you leave out is untouched. Each must already exist in DMU Mail. See the notes for each kind.
visibilitystringoptional
shared (the default), or personal on a key that includes personal contacts.

Returns

The contact, as List contacts describes it, with 201 Created.

Errors

400email_required
Neither email nor emails was sent.
400invalid
A value is wrong, such as an address or a phone number. The error’s field says which.
400unknown_field
fields has a key your organisation doesn’t have. fields lists them.
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.
403personal_not_allowed
A personal contact, on a key that doesn’t include personal contacts.
409duplicate
Another contact has that address. The error has its contactId.
413too_large
The request body is over 256 KB.
429rate_limited
More than 120 requests a minute from this key. Wait for Retry-After seconds.
curl https://app.dmu.email/api/v1/contacts \
  -X POST \
  -H "Authorization: Bearer dmk_7f3a9c2e1b4d_Xq8v…" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "anna@papadakis-acc.gr",
    "firstName": "Άννα",
    "lastName": "Παπαδάκη",
    "company": "Λογιστήριο Παπαδάκη",
    "fields": { "vat_number": "094536781" }
  }'

Response

201 Created

{
  "data": {
    "id": "3d7a51c2",
    "visibility": "shared",
    "source": "api",
    "firstName": "Άννα",
    "lastName": "Παπαδάκη",
    "company": "Λογιστήριο Παπαδάκη",
    "jobTitle": null,
    "email": "anna@papadakis-acc.gr",
    "emails": ["anna@papadakis-acc.gr"],
    "phones": [],
    "fields": {
      "vat_number": "094536781"
    },
    "locked": [
      "first_name",
      "last_name",
      "company",
      "email",
      "vat_number"
    ],
    "createdAt": "2026-10-25T06:12:40.000Z",
    "updatedAt": "2026-10-25T06:12:40.000Z"
  }
}

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