Contact (contact)

Un contact est un contact professionnel rattaché à une company. Il porte son nom d'affichage, ses coordonnées et sa fonction, et peut se voir attribuer un ou plusieurs rôles qui le qualifient vis-à-vis de la company.

Rôle

Le contact sépare le contact professionnel de l'entité légale. Une company (société, entreprise) peut avoir plusieurs contacts — représentant légal, autorisateur de paiement, contact de facturation — chacun avec ses propres informations et son propre niveau de vérification.

Les vérifications KYC, AML, PEP, sanctions ou liveness sont enregistrées dans des compliance_check liés au contact, jamais recopiées sur celui-ci. Un contact peut être recherché par email et résolu par rôle dans les processus d'orchestration.

Identifiant et structure

Chaque contact porte un identifiant stable préfixé par ctc_. Il référence sa company parente via 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":"Directrice financière"
"preferred_locale":"fr-FR"
"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": "Directrice financière",
  "preferred_locale": "fr-FR",
  "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"
}

Champs

ChampTypeRequisDescription
idstringouiIdentifiant du contact (préfixe ctc_).
objectstringouiToujours "contact".
merchant_idstringouiMarchand auquel appartient le contact.
company_idstringouiIdentifiant de la company parente (cmp_…).
full_namestringouiNom complet canonique, conservé exactement comme fourni.
first_namestringnonPrénom structuré, lorsqu’il est connu sans déduction.
last_namestringnonNom de famille structuré, lorsqu’il est connu sans déduction.
emailstringnonAdresse e-mail. Utilisée comme clé de recherche par email.
phonestringnonNuméro de téléphone au format international E.164, par exemple +33123456789.
job_titlestringnonFonction professionnelle libre.
preferred_localestringnonLocale BCP 47 préférée, par exemple fr-FR.
suspendedbooleanouiIndique si le contact est suspendu. Un contact suspendu conserve son historique mais n'est plus retenu pour les opérations futures.
suspended_atdatetimenonDate de la suspension en cours.
suspension_reasonstringnonMotif libre de la suspension en cours.
source_referencestringnonRéférence dans votre système (CRM, RH…).
metadataobjectnonMap plate de scalaires `string | number | boolean`, selon la convention metadata de l’API.
created_atdatetimeouiDate de création.
updated_atdatetimeouiDate de dernière mise à jour.

Identité et conformité

Les résultats réglementaires ne sont pas des propriétés intrinsèques du contact. Chaque vérification produit un compliance_check avec subject_type=contact, l'ID du contact dans subject_id, une nature dans check_type et un résultat normalisé dans result.

Mise à jour via processus Les processus soumettent les drafts de contrôle via submit_draft. Les événements compliance_check.passed, compliance_check.failed, compliance_check.review_required et compliance_check.expired portent les transitions de conformité.

Suspension

Une personne peut devoir cesser d'agir pour une company sans pour autant disparaître de la base : alerte sanctions, soupçon de fraude, accès compromis, départ des effectifs. Supprimer le contact ferait perdre l'historique de ses actes passés — commandes, factures, dossiers d'entrée en relation, contrôles de conformité. La suspension répond à ce besoin : elle neutralise le contact sans rien effacer.

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

{
  "reason": "sanctions_match"
}

Un contact suspendu :

  • n'est plus retourné par GET /v1/companies/:id/contacts/resolve, sauf include_suspended=true — les nodes de résolution basculent donc sur la route not_found ;
  • ne peut plus recevoir de nouveau contact_role : la création répond 409 ;
  • reste lisible et modifiable, pour pouvoir corriger ses données et lever la suspension.

POST /v1/contacts/:id/reactivate lève la suspension et efface suspended_at et suspension_reason.

Suspension ou révocation de rôle ? La suspension porte sur la personne et se lève. La révocation d'un rôle est un fait daté et définitif qui décrit la fin d'un mandat. Un départ de la société se traduit par la révocation des rôles ; un blocage décidé par le marchand se traduit par une suspension. Suspendre une company ne suspend pas ses contacts, et inversement.

Les événements contact.suspended et contact.reactivated permettent de déclencher un processus, par exemple pour repartir en collecte d'un nouveau signataire quand un dossier en cours perd le sien.

Mode brouillon

Pendant un parcours d'entrée en relation, les données du contact sont collectées progressivement par l'utilisateur final avant qu'une company n'existe encore. La plateforme prend en charge ce cas via le mode brouillon : un contact en brouillon porte le même payload métier, sans identifiant, et n'est pas encore rattaché à une company définitive.

Dans les processus, le brouillon circule avec le type platform.contact (draft). Le node submit_contact le convertit en contact engagé dès qu'une company est disponible :

text
[Collecte contact (draft)] → [Créer company] → [Submit contact]
                                                         ↓
                                               contact (engagé, ctc_…)

Les nodes KYC (vérification d'identité, liveness, SIRENE) acceptent également les drafts en entrée — la vérification peut donc démarrer avant la soumission finale.

Relations

Objet liéLienAccès
companyParent (1..1)Champ company_id · Page company
contact_role0..n rôlesGET /v1/companies/:id/roles · Page rôle de contact

La résolution d'un contact par rôle et niveau de certification est documentée dans la section Dans les processus ci-dessous et dans la page company (endpoint GET /v1/companies/:id/contacts/resolve).

Dans les processus

NodeRôleEntrées / sorties clés
create_contactCrée un contact directement rattaché à une companyAccepte : company · Produit : contact
submit_contactConvertit un draft collecté en contact et le rattache à une companyAccepte : company, contact (draft) · Produit : contact
find_contact_by_emailCherche un contact par email, route selon le résultatAccepte : email, company (optionnel) · Route found / not_found · found produit : contact
resolve_contactRésout le meilleur contact via ses rôles actifsAccepte : company, role_types, certification_levels, selection_strategy · Route found / not_found
sirene.verify_sirene_company_directorVérifie si le contact est un dirigeant déclaré dans SIRENEAccepte : contact, company · Route verified / not_verified
get_contact_compliance_checksRécupère les contrôles de conformité du contact, du plus récent au plus ancienAccepte : contact · Produit : compliance_checks, count

Résolution par rôle

Le node resolve_contact identifie le meilleur contact d'une company parmi ses rôles actifs (non révoqués, dans la fenêtre valid_from / valid_until). La stratégie de sélection détermine lequel retenir quand plusieurs candidats correspondent :

StratégieComportement
firstPremier rôle trouvé (ordre de création).
latestRôle créé le plus récemment.
most_certifiedRôle avec le niveau de certification le plus élevé (certified > verified > declarative).
best_role_type_fitRôle dont le type correspond le mieux à l'ordre de priorité fourni dans role_types.

En cas de succès, la route found produit selected_contact, selected_contact_role, selected_role_type et other_candidates.

Recherche par email

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"
  }
}

Si deux contacts partagent le même email, la recherche retourne une erreur 409 duplicate_contact_match. L'ajout du paramètre company_id restreint la recherche à une company donnée et évite ce conflit.

Événements

Les changements du contact et les décisions de conformité utilisent des familles d'événements distinctes. Les décisions sont émises par compliance_check.*.

ÉvénementDéclencheur
contact.createdLe contact vient d'être créé.
contact.updatedLe contact vient d’être mis à jour.
contact.suspendedLe contact a été suspendu.
contact.reactivatedLa suspension du contact a été levée.

Chaque événement inclut l'objet contact complet dans son payload. La configuration des webhooks est décrite dans Recevoir des webhooks.