Contact ( contact )

A contact is a professional contact attached to a company . It carries its display name, contact details, and job title and may be assigned one or more roles that qualify it in relation to the company.

Role

The contact separates the professional contact from the legal entity. A company may have several contacts — legal representative, payment authorizer, billing contact — each with their own information and verification level.

KYC, AML, PEP, sanctions, or liveness checks are recorded in compliance_check resources linked to the contact, never copied onto it. A contact can be searched by email and resolved by role in orchestration processes.

Identifier and structure

Each contact has a stable identifier prefixed with ctc_. It references its parent company through company_id.

JSON
"contact":{17 items
"object":"contact"
"id":"ctc_d12e3f4a5b6c7d8e"
"company_id":"cmp_3a8f1d9c2b4e7f6a"
"full_name":"Marie Dupont"
"first_name":"Marie"
"last_name":"Dupont"
"email":"marie.dupont@dupont-industries.fr"
"phone":"+33612345678"
"job_title":"Finance Director"
"preferred_locale":"en-US"
"suspended":false
"suspended_at":null
"suspension_reason":null
"source_reference":"RH-00421"
"metadata":{}0 items
"created_at":"2026-01-12T10:00:00.000Z"
"updated_at":"2026-03-05T14:20:00.000Z"
}
{
"object": "contact",
"id": "ctc_d12e3f4a5b6c7d8e",
"company_id": "cmp_3a8f1d9c2b4e7f6a",
"full_name": "Marie Dupont",
"first_name": "Marie",
"last_name": "Dupont",
"email": "marie.dupont@dupont-industries.fr",
"phone": "+33612345678",
"job_title": "Finance Director",
"preferred_locale": "en-US",
"suspended": false,
"suspended_at": null,
"suspension_reason": null,
"source_reference": "RH-00421",
"metadata": {},
"created_at": "2026-01-12T10:00:00.000Z",
"updated_at": "2026-03-05T14:20:00.000Z"
}

Fields

FieldTypeRequiredDescription
idstringyesContact identifier (prefix `ctc_`).
objectstringyesAlways "contact".
merchant_idstringyesMerchant to which the contact belongs.
company_idstringyesParent company identifier (`cmp_…`).
full_namestringyesCanonical full name, preserved exactly as supplied.
first_namestringnoStructured first name, when known without inference.
last_namestringnoStructured last name, when known without inference.
emailstringnoEmail address. Used as the lookup key for email search.
phonestringnoPhone number in international E.164 format, for example `+33123456789`.
job_titlestringnoFonction professionnelle libre.
preferred_localestringnoPreferred BCP 47 locale, for example `fr-FR`.
suspendedbooleanyesWhether the contact is suspended. A suspended contact keeps its history but is no longer selected for future operations.
suspended_atdatetimenoDate of the current suspension.
suspension_reasonstringnoFree-form reason for the current suspension.
source_referencestringnoReference in your system (CRM, HR…).
metadataobjectnoFlat map of `string | number | boolean` scalars, following the API metadata convention.
created_atdatetimeyesCreation date.
updated_atdatetimeyesLast update date.

Identity and compliance

Regulatory outcomes are not intrinsic properties of the contact. Each verification produces a compliance_check with subject_type=contact, the contact ID in subject_id, a nature in check_type and a normalized result in result.

Update through a process

Processes submit check drafts through submit_draft. Events compliance_check.passed, compliance_check.failed, compliance_check.review_required and compliance_check.expired carry compliance transitions.

Suspension

A person may need to stop acting for a company without disappearing from the database: sanctions alert, fraud suspicion, compromised access, departure from staff. Deleting the contact would lose the history of past acts — orders, invoices, onboarding cases, compliance checks. Suspension meets this need: it disables the contact without erasing anything.

HTTP
POST /v1/contacts/ctc_d12e3f4a5b6c7d8e/suspend
Content-Type: application/json

{
"reason": "sanctions_match"
}

A suspended contact:

  • is no longer returned by GET /v1/companies/:id/contacts/resolve, except with include_suspended=true — resolution nodes therefore route to not_found ;
  • cannot receive a new contact_role : creation returns 409 ;
  • remains readable and editable so its data can be corrected and suspension lifted.

POST /v1/contacts/:id/reactivate lifts the suspension and clears suspended_at and suspension_reason.

Suspension or role revocation?

Suspension concerns the person and can be lifted. Revocation of a role is a dated, definitive fact describing the end of a mandate. Leaving the company is represented by revoking roles; a merchant-imposed block is represented by suspension. Suspending a company does not suspend its contacts, and vice versa.

Events contact.suspended and contact.reactivated can trigger a process, for example to collect a new signatory when an ongoing case loses its current one.

Draft mode

During onboarding, contact data is collected progressively from the end user before a company necessarily exists. The platform supports this through a draft: a contact in draft mode, which carries the same business payload without an identifier and is not yet attached to a final company.

In processes, the draft flows with type platform.contact (draft). The node submit_contact and is converted into a persisted contact as soon as a company is available:

text
[Collect contact (draft)] → [Create company] → [Submit contact]
                                                       ↓
                                             contact (persisted, ctc_…)

KYC nodes — identity verification, liveness, SIRENE — also accept drafts as inputs, so verification can start before final submission.

Relationships

Linked objectLinkAccess
companyParent (1..1)company_id field · Company page
contact_role0..n roles

GET /v1/companies/:id/roles · Contact-role page

Resolving a contact by role and certification level is documented in the In processes section below and on the page company (endpoint GET /v1/companies/:id/contacts/resolve).

In processes

NodeRoleKey inputs / outputs
create_contactCreates a contact directly attached to a companyAccepts: company · Produces: contact
submit_contactConverts a collected draft into a contact and attaches it to a companyAccepts: company, contact (draft) · Produces: contact
find_contact_by_emailSearches for a contact by email and routes according to the resultAccepts: email, company (optional) · Route found / not_found · found produces: contact
resolve_contactResolves the best contact through active rolesAccepts: company, role_types, certification_levels, selection_strategy · Route found / not_found
sirene.verify_sirene_company_directorChecks whether the contact is a declared officer in SIRENEAccepts: contact, company · Route verified / not_verified
get_contact_compliance_checksRetrieves the contact's compliance checks from newest to oldestAccepts: contact · Produces: compliance_checks, count

Role-based resolution

The node resolve_contact identifies the best contact for a company among active roles — not revoked and within the valid_from / valid_untilwindow. The selection strategy determines which one is retained when several candidates match:

StrategyBehavior
firstFirst role found (creation order).
latestMost recently created role.
most_certifiedRole with the highest certification level (certified > verified > declarative).
best_role_type_fitRole whose type best matches the priority order supplied in role_types.

On success, the route found produces selected_contact, selected_contact_role, selected_role_type and other_candidates.

Email search

HTTP
GET /v1/contacts/search
?merchant_id=mrc_1a2b
&email=marie.dupont@dupont-industries.fr
"contact_search_result":{2 items
"object":"contact_search_result"
"contact":{2 items
"id":"ctc_d12e"
"email":"marie.dupont@dupont-industries.fr"
}
}
{
"object": "contact_search_result",
"contact": {
  "id": "ctc_d12e",
  "email": "marie.dupont@dupont-industries.fr"
}
}

When two contacts share the same email, search returns an error 409 duplicate_contact_match. Adding the parameter company_id restricts search to a given company and avoids this conflict.

Events

Contact changes and compliance decisions use distinct event families. Decisions are emitted by compliance_check.*.

EventTrigger
contact.createdThe contact was just created.
contact.updatedThe contact was just updated.
contact.suspendedThe contact was suspended.
contact.reactivatedThe contact suspension was lifted.

Every event includes the complete contact object in its payload. Webhook configuration is described in Receive webhooks.