Skip to content

Contacts

The address book holds persons and companies, per entity. Contacts are linked to signature requests, registered mails and tasks (contactId), and their activity lists those resources.

  • Shared contacts are visible to everyone with contacts.read in the entity.
  • Private contacts (isPrivate: true) are visible to their creator only, and are never sent to webhooks.
  • Editing requires contacts.write on your own contacts, contacts.manage on the others. Import, export and merge require contacts.manage.
Terminal window
curl -s -X POST "$MLT_API_URL/v1/contacts" \
-H "Authorization: Bearer $MLT_TOKEN" -H "Content-Type: application/json" \
-d '{
"entityId": "0192f3a1-7c2e-7b4d-9a61-200000000002",
"kind": "person",
"civility": "mrs",
"firstName": "Marie",
"lastName": "Durand",
"email": "marie.durand@example.fr",
"mobilePhone": "06 12 34 56 78",
"address": { "line1": "12 rue Vendôme", "postalCode": "69006", "city": "Lyon", "country": "FR" },
"tags": ["locataire"],
"externalRef": "CRM-00421"
}'
  • Phone numbers are normalized to E.164; national French numbers are accepted. SIREN (9 digits) and SIRET (14 digits) are checked (Luhn).
  • A person can be linked to a company contact of the same entity with companyId (“works at”).
  • externalRef stores your own identifier (e.g. the CRM id): use it to find the contact again.
  1. Look for a match with GET /v1/contacts/duplicates?entityId=…&email=… (also siret, firstName/lastName, companyName). Each match lists its reasons (email, siret, name).
  2. Update with PATCH /v1/contacts/{id} (omitted fields unchanged, null clears), or create it.
  3. Listen to contact.created and contact.updated webhooks to sync in the other direction.

GET /v1/contacts supports full-text search (q over names, company, emails, phones, SIREN/SIRET and tags, accent and case insensitive), filters (kind, tag, visibility, companyId, createdByMe) and pagination.

POST /v1/contacts/import takes a CSV (file) and a mapping (data) of target fields to CSV column names:

{
"entityId": "0192f3a1-7c2e-7b4d-9a61-200000000002",
"mapping": { "firstName": "Prénom", "lastName": "Nom", "email": "Email", "mobilePhone": "Mobile", "companyName": "Société" },
"onDuplicate": "skip",
"tags": ["import-octobre"],
"dryRun": true
}

Run it with dryRun: true first: the report lists the invalid rows (errors) and the rows matching existing contacts (duplicates) without creating anything. GET /v1/contacts/export returns the contacts matching the same filters as the list, as CSV.

  • POST /v1/contacts/{id}/merge with { "sourceId": "…", "takeFromSource": ["mobilePhone"] } merges the source into {id} and deletes the source.
  • DELETE /v1/contacts/{id} deletes permanently (right to erasure). Links to other resources are removed.