API-Referenzv1

Baue auf deinen LeadGrid-Pipelines auf.

Erstelle Dossiers, verschiebe sie durch Phasen, synchronisiere Notizen und reagiere auf Events. Eine REST API, JSON rein und raus. Verfügbar im Growth-Plan.

01: Hier starten

Übersicht

Die LeadGrid API ermöglicht es dir, Dossiers zu erstellen und zu verwalten, Phasen zu aktualisieren, Notizen anzuhängen und Daten mit deinen eigenen Tools zu synchronisieren. Jede Anfrage gibt JSON zurück.

Basis-URL
https://leadgrid.io/api/v1
Format
JSON (UTF-8)
Auth
Bearer API-Schlüssel
Verfügbarkeit
Growth-Plan

Alle Zeitstempel sind ISO 8601 in UTC. Alle Beträge sind ganzzahlig oder dezimal in der kleinsten praktischen Einheit (z. B. Euro, nicht Cent). Die Paginierung verwendet page und per_page Abfrageparameter; Antworten enthalten ein meta Objekt mit der Gesamtanzahl.

02: Sicherheit

Authentifizierung

Jede Anfrage muss einen API-Schlüssel im Authorization-Header tragen. Schlüssel beginnen mit lg_live_ und sind auf eine Organisation beschränkt.

  1. 1Gehe zu Einstellungen → API und klicke auf API-Schlüssel erstellen.
  2. 2Wähle die benötigten Scopes (siehe Tabelle unten) und setze optional ein Ablaufdatum. Der vollständige Schlüssel wird einmalig angezeigt, kopiere ihn sofort.
  3. 3Sende den Schlüssel als Bearer-Token bei jeder Anfrage mit.
curl
curl https://leadgrid.io/api/v1/dossiers \
  -H "Authorization: Bearer lg_live_your_key_here"
Verfügbare Scopes
FeldTypBeschreibung
dossiers:readscopeDossiers auflisten und abrufen.
dossiers:writescopeDossiers erstellen, aktualisieren und archivieren. Auch erforderlich, um Phasen zu verschieben.
contacts:readscopeKontakte auflisten und abrufen sowie ihre Dossierverknüpfungen lesen.
contacts:writescopeKontakte erstellen, aktualisieren und löschen. Zusätzlich zu dossiers:write erforderlich, um Kontakte mit einem Dossier zu verknüpfen oder die Verknüpfung aufzuheben.
flows:readscopeFlows auflisten und ihre Phasen lesen.
notes:readscopeNotizen zu Dossiers lesen.
notes:writescopeNeue Notizen zu Dossiers hinzufügen.
Lege deinen Schlüssel niemals in clientseitigem Code offen. Der Schlüssel hat vollen Zugriff auf deine Organisation; behandle ihn wie ein Passwort. Wenn ein Schlüssel geleakt wird, lösche ihn unter Einstellungen → API und ersetze ihn sofort.
03: Ressourcen

Dossiers

Dossiers sind die Entitäten, die du verfolgst, Kandidaten im Recruiting oder Leads im Vertrieb. Jedes Dossier gehört zu genau einem Flow und befindet sich in genau einer Phase.

GET/dossiers

Dossiers in deiner Organisation auflisten. Unterstützt Filtern und Paginierung.

Abfrageparameter
FeldTypBeschreibung
typestring'candidate' or 'sales'.
statusstring'active', 'won', 'lost' or 'archived'.
stage_iduuidReturn only dossiers currently in this stage.
pageinteger1-based page number. Default: 1.
per_pageintegerItems per page (max 100). Default: 25.
Beispielanfrage
curl "https://leadgrid.io/api/v1/dossiers?type=sales&status=active" \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": [
    {
      "id": "6f2b…",
      "type": "sales",
      "name": "Rabobank, Talent rollout",
      "company": "Rabobank",
      "contact_person": "Mark de Vries",
      "deal_size": 45000,
      "deal_currency": "EUR",
      "status": "active",
      "current_stage_id": "c3e1…",
      "assigned_to": "ab12…",
      "created_at": "2026-04-10T09:21:14Z"
    }
  ],
  "meta": { "total": 34, "page": 1, "per_page": 25 }
}
POST/dossiers

Ein neues Dossier erstellen. Wenn flow_id weggelassen wird, wird der Standard-Flow für den angegebenen Typ verwendet; das Dossier startet in der ersten Phase dieses Flows. Übergib optional eine contact_id, um das Dossier mit einem bestehenden Kontakt zu verknüpfen, statt einen neuen anzulegen. Sende application/json für eine einfache Erstellung oder multipart/form-data mit einem 'cv'-Dateifeld, um das Dossier UND einen PDF-Lebenslauf in einem atomaren Aufruf anzuhängen: Wenn der Upload fehlschlägt, wird das Dossier zurückgerollt.

Request-Body
FeldTypBeschreibung
type*string'candidate' or 'sales'.
name*stringFor candidates: the person's name. For sales: deal or account name.
emailstringPrimary contact email.
phonestringPrimary contact phone.
companystringCandidate: current employer. Sales: target company.
rolestringCandidate: role they're applying for. Sales: role of the contact.
contact_iduuidLink the dossier to an existing Contact instead of creating a new one. Must belong to your organization.
flow_iduuidOverride the default flow. Must belong to your organization.
assigned_touuidUser ID of the member to assign this dossier to.
intake_notesstringDirector/intake notes shown in the dossier drawer.
contact_personstringSales only. Named contact at the target company.
deal_sizenumberSales only. Expected contract value.
deal_currencystringSales only. ISO 4217 currency code (e.g. 'EUR').
cvfile (pdf)multipart/form-data only. Optional PDF CV (max 10 MB). Uploaded and attached in the same call. If the upload fails, the dossier is rolled back.
Beispielanfrage
# JSON, plain create
curl -X POST https://leadgrid.io/api/v1/dossiers \
  -H "Authorization: Bearer lg_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "sales",
    "name": "KLM, Cabin crew hiring",
    "company": "KLM",
    "contact_person": "Pieter van Leeuwen",
    "deal_size": 62000,
    "deal_currency": "EUR"
  }'

# multipart, create + attach CV in one call
curl -X POST https://leadgrid.io/api/v1/dossiers \
  -H "Authorization: Bearer lg_live_your_key" \
  -F "type=candidate" \
  -F "name=Sophie van Dijk" \
  -F "role=Senior Frontend Engineer" \
  -F "email=sophie@example.com" \
  -F "cv=@./resume.pdf"
Beispielantwort
{
  "data": {
    "id": "a91c…",
    "type": "candidate",
    "name": "Sophie van Dijk",
    "cv_url": "<org-id>/dossiers/a91c…/cv.pdf",
    "status": "active",
    "current_stage_id": "b77f…",
    "created_at": "2026-04-15T12:03:40Z"
  }
}
GET/dossiers/:id

Ein einzelnes Dossier anhand der ID abrufen.

Beispielanfrage
curl https://leadgrid.io/api/v1/dossiers/a91c… \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": {
    "id": "a91c…",
    "type": "sales",
    "name": "KLM, Cabin crew hiring",
    "deal_size": 62000,
    "current_stage_id": "b77f…"
  }
}
PATCH/dossiers/:id

Eine beliebige Teilmenge von Feldern aktualisieren. Das Setzen von current_stage_id verschiebt das Dossier in eine neue Phase und löst einen dossier.stage_changed-Webhook aus.

Request-Body
FeldTypBeschreibung
namestringRename the dossier.
emailstringUpdate primary contact email.
phonestringUpdate phone.
companystringUpdate company / employer.
rolestringUpdate role.
contact_personstringSales only.
deal_sizenumberSales only.
deal_currencystringSales only.
statusstring'active', 'won', 'lost' or 'archived'.
assigned_touuidReassign to another member. Null to unassign.
intake_notesstringReplace intake notes.
current_stage_iduuidMove to a new stage. Must belong to the dossier's flow.
Beispielanfrage
curl -X PATCH https://leadgrid.io/api/v1/dossiers/a91c… \
  -H "Authorization: Bearer lg_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "current_stage_id": "d8e2…", "status": "active" }'
Beispielantwort
{
  "data": {
    "id": "a91c…",
    "current_stage_id": "d8e2…",
    "status": "active"
  }
}
DELETE/dossiers/:id

Archiviert das Dossier (Soft Delete). Setzt den Status auf 'archived' und löst dossier.deleted aus. Daten bleiben erhalten und können per PATCH wiederhergestellt werden.

Beispielanfrage
curl -X DELETE https://leadgrid.io/api/v1/dossiers/a91c… \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": {
    "id": "a91c…",
    "status": "archived"
  }
}
POST/dossiers/:id/cv

Einen PDF-Lebenslauf (max. 10 MB) hochladen und an ein vorhandenes Dossier anhängen. Der Upload ersetzt einen eventuell vorhandenen Lebenslauf. Akzeptiert multipart/form-data mit einem 'cv'-Feld oder application/pdf mit den PDF-Bytes als Raw-Body. Löst dossier.updated aus.

Beispielanfrage
# multipart/form-data
curl -X POST https://leadgrid.io/api/v1/dossiers/a91c…/cv \
  -H "Authorization: Bearer lg_live_your_key" \
  -F "cv=@./resume.pdf"

# raw application/pdf
curl -X POST https://leadgrid.io/api/v1/dossiers/a91c…/cv \
  -H "Authorization: Bearer lg_live_your_key" \
  -H "Content-Type: application/pdf" \
  --data-binary @./resume.pdf
Beispielantwort
{
  "data": {
    "id": "a91c…",
    "cv_url": "<org-id>/dossiers/a91c…/cv.pdf"
  }
}
04: Ressourcen

Kontakte

Kontakte sind die Personen in deinem Netzwerk: Kandidaten, Interessenten, Kunden, Lieferanten und Partner. Ein einzelner Kontakt kann mehrere kinds gleichzeitig haben und mit beliebig vielen Dossiers verknüpft sein.

GET/contacts

Kontakte in deiner Organisation auflisten. Unterstützt Filterung nach kind, Pool-Status und Freitextsuche sowie Paginierung.

Abfrageparameter
FeldTypBeschreibung
kindstringFilter by kind. Repeat the parameter to combine values: 'candidate', 'prospect', 'client', 'supplier' or 'partner'.
poolstring'in_pool' for contacts currently in the talent pool, 'expired' for contacts whose pool window has passed.
searchstringFree-text search over full_name, email, company and role.
pageinteger1-based page number. Default: 1.
per_pageintegerItems per page (max 100). Default: 25.
Beispielanfrage
curl "https://leadgrid.io/api/v1/contacts?kind=candidate&kind=client&search=sophie" \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": [
    {
      "id": "c12a…",
      "full_name": "Sophie van Dijk",
      "email": "sophie@example.com",
      "phone": "+31 6 12345678",
      "linkedin_url": "https://linkedin.com/in/sophievandijk",
      "company": "Adyen",
      "role": "Senior Frontend Engineer",
      "city": "Amsterdam",
      "kind": ["candidate", "client"],
      "notes": null,
      "dossier_count": 2,
      "created_at": "2026-04-08T11:14:02Z"
    }
  ],
  "meta": { "total": 142, "page": 1, "per_page": 25 }
}
POST/contacts

Einen neuen Kontakt erstellen. full_name ist das einzige Pflichtfeld. Existiert bereits ein Kontakt mit derselben E-Mail-Adresse in deiner Organisation (Groß-/Kleinschreibung wird ignoriert), gibt die API 409 mit einem duplicate_contact-Fehler zurück.

Request-Body
FeldTypBeschreibung
full_name*stringThe contact's full name.
emailstringPrimary email. Must be unique per organization (case-insensitive). Returns 409 on conflict.
phonestringPrimary phone number.
linkedin_urlstringPublic LinkedIn profile URL.
companystringCurrent employer or account.
rolestringJob title or role.
citystringCity of residence.
kindstring[]Array of kinds: 'candidate', 'prospect', 'client', 'supplier', 'partner'. Defaults to an empty array.
notesstringFree-form internal notes shown on the contact drawer.
Beispielanfrage
curl -X POST https://leadgrid.io/api/v1/contacts \
  -H "Authorization: Bearer lg_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "full_name": "Sophie van Dijk",
    "email": "sophie@example.com",
    "company": "Adyen",
    "role": "Senior Frontend Engineer",
    "city": "Amsterdam",
    "kind": ["candidate"]
  }'
Beispielantwort
{
  "data": {
    "id": "c12a…",
    "full_name": "Sophie van Dijk",
    "email": "sophie@example.com",
    "company": "Adyen",
    "role": "Senior Frontend Engineer",
    "city": "Amsterdam",
    "kind": ["candidate"],
    "dossier_count": 0,
    "created_at": "2026-04-30T08:21:14Z"
  }
}
GET/contacts/:id

Einen einzelnen Kontakt anhand der ID abrufen, einschließlich seiner kinds und aggregierter Dossierzahlen.

Beispielanfrage
curl https://leadgrid.io/api/v1/contacts/c12a… \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": {
    "id": "c12a…",
    "full_name": "Sophie van Dijk",
    "email": "sophie@example.com",
    "company": "Adyen",
    "role": "Senior Frontend Engineer",
    "city": "Amsterdam",
    "kind": ["candidate", "client"],
    "dossier_count": 2
  }
}
PATCH/contacts/:id

Beliebige Felder eines Kontakts teilweise aktualisieren. Sende nur die Schlüssel, die du ändern möchtest.

Request-Body
FeldTypBeschreibung
full_namestringRename the contact.
emailstringUpdate primary email. Still subject to the per-org uniqueness check.
phonestringUpdate phone number.
linkedin_urlstringUpdate LinkedIn URL.
companystringUpdate company.
rolestringUpdate role.
citystringUpdate city.
kindstring[]Replace the full kinds array. Send the complete set of kinds you want on the contact.
notesstringReplace internal notes.
Beispielanfrage
curl -X PATCH https://leadgrid.io/api/v1/contacts/c12a… \
  -H "Authorization: Bearer lg_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "kind": ["candidate", "client"], "city": "Rotterdam" }'
Beispielantwort
{
  "data": {
    "id": "c12a…",
    "kind": ["candidate", "client"],
    "city": "Rotterdam"
  }
}
DELETE/contacts/:id

Den Kontakt endgültig löschen. Die Verknüpfungen in dossier_contacts werden mitgelöscht, die verknüpften Dossiers selbst bleiben erhalten.

Beispielanfrage
curl -X DELETE https://leadgrid.io/api/v1/contacts/c12a… \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": {
    "id": "c12a…",
    "deleted": true
  }
}

Dossierverknüpfungen

Eine Dossier-Kontakt-Verknüpfung verbindet einen Kontakt mit einem Dossier und hält fest, welche Rolle die Person bei diesem Deal oder Hire einnimmt (primary, hiring manager, decision maker, champion, gatekeeper, introducer oder other). Ein Dossier kann viele Kontakte haben; ein Kontakt kann auf vielen Dossiers stehen.

GET/dossiers/:id/contacts

Die mit einem Dossier verknüpften Kontakte auflisten, inklusive Rolle und Information, ob es sich um den primären Kontakt handelt.

Beispielanfrage
curl https://leadgrid.io/api/v1/dossiers/a91c…/contacts \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": [
    {
      "contact_id": "c12a…",
      "full_name": "Sophie van Dijk",
      "email": "sophie@example.com",
      "company": "Adyen",
      "role_on_dossier": "primary",
      "is_primary": true
    },
    {
      "contact_id": "c44b…",
      "full_name": "Mark de Vries",
      "email": "mark@rabobank.nl",
      "company": "Rabobank",
      "role_on_dossier": "decision_maker",
      "is_primary": false
    }
  ],
  "meta": { "total": 2, "page": 1, "per_page": 25 }
}
POST/dossiers/:id/contacts

Einen vorhandenen Kontakt mit einer Rolle an ein Dossier knüpfen. Wenn is_primary auf true gesetzt wird, verliert ein vorheriger primärer Kontakt auf diesem Dossier diesen Status.

Request-Body
FeldTypBeschreibung
contact_id*uuidThe contact to link. Must belong to your organization.
role_on_dossier*stringOne of 'primary', 'hiring_manager', 'decision_maker', 'champion', 'gatekeeper', 'introducer' or 'other'.
is_primarybooleanDefault: false. Setting true demotes the previous primary contact on this dossier.
Beispielanfrage
curl -X POST https://leadgrid.io/api/v1/dossiers/a91c…/contacts \
  -H "Authorization: Bearer lg_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_id": "c44b…",
    "role_on_dossier": "decision_maker",
    "is_primary": false
  }'
Beispielantwort
{
  "data": {
    "dossier_id": "a91c…",
    "contact_id": "c44b…",
    "role_on_dossier": "decision_maker",
    "is_primary": false
  }
}
DELETE/dossiers/:id/contacts/:contact_id

Die Verknüpfung eines Kontakts mit einem Dossier aufheben. Der Kontakt selbst bleibt bestehen.

Beispielanfrage
curl -X DELETE https://leadgrid.io/api/v1/dossiers/a91c…/contacts/c44b… \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": {
    "dossier_id": "a91c…",
    "contact_id": "c44b…",
    "unlinked": true
  }
}
05: Ressourcen

Flows

Flows sind die Pipelines, durch die Dossiers sich bewegen. Jeder Flow hat geordnete Phasen mit optionalen Deadlines und Gewinnwahrscheinlichkeiten.

GET/flows

Flows in deiner Organisation auflisten. Phasen sind verschachtelt und nach Position geordnet.

Abfrageparameter
FeldTypBeschreibung
typestringFilter to 'candidate' or 'sales'.
pageintegerPage number. Default: 1.
per_pageintegerItems per page. Default: 25.
Beispielanfrage
curl "https://leadgrid.io/api/v1/flows?type=sales" \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": [
    {
      "id": "f01a…",
      "name": "Sales Flow",
      "type": "sales",
      "is_default": true,
      "stages": [
        {
          "id": "s1…",
          "name": "Lead",
          "position": 1,
          "deadline_days": 3,
          "win_probability": 14,
          "color": "#FF5C35"
        },
        {
          "id": "s2…",
          "name": "Discovery",
          "position": 2,
          "deadline_days": 5,
          "win_probability": 29,
          "color": "#22C55E"
        }
      ]
    }
  ],
  "meta": { "total": 1, "page": 1, "per_page": 25 }
}
GET/flows/:id/stages

Die Phasen für einen einzelnen Flow abrufen, sortiert nach Position. Nützlich, wenn du die flow_id bereits kennst und nur die Phasen möchtest.

Beispielanfrage
curl https://leadgrid.io/api/v1/flows/f01a…/stages \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": [
    {
      "id": "s1…",
      "name": "Lead",
      "position": 1,
      "deadline_days": 3,
      "win_probability": 14
    }
  ],
  "meta": { "total": 6, "page": 1, "per_page": 6 }
}
06: Ressourcen

Notizen

Notizen sind die Zeitleiste der Aktualisierungen, die an ein Dossier angehängt sind. Sie sind von ältester bis neuester sortiert und standardmäßig immer intern.

GET/dossiers/:id/notes

Notizen für ein Dossier auflisten, älteste zuerst.

Beispielanfrage
curl https://leadgrid.io/api/v1/dossiers/a91c…/notes \
  -H "Authorization: Bearer lg_live_your_key"
Beispielantwort
{
  "data": [
    {
      "id": "n1…",
      "dossier_id": "a91c…",
      "content": "Had a great first call, strong culture fit.",
      "is_internal": true,
      "created_at": "2026-04-14T09:12:30Z"
    }
  ],
  "meta": { "total": 3, "page": 1, "per_page": 25 }
}
POST/dossiers/:id/notes

Eine neue Notiz zu einem Dossier hinzufügen. Löst einen note.created-Webhook aus.

Request-Body
FeldTypBeschreibung
content*stringThe note text. Cannot be empty.
is_internalbooleanDefault: true. Internal notes are not shared.
Beispielanfrage
curl -X POST https://leadgrid.io/api/v1/dossiers/a91c…/notes \
  -H "Authorization: Bearer lg_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Followed up by email." }'
Beispielantwort
{
  "data": {
    "id": "n2…",
    "dossier_id": "a91c…",
    "content": "Followed up by email.",
    "is_internal": true,
    "created_at": "2026-04-15T12:04:10Z"
  }
}
07: Events

Webhooks

Konfiguriere einen Webhook-Endpunkt unter Einstellungen → API. LeadGrid sendet eine POST-Anfrage mit einem JSON-Body, wenn eines dieser Events eintritt.

Event-Typen
FeldTypBeschreibung
dossier.createdeventA new dossier was created (via API, UI or email).
dossier.updatedeventAny field on a dossier changed. Fires alongside stage_changed when applicable.
dossier.stage_changedeventcurrent_stage_id was updated.
dossier.deletedeventDossier was archived (status set to 'archived').
note.createdeventA new note was added to a dossier.
Example payload
POST https://your-app.com/webhooks/leadgrid
Content-Type: application/json
X-LeadGrid-Signature: t=1713178230,v1=3b2c4f…

{
  "id": "evt_…",
  "type": "dossier.stage_changed",
  "created_at": "2026-04-15T12:04:10Z",
  "data": {
    "id": "a91c…",
    "current_stage_id": "d8e2…",
    "status": "active"
  }
}

Signaturverifizierung

Jede Webhook-Anfrage enthält einen X-LeadGrid-Signature Header mit einem Zeitstempel und einer HMAC-SHA256-Signatur von `${"timestamp"}.${"body"}` signiert mit dem Geheimnis deines Endpunkts. Verifiziere sie, bevor du dem Payload vertraust.

node.js (verification)
import crypto from "node:crypto";

export function verifyLeadGridSignature(
  header: string,
  body: string,
  secret: string,
) {
  const parts = Object.fromEntries(
    header.split(",").map((p) => p.split("=")),
  );
  const { t, v1 } = parts as { t: string; v1: string };

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${t}.${body}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(v1),
  );
}
08: Referenz

Fehler & Rate Limits

Fehler verwenden Standard-HTTP-Statuscodes. Der Body enthält immer ein Error-Objekt mit einem stabilen Code und einer lesbaren Nachricht.

Error shape
{
  "error": {
    "code": "not_found",
    "message": "Dossier not found."
  }
}
Häufige Fehlercodes
FeldTypBeschreibung
unauthorized401Missing, malformed or invalid API key. Also returned for expired keys.
plan_required402Your organization is on Free or Pro. API access requires Growth.
forbidden403The API key doesn't include the required scope for this action.
not_found404The resource doesn't exist, or doesn't belong to your organization.
invalid_body400Missing required field, unknown value or malformed JSON.
rate_limited429You've exceeded the rate limit for your plan. Retry after the time in the Retry-After header.
internal500Unexpected server error. Safe to retry.
Growth Rate Limit
600 req / min / key
429-Antwort
Retry-After header in seconds
Jede Antwort enthält X-RateLimit-Limit und X-RateLimit-Remaining Header, damit du zurückschalten kannst, bevor du das Limit erreichst.