API & MCP

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.

HTTP
POST /api/v1/respondent-invites

Jede 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#

FeldTypPflichtRegeln
agentIdstringJaProjekt-ID (UUID) in der Organisation des Schlüssels
identitiesarrayJa1 bis 10 Einträge, einer pro Typ.
identities[].typestringJaBis zu 64 Zeichen: Kleinbuchstaben, Ziffern, _ und -, beginnend mit einem Buchstaben oder einer Ziffer. Großbuchstaben werden in Kleinbuchstaben umgewandelt.
identities[].valuestringJa1 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.
organizationIdstringNeinWenn du es sendest, muss es zur Organisation des Schlüssels passen
send_emailbooleanNeintrue 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#

JSON
{
  "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"
  }
}
FeldBeschreibung
invite.idEinladungs-ID. Webhooks senden sie als respondent.invite_id.
invite.statuspending, opened oder completed
invite.conversation_idDas Gespräch, das für diesen Teilnehmer erstellt wurde
invite.identitiesDie Identitäten, die du gesendet hast, jeweils mit source: "owner"
invite.urlDer Link zum Verschicken. Er nutzt deine verifizierte eigene Domain, falls du eine hast. null, sobald die Einladung abgeschlossen ist.
  1. Erstellt. Die Einladung ist pending und ihr Gespräch invited.
  2. Geöffnet. Öffnet der Teilnehmer den Link, werden beide opened. Das Gespräch wechselt zu started, sobald er antwortet.
  3. Fortgesetzt. Verlässt der Teilnehmer das Gespräch und kommt über denselben Link zurück, macht er im selben Gespräch weiter.
  4. 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#

HTTP
GET /api/v1/respondent-conversations

Dieser 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.

ParameterPflichtBeschreibung
agentIdJaProjekt-ID
limitNein1 bis 100. Standard 50.
statusNeininvited, opened, started, completed oder cancelled
cursorNeinnextCursor.created_at aus der vorherigen Seite
cursorIdNeinnextCursor.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.

JSON
{
  "error": "Invalid request",
  "code": "invalid_request",
  "details": {
    "formErrors": [],
    "fieldErrors": {
      "identities": ["Add at least one respondent identity."]
    }
  }
}
StatuscodeUrsache
400invalid_requestEin Feld oder Query-Parameter fehlt oder ist ungültig
401unauthorizedDer Authorization-Header fehlt, ist nicht Bearer dia_org_live_..., oder der Schlüssel wurde widerrufen
403forbiddenDeine Organisation hat keinen Pro-, Business- oder Enterprise-Tarif, oder organizationId passt nicht zum Schlüssel
404not_foundagentId ist kein Projekt in der Organisation des Schlüssels
500internal_errorBei 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.