Ü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.
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.
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.
- 1Gehe zu Einstellungen → API und klicke auf API-Schlüssel erstellen.
- 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.
- 3Sende den Schlüssel als Bearer-Token bei jeder Anfrage mit.
curl https://leadgrid.io/api/v1/dossiers \ -H "Authorization: Bearer lg_live_your_key_here"
| Feld | Typ | Beschreibung |
|---|---|---|
| dossiers:read | scope | Dossiers auflisten und abrufen. |
| dossiers:write | scope | Dossiers erstellen, aktualisieren und archivieren. Auch erforderlich, um Phasen zu verschieben. |
| flows:read | scope | Flows auflisten und ihre Phasen lesen. |
| notes:read | scope | Notizen zu Dossiers lesen. |
| notes:write | scope | Neue Notizen zu Dossiers hinzufügen. |
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.
/dossiersDossiers in deiner Organisation auflisten. Unterstützt Filtern und Paginierung.
| Feld | Typ | Beschreibung |
|---|---|---|
| type | string | 'candidate' or 'sales'. |
| status | string | 'active', 'won', 'lost' or 'archived'. |
| stage_id | uuid | Return only dossiers currently in this stage. |
| page | integer | 1-based page number. Default: 1. |
| per_page | integer | Items per page (max 100). Default: 25. |
curl "https://leadgrid.io/api/v1/dossiers?type=sales&status=active" \ -H "Authorization: Bearer lg_live_your_key"
{
"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 }
}/dossiersEin 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. 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.
| Feld | Typ | Beschreibung |
|---|---|---|
| type* | string | 'candidate' or 'sales'. |
| name* | string | For candidates: the person's name. For sales: deal or account name. |
| string | Primary contact email. | |
| phone | string | Primary contact phone. |
| company | string | Candidate: current employer. Sales: target company. |
| role | string | Candidate: role they're applying for. Sales: role of the contact. |
| flow_id | uuid | Override the default flow. Must belong to your organization. |
| assigned_to | uuid | User ID of the member to assign this dossier to. |
| intake_notes | string | Director/intake notes shown in the dossier drawer. |
| contact_person | string | Sales only. Named contact at the target company. |
| deal_size | number | Sales only. Expected contract value. |
| deal_currency | string | Sales only. ISO 4217 currency code (e.g. 'EUR'). |
| cv | file (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. |
# 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"{
"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"
}
}/dossiers/:idEin einzelnes Dossier anhand der ID abrufen.
curl https://leadgrid.io/api/v1/dossiers/a91c… \ -H "Authorization: Bearer lg_live_your_key"
{
"data": {
"id": "a91c…",
"type": "sales",
"name": "KLM — Cabin crew hiring",
"deal_size": 62000,
"current_stage_id": "b77f…"
}
}/dossiers/:idEine 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.
| Feld | Typ | Beschreibung |
|---|---|---|
| name | string | Rename the dossier. |
| string | Update primary contact email. | |
| phone | string | Update phone. |
| company | string | Update company / employer. |
| role | string | Update role. |
| contact_person | string | Sales only. |
| deal_size | number | Sales only. |
| deal_currency | string | Sales only. |
| status | string | 'active', 'won', 'lost' or 'archived'. |
| assigned_to | uuid | Reassign to another member. Null to unassign. |
| intake_notes | string | Replace intake notes. |
| current_stage_id | uuid | Move to a new stage. Must belong to the dossier's flow. |
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" }'{
"data": {
"id": "a91c…",
"current_stage_id": "d8e2…",
"status": "active"
}
}/dossiers/:idArchiviert 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.
curl -X DELETE https://leadgrid.io/api/v1/dossiers/a91c… \ -H "Authorization: Bearer lg_live_your_key"
{
"data": {
"id": "a91c…",
"status": "archived"
}
}/dossiers/:id/cvEinen 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.
# 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
{
"data": {
"id": "a91c…",
"cv_url": "<org-id>/dossiers/a91c…/cv.pdf"
}
}Flows
Flows sind die Pipelines, durch die Dossiers sich bewegen. Jeder Flow hat geordnete Phasen mit optionalen Deadlines und Gewinnwahrscheinlichkeiten.
/flowsFlows in deiner Organisation auflisten. Phasen sind verschachtelt und nach Position geordnet.
| Feld | Typ | Beschreibung |
|---|---|---|
| type | string | Filter to 'candidate' or 'sales'. |
| page | integer | Page number. Default: 1. |
| per_page | integer | Items per page. Default: 25. |
curl "https://leadgrid.io/api/v1/flows?type=sales" \ -H "Authorization: Bearer lg_live_your_key"
{
"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 }
}/flows/:id/stagesDie 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.
curl https://leadgrid.io/api/v1/flows/f01a…/stages \ -H "Authorization: Bearer lg_live_your_key"
{
"data": [
{
"id": "s1…",
"name": "Lead",
"position": 1,
"deadline_days": 3,
"win_probability": 14
}
],
"meta": { "total": 6, "page": 1, "per_page": 6 }
}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.
/dossiers/:id/notesNotizen für ein Dossier auflisten, älteste zuerst.
curl https://leadgrid.io/api/v1/dossiers/a91c…/notes \ -H "Authorization: Bearer lg_live_your_key"
{
"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 }
}/dossiers/:id/notesEine neue Notiz zu einem Dossier hinzufügen. Löst einen note.created-Webhook aus.
| Feld | Typ | Beschreibung |
|---|---|---|
| content* | string | The note text. Cannot be empty. |
| is_internal | boolean | Default: true. Internal notes are not shared. |
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." }'{
"data": {
"id": "n2…",
"dossier_id": "a91c…",
"content": "Followed up by email.",
"is_internal": true,
"created_at": "2026-04-15T12:04:10Z"
}
}Webhooks
Konfiguriere einen Webhook-Endpunkt unter Einstellungen → API. LeadGrid sendet eine POST-Anfrage mit einem JSON-Body, wenn eines dieser Events eintritt.
| Feld | Typ | Beschreibung |
|---|---|---|
| dossier.created | event | A new dossier was created (via API, UI or email). |
| dossier.updated | event | Any field on a dossier changed. Fires alongside stage_changed when applicable. |
| dossier.stage_changed | event | current_stage_id was updated. |
| dossier.deleted | event | Dossier was archived (status set to 'archived'). |
| note.created | event | A new note was added to a dossier. |
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.
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),
);
}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": {
"code": "not_found",
"message": "Dossier not found."
}
}| Feld | Typ | Beschreibung |
|---|---|---|
| unauthorized | 401 | Missing, malformed or invalid API key. Also returned for expired keys. |
| plan_required | 402 | Your organization is on Free or Pro. API access requires Growth. |
| forbidden | 403 | The API key doesn't include the required scope for this action. |
| not_found | 404 | The resource doesn't exist, or doesn't belong to your organization. |
| invalid_body | 400 | Missing required field, unknown value or malformed JSON. |
| rate_limited | 429 | You've exceeded the rate limit for your plan. Retry after the time in the Retry-After header. |
| internal | 500 | Unexpected server error. Safe to retry. |
X-RateLimit-Limit und X-RateLimit-Remaining Header, damit du zurückschalten kannst, bevor du das Limit erreichst.