Erste Schritte
API und Webhooks sind in den Tarifen Pro und Business enthalten, ebenso in den 14 Testtagen. Den API-Schlüssel legt der Inhaber des Kontos unter Einstellungen → Integrationen an. Er wird genau einmal angezeigt; fordera speichert ihn nur als Hash.
Basis-Adresse: https://fordera.de/api/v1. Alle Antworten sind JSON, Zeitpunkte im Format ISO 8601 (UTC).
Typischer Ablauf mit einem CRM
- Einmalig:
GET /workflowsabrufen und die passendeidmerken. - Neuer Kunde im CRM:
POST /requestsmit dieserworkflowId. fordera verschickt die Anfrage. - Webhook
document.uploaded: Datei überfile.downloadUrlabholen und mitfile.sha256prüfen. - Webhook
request.completed: Akte im CRM als vollständig markieren.
Anmeldung
Jeder Aufruf trägt den Schlüssel im Kopf Authorization:
curl https://fordera.de/api/v1/workflows \
-H "Authorization: Bearer frd_IHR_SCHLUESSEL"Je Schlüssel sind 600 Aufrufe pro Minute möglich. Jeder Schlüssel hat Zugriff auf alle Daten Ihrer Firma und nur auf diese. Widerrufen Sie einen Schlüssel jederzeit unter Einstellungen → Integrationen.
Fehler
Fehler kommen mit passendem HTTP-Status und einem Text für Menschen (error). Wo ein Programm unterschiedlich reagieren soll, steht zusätzlich ein fester code, der sich nicht ändert.
| Status | code | Bedeutung |
|---|---|---|
| 400 | invalid_status | Unbekannter Wert für status in GET /requests |
| 400 | invalid_updated_since | updatedSince ist kein gültiger Zeitpunkt |
| 400 | Pflichtfeld fehlt oder ist ungültig (Text in error) | |
| 401 | invalid_api_key | Schlüssel fehlt, ist falsch oder widerrufen |
| 402 | Monatliches Anfrage-Kontingent Ihres Tarifs erreicht | |
| 403 | plan_without_api | Der Tarif enthält keine API. Schlüssel gültig, Upgrade nötig |
| 403 | E-Mail-Adresse des Kontos noch nicht bestätigt | |
| 404 | Nicht gefunden, oder gehört zu einer anderen Firma | |
| 409 | PATCH /customers/:id: Die E-Mail gehört schon einem anderen Kunden | |
| 409 | workflow_name_ambiguous | workflowName passt auf mehrere Workflows. Bitte workflowId senden |
| 429 | rate_limited | Zu viele Aufrufe. Kopf Retry-After nennt die Wartezeit in Sekunden |
Workflows
GET /workflows
Alle Workflows Ihrer Firma mit ihren Positionen, sortiert nach Name.
{
"data": [{
"id": "cm…",
"name": "Factoring: Neukunde / Bonitätsprüfung",
"description": "…",
"reminderDays": [3, 7, 14],
"expiryDays": 30,
"positions": [
{ "id": "cm…", "name": "BWA", "description": null, "type": "FILE", "required": true }
],
"createdAt": "…", "updatedAt": "…"
}]
}type ist FILE (Datei), TEXT, NUMBER, DATE oder CONSENT (Einwilligung mit Zustimmungsfeld). Die id einer Position heißt in Anfragen und Webhooks requirementId.
Anfragen
POST /requests
Legt eine Anfrage an und verschickt sie standardmäßig per E-Mail.
| Feld | Pflicht | Bedeutung |
|---|---|---|
workflowId | eines von beiden | ID aus GET /workflows (empfohlen) |
workflowName | eines von beiden | Name des Workflows, Groß- und Kleinschreibung egal |
recipientName | ja | Name des Empfängers |
recipientEmail | ja | E-Mail des Empfängers |
dueDays | nein | Frist in Tagen, Standard 7 |
introText | nein | Eigener Einleitungstext, längere Texte werden auf 600 Zeichen gekürzt |
sendEmail | nein | false: nur anlegen, Link selbst weitergeben. Standard true |
HTTP 201
{
"id": "cm…",
"portalUrl": "https://fordera.de/portal/…",
"status": "OPEN",
"emailSent": true
}emailSent meldet, ob der Mailversand tatsächlich angenommen wurde. Bei false trotz sendEmail: true erklärt emailError den Fehlschlag. Die Anfrage ist trotzdem angelegt, der portalUrl funktioniert.
GET /requests
Liste der Anfragen, neueste zuerst.
| Parameter | Bedeutung |
|---|---|
status | OPEN, PARTIAL, COMPLETE, OVERDUE oder ARCHIVED |
updatedSince | Nur Anfragen, die sich seit diesem Zeitpunkt geändert haben. Ideal für den regelmäßigen Abgleich |
limit | Einträge je Seite, Standard 50, höchstens 200 |
offset | Wie viele Einträge übersprungen werden, zum Weiterblättern |
{
"total": 312, "limit": 50, "offset": 0,
"data": [{
"id": "cm…", "recipientName": "…", "recipientEmail": "…",
"workflow": "…", "status": "PARTIAL",
"progress": { "done": 3, "total": 5, "requiredDone": 3, "requiredTotal": 4, "optionalOpen": 1 },
"portalUrl": "…", "openedAt": "…", "dueDate": "…",
"createdAt": "…", "updatedAt": "…"
}]
}COMPLETE heißt: Alle Pflichtpositionen liegen vor. Freiwillige Unterlagen können danach noch eintreffen (optionalOpen).
GET /requests/:id
Eine Anfrage mit allen Positionen und Dateien.
{
"id": "cm…", "status": "PARTIAL", "workflow": "…", "portalUrl": "…",
"recipientName": "…", "recipientEmail": "…",
"openedAt": "…", "dueDate": "…", "createdAt": "…",
"positions": [{
"requirementId": "cm…", "name": "Jahresabschluss", "type": "FILE",
"required": true, "status": "UPLOADED", "value": null, "rejectionReason": null,
"file": { …zuletzt hochgeladene Datei… },
"files": [ { "id": "cm…", "fileName": "abschluss.pdf", "mimeType": "application/pdf",
"fileSize": 182044, "sha256": "…", "uploadedAt": "…",
"downloadUrl": "https://fordera.de/api/v1/files/cm…" } ]
}],
"extraFiles": [ { …wie oben…, "comment": "Noch ein Kontoauszug" } ]
}Status einer Position: PENDING, UPLOADED, ACCEPTED, REJECTED, WAIVED, SKIPPED oder DECLINED. extraFiles sind Unterlagen, die der Empfänger freiwillig zusätzlich hochgeladen hat.
Dateien
GET /files/:id
Lädt eine Datei herunter, mit demselben Schlüssel. Jeder Abruf wird im Protokoll des Vorgangs vermerkt. Prüfen Sie die Datei gegen sha256, um sicherzugehen, dass sie seit dem Eingang unverändert ist.
curl -H "Authorization: Bearer frd_…" -o abschluss.pdf \
https://fordera.de/api/v1/files/cm…Kunden
| Aufruf | Bedeutung |
|---|---|
GET /customers?q=&limit=&offset= | Kundenstamm durchsuchen. Antwort { customers, total } |
POST /customers | Kunde anlegen oder anhand der E-Mail aktualisieren (name, email, organization, notes) |
GET /customers/:id | Einen Kunden abrufen |
PATCH /customers/:id | Einzelne Felder ändern |
DELETE /customers/:id | Kunden löschen |
Webhooks
fordera meldet Ereignisse per POST an eine https-Adresse Ihrer Wahl. Ziele legen Sie unter Einstellungen → Integrationen an und wählen dort, welche Ereignisse sie erhalten.
POST https://ihr-system.de/fordera
x-fordera-event: document.uploaded
x-fordera-event-id: evt_3f2c…
x-fordera-signature: 9a41… (HMAC-SHA256, hex)
{
"id": "evt_3f2c…",
"event": "document.uploaded",
"timestamp": "2026-10-06T09:12:44.120Z",
"data": { … }
}Ereignisse
| Ereignis | Wann | Felder in data |
|---|---|---|
request.created | Anfrage angelegt (App, API oder Serie) | requestId, recipientName, recipientEmail, workflow, status |
request.opened | Empfänger öffnet den Link zum ersten Mal | requestId, recipientName |
document.uploaded | Datei, Angabe oder Zusatzdatei eingegangen | requestId, requirementId, requirement, kind (file, field, extra), requestStatus, bei file und extra zusätzlich fileName und file, bei field value, bei extra comment. Bei extra sind requirement und requirementId null |
document.rejected | Ihr Team lehnt eine Unterlage ab | requestId, requirement, reason |
request.completed | Alle Pflichtpositionen liegen vor | requestId, recipientName, recipientEmail, workflow, optionalOpen, optionalSkipped |
reminder.sent | Erinnerung verschickt | requestId, reminderNumber, missing, missingRequired, manual |
file hat dieselben Felder wie in GET /requests/:id, einschließlich downloadUrl und sha256.
Echtheit prüfen
Bilden Sie den HMAC-SHA256 über den unveränderten Nachrichtentext mit dem Signatur-Geheimnis Ihres Ziels und vergleichen Sie ihn mit x-fordera-signature. Beispiel in Node.js:
import { createHmac, timingSafeEqual } from "node:crypto";
function istEcht(rohText, signatur, geheimnis) {
const erwartet = createHmac("sha256", geheimnis).update(rohText).digest("hex");
return erwartet.length === signatur.length &&
timingSafeEqual(Buffer.from(erwartet), Buffer.from(signatur));
}Zustellung und Wiederholung
Antworten Sie mit einem Status 2xx innerhalb von 5 Sekunden. Sonst gilt die Zustellung als gescheitert, und fordera versucht es erneut: nach etwa 1, 2, 4, 8 und 16 Stunden, insgesamt sechsmal. Eine Wiederholung trägt denselben Text, dieselbe Signatur und dieselbe id, damit Sie Doppelte überspringen können. timestamp ist der Zeitpunkt des Ereignisses, nicht der Zustellung.
Die Reihenfolge der Ereignisse ist nicht garantiert. Beim letzten Upload kann request.completed vor dem zugehörigen document.uploaded eintreffen. Verlassen Sie sich auf requestStatus und rufen Sie im Zweifel GET /requests/:id ab.
Zapier, Make und n8n
Ohne Programmierung: Legen Sie in Zapier, Make oder n8n einen Webhook-Auslöser an und tragen Sie dessen Adresse in fordera als Ziel ein. Jedes Ereignis startet dann Ihren Ablauf, etwa „Dokument eingegangen → Datei in SharePoint ablegen“. Für die andere Richtung („Neukunde im CRM → Anfrage auslösen“) nutzen Sie das HTTP-Modul des Werkzeugs mit POST /requests und dem Kopf Authorization.
Fragen zur Anbindung?
Schreiben Sie an info@fordera.de. Zur Datensicherheit siehe Sicherheit und den AV-Vertrag.