Teilnehmer-Einladungen-API
Mit Teilnehmer-Einladungen laden deine eigenen Systeme bekannte Personen zu einem Interview ein. Erstelle für einen Kunden einen persönlichen Link mit seiner E-Mail-Adresse oder Account-ID und verschick ihn, wie du willst. Seine Antworten sind dann von Anfang an mit diesem Kunden verknüpft.
Du brauchst einen Pro-, Business- oder Enterprise-Tarif und einen API-Schlüssel. Schlüssel und Authentifizierung sind im API-Überblick beschrieben.
Die Ergebnisse liest du mit der Gespräche-API: Jedes Gespräch enthält sein invite und die Identitäten, die du angehängt hast.
Diese Endpunkte sind älter als der Rest der API und behalten ihre ursprünglichen Namen: Sie nennen ein Projekt Agent (agentId) und nutzen Parameter in camelCase.
Einladungslink erstellen#
POST /api/v1/respondent-invitesJede Anfrage erstellt einen Link für einen Teilnehmer in einem Projekt. Diaform legt dabei sofort auch das Gespräch an und hängt die Identitäten an, die du sendest. So sind die Ergebnisse von Anfang an mit dieser Person verknüpft.
Request-Body#
| Feld | Typ | Pflicht | Regeln |
|---|---|---|---|
agentId | string | Ja | Projekt-ID (UUID) in der Organisation des Schlüssels |
identities | array | Ja | 1 bis 10 Einträge, einer pro Typ. |
identities[].type | string | Ja | Bis zu 64 Zeichen: Kleinbuchstaben, Ziffern, _ und -, beginnend mit einem Buchstaben oder einer Ziffer. Großbuchstaben werden in Kleinbuchstaben umgewandelt. |
identities[].value | string | Ja | 1 bis 512 Zeichen nach dem Entfernen von Leerzeichen am Anfang und Ende. Ein email-Wert muss eine gültige E-Mail-Adresse sein und wird in Kleinbuchstaben gespeichert. |
organizationId | string | Nein | Wenn du es sendest, muss es zur Organisation des Schlüssels passen |
send_email | boolean | Nein | true schickt den Link per E-Mail an die email-Identität der Einladung und sendet nach 3 Tagen eine Erinnerung, falls der Teilnehmer nicht abgeschlossen hat. Standard false. |
Wenn du send_email sendest, enthält die Antwort ein email-Objekt: { "status": "sent" }, { "status": "failed" } oder { "status": "skipped", "reason": "..." }. Die Einladung wird in jedem Fall erstellt. Mögliche Gründe sind no_email, unsubscribed, not_published, no_usage, monthly_limit (das monatliche Kontingent an Einladungs-E-Mails deines Tarifs ist aufgebraucht), answered, already_sent, in_progress, plan und not_found. Was die E-Mail enthält, steht unter Teilnehmer identifizieren.
Gängige Typen sind email, name, identifier, user_id und account_id. Jeder Typ, der den Regeln folgt, funktioniert.
Beispiel#
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" }
]
}'Antwort#
{
"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"
}
}| Feld | Beschreibung |
|---|---|
invite.id | Einladungs-ID. Webhooks senden sie als respondent.invite_id. |
invite.status | pending, opened oder completed |
invite.conversation_id | Das Gespräch, das für diesen Teilnehmer erstellt wurde |
invite.identities | Die Identitäten, die du gesendet hast, jeweils mit source: "owner" |
invite.url | Der Link zum Verschicken. Er nutzt deine verifizierte eigene Domain, falls du eine hast. null, sobald die Einladung abgeschlossen ist. |
So verhält sich der Link#
- Erstellt. Die Einladung ist
pendingund ihr Gesprächinvited. - Geöffnet. Öffnet der Teilnehmer den Link, werden beide
opened. Das Gespräch wechselt zustarted, sobald er antwortet. - Fortgesetzt. Verlässt der Teilnehmer das Gespräch und kommt über denselben Link zurück, macht er im selben Gespräch weiter.
- Beendet. Endet das Gespräch, ob abgeschlossen oder abgebrochen, wird die Einladung
completed, und der Link funktioniert nicht mehr.
Das Projekt muss veröffentlicht sein, damit sich der Link öffnet. Links funktionieren in Projekten mit Öffentlicher Link und mit Nur Einladungslinks. Bei öffentlichen Projekten funktioniert auch der normale Link weiter. Siehe Teilnehmer identifizieren.
Älterer Endpunkt für Gespräche#
GET /api/v1/respondent-conversationsDieser Endpunkt listet die Gespräche eines Projekts auf und funktioniert weiterhin. Bestehende Integrationen müssen also nichts ändern. Für Neues nutze Gespräche auflisten. Dort gibt es zusätzlich Filter, Transkripte und eine einfachere Paginierung.
| Parameter | Pflicht | Beschreibung |
|---|---|---|
agentId | Ja | Projekt-ID |
limit | Nein | 1 bis 100. Standard 50. |
status | Nein | invited, opened, started, completed oder cancelled |
cursor | Nein | nextCursor.created_at aus der vorherigen Seite |
cursorId | Nein | nextCursor.id aus der vorherigen Seite |
Er gibt conversations zurück (jeweils mit conversation_id, created_at, status, respondent_email, metadata, identities, summary und invite) und nextCursor, ein Objekt mit created_at und id, oder null auf der letzten Seite. Schick diese beiden Werte als cursor und cursorId zurück.
Sende cursor URL-kodiert. Sein Zeitstempel enthält ein +, das als %2B gesendet werden muss. Ein rohes + wird als Leerzeichen gelesen, und die Anfrage schlägt mit 400 fehl. curl --data-urlencode und URLSearchParams kodieren ihn für dich.
Fehler#
Fehler liefern JSON mit einer error-Meldung und einem code, wie im Rest der API. Ein 400 enthält zusätzlich details.fieldErrors mit dem Namen des fehlerhaften Felds.
{
"error": "Invalid request",
"code": "invalid_request",
"details": {
"formErrors": [],
"fieldErrors": {
"identities": ["Add at least one respondent identity."]
}
}
}| Status | code | Ursache |
|---|---|---|
400 | invalid_request | Ein Feld oder Query-Parameter fehlt oder ist ungültig |
401 | unauthorized | Der Authorization-Header fehlt, ist nicht Bearer dia_org_live_..., oder der Schlüssel wurde widerrufen |
403 | forbidden | Deine Organisation hat keinen Pro-, Business- oder Enterprise-Tarif, oder organizationId passt nicht zum Schlüssel |
404 | not_found | agentId ist kein Projekt in der Organisation des Schlüssels |
500 | internal_error | Bei Diaform ist ein Fehler aufgetreten. Versuch es noch einmal. |
Limits#
Diese beiden Endpunkte haben kein Ratenlimit. Jede Einladung nimmt bis zu 10 Identitäten auf (eine pro Typ), und jede Organisation kann bis zu 10 API-Schlüssel haben.