API des invitations de répondants
Les invitations de répondants permettent à vos propres systèmes d’inviter des personnes connues à un entretien. Créez un lien personnel pour un client, avec son e-mail ou son ID de compte associé, envoyez-le comme vous le souhaitez, et ses réponses sont rattachées à ce client dès le départ.
Il vous faut une offre Pro, Business ou Enterprise et une clé API. Pour les clés et l’authentification, consultez la Vue d’ensemble de l’API.
Pour lire les résultats, utilisez l’API des conversations : chaque conversation contient son invite et les identités que vous avez associées.
Ces endpoints sont plus anciens que le reste de l’API et gardent leurs noms d’origine : ils appellent un projet un agent (agentId) et utilisent des paramètres en camelCase.
Créer un lien d’invitation#
POST /api/v1/respondent-invitesChaque requête crée un lien pour un répondant dans un projet. Diaform crée aussi immédiatement la conversation et y associe les identités que vous envoyez : les résultats sont donc rattachés à cette personne dès le départ.
Corps de la requête#
| Champ | Type | Obligatoire | Règles |
|---|---|---|---|
agentId | string | Oui | ID du projet (UUID) dans l’organisation de la clé |
identities | array | Oui | De 1 à 10 éléments, un par type. |
identities[].type | string | Oui | Jusqu’à 64 caractères : lettres minuscules, chiffres, _ et -, en commençant par une lettre ou un chiffre. Les majuscules sont converties en minuscules. |
identities[].value | string | Oui | De 1 à 512 caractères, espaces de début et de fin retirés. Une valeur email doit être une adresse e-mail valide et est stockée en minuscules. |
organizationId | string | Non | Si vous l’envoyez, il doit correspondre à l’organisation de la clé |
send_email | boolean | Non | true envoie le lien par e-mail à l’identité email de l’invitation, puis un rappel au bout de 3 jours si le répondant n’a pas terminé. false par défaut. |
Quand vous envoyez send_email, la réponse contient un objet email : { "status": "sent" }, { "status": "failed" } ou { "status": "skipped", "reason": "..." }. L’invitation est créée dans tous les cas. Les raisons possibles sont no_email, unsubscribed, not_published, no_usage, monthly_limit (les e-mails d’invitation mensuels de votre offre sont épuisés), answered, already_sent, in_progress, plan et not_found. Consultez Identifier les répondants pour savoir ce que contient l’e-mail.
Les types courants sont email, name, identifier, user_id et account_id. Tout type qui respecte les règles fonctionne.
Exemple#
curl -X POST "https://diaform.io/api/v1/respondent-invites" \
-H "Authorization: Bearer $DIAFORM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "b8acb3ab-1f3d-4a7e-a846-b7f493f86b6d",
"identities": [
{ "type": "email", "value": "alex@acme.com" },
{ "type": "account_id", "value": "acct_4821" }
]
}'Réponse#
{
"organization_id": "4d6ecdb4-8543-4adf-ae65-1f24106d5474",
"agent_id": "b8acb3ab-1f3d-4a7e-a846-b7f493f86b6d",
"agent_name": "Onboarding interviews",
"invite": {
"id": "3a4f49c7-b8f4-4c44-8f74-fd8e4277c3e4",
"created_at": "2026-05-07T12:00:00.123456+00:00",
"status": "pending",
"opened_at": null,
"completed_at": null,
"conversation_id": "0f8d43a2-6df9-49c8-bf5d-fd2b6ec2d9ee",
"identities": [
{
"id": "71138f36-d16a-41f8-8a1f-65b9b8d483e3",
"created_at": "2026-05-07T12:00:00.123456+00:00",
"conversation_id": "0f8d43a2-6df9-49c8-bf5d-fd2b6ec2d9ee",
"source": "owner",
"identity_type": "email",
"value": "alex@acme.com",
"metadata": {}
},
{
"id": "120feee2-a10e-4b9a-af8e-a54d4dd672a1",
"created_at": "2026-05-07T12:00:00.123456+00:00",
"conversation_id": "0f8d43a2-6df9-49c8-bf5d-fd2b6ec2d9ee",
"source": "owner",
"identity_type": "account_id",
"value": "acct_4821",
"metadata": {}
}
],
"url": "https://acme.diaform.io/c/b8acb3ab-1f3d-4a7e-a846-b7f493f86b6d?invite=dia_resp_pCaJHykjUYBKZdkbVUtbyZRMC3yFzm246SK2K8lw"
}
}| Champ | Description |
|---|---|
invite.id | ID de l’invitation. Les webhooks l’envoient dans respondent.invite_id. |
invite.status | pending, opened ou completed |
invite.conversation_id | La conversation créée pour ce répondant |
invite.identities | Les identités que vous avez envoyées, chacune avec source: "owner" |
invite.url | Le lien à envoyer. Il utilise votre domaine personnalisé vérifié, si vous en avez un. null une fois l’invitation terminée. |
Fonctionnement du lien#
- Création. L’invitation est
pendinget sa conversation estinvited. - Ouverture. Quand le répondant ouvre le lien, les deux passent à
opened. La conversation passe àstarteddès qu’il répond. - Reprise. Si le répondant part puis revient par le même lien, il reprend la même conversation.
- Fin. Quand la conversation prend fin, qu’elle soit terminée ou annulée, l’invitation passe à
completedet le lien cesse de fonctionner.
Le projet doit être publié pour que le lien s’ouvre. Les liens fonctionnent pour les projets en Lien public comme en Liens sur invitation. Pour les projets publics, le lien habituel continue aussi de fonctionner. Consultez Identifier les répondants.
Ancien endpoint des conversations#
GET /api/v1/respondent-conversationsCet endpoint liste les conversations d’un projet et fonctionne toujours : les intégrations existantes n’ont donc pas besoin de changer. Pour les nouveaux développements, utilisez Lister les conversations, qui ajoute des filtres, les transcriptions et une pagination plus simple.
| Paramètre | Obligatoire | Description |
|---|---|---|
agentId | Oui | ID du projet |
limit | Non | De 1 à 100. 50 par défaut. |
status | Non | invited, opened, started, completed ou cancelled |
cursor | Non | nextCursor.created_at de la page précédente |
cursorId | Non | nextCursor.id de la page précédente |
Il renvoie conversations (chacune avec conversation_id, created_at, status, respondent_email, metadata, identities, summary et invite) et nextCursor, un objet avec created_at et id, ou null sur la dernière page. Renvoyez ces deux valeurs dans cursor et cursorId.
Encodez cursor pour l’URL. Son horodatage contient un +, qui doit être envoyé sous la forme %2B. Un + brut est lu comme une espace et la requête échoue avec 400. curl --data-urlencode et URLSearchParams l’encodent pour vous.
Erreurs#
Les erreurs renvoient du JSON avec un message error et un code, comme dans le reste de l’API. Une erreur 400 inclut aussi details.fieldErrors, qui indique le champ en cause.
{
"error": "Invalid request",
"code": "invalid_request",
"details": {
"formErrors": [],
"fieldErrors": {
"identities": ["Add at least one respondent identity."]
}
}
}| Statut | code | Cause |
|---|---|---|
400 | invalid_request | Un champ ou un paramètre de requête est absent ou invalide |
401 | unauthorized | L’en-tête Authorization est absent, n’est pas Bearer dia_org_live_..., ou la clé a été révoquée |
403 | forbidden | Votre organisation n’a pas l’offre Pro, Business ou Enterprise, ou organizationId ne correspond pas à la clé |
404 | not_found | agentId n’est pas un projet de l’organisation de la clé |
500 | internal_error | Une erreur s’est produite du côté de Diaform. Réessayez. |
Limites#
Ces deux endpoints n’ont pas de limite de débit. Chaque invitation accepte jusqu’à 10 identités (une par type), et chaque organisation peut avoir jusqu’à 10 clés API.