Fehlerbehandlung
Cord verwendet übliche HTTP-Codes und eine vorhersehbare Fehlerstruktur, um Erfolg oder Fehlschlag anzuzeigen.
HTTP-Statuscodes
Die Cord-API gibt immer Standard-HTTP-Statuscodes zurück. Als Faustregel gilt:
2xxbedeutet Erfolg.4xxbedeutet einen Fehler in den übermittelten Angaben (z. B. fehlende Parameter, ungültiges Token).5xxbedeutet einen Fehler auf den Servern von Cord (sehr selten).
Übersicht der Codes
| Code | Beschreibung |
|---|---|
| 200 OK | Alles hat wie erwartet funktioniert. |
| 400 Bad Request | Die Anfrage war nicht zulässig. Meist bedeutet das invalid_request (fehlende Felder) oder invalid_json; außerdem invalid_cursor oder invalid_api_version. |
| 401 Unauthorized | Ihr API-Schlüssel fehlt, ist falsch oder wurde widerrufen. |
| 402 Payment Required | Der Vorgang erfordert einen höheren Tarif (subscription_required), überschreitet ein Limit Ihres aktuellen Tarifs (plan_limit_reached, z. B. die Anzahl der Kunden oder Produkte) oder der Schlüssel überschreitet die Anzahl der Schlüssel, die Ihr Tarif enthält (subscription_key_limit). |
| 403 Forbidden | Ihre Berechtigungen reichen nicht aus (z. B. ein Schreibversuch mit einem nur lesenden Schlüssel oder ein öffentlicher Schlüssel, der einen Vorgang außerhalb seines Geltungsbereichs versucht). |
| 404 Not Found | Die Ressource (Angebot, Kunde, Rechnung) existiert nicht. |
| 409 Conflict | Ein ungültiger Statuswechsel für die Ressource (invalid_state) – zum Beispiel das Bestätigen eines Angebots, das noch ein Entwurf ist, oder das Löschen von Testdaten (/api/test-mode/reset), ohne sich in einer Sandbox-Organisation zu befinden. Auch, wenn eine andere Anfrage mit demselben Idempotency-Key noch läuft (idempotency_in_progress), oder wenn eine gestempelte Rechnung eine Gutschrift braucht, statt storniert zu werden (credit_note_required). |
| 413 Payload Too Large | Der Body ist größer als 1 MB (payload_too_large); bei POST /api/v1/elements/ai-draft ist die Datei größer als 4 MB, bei POST /api/v1/setup/plans größer als 3 MB. |
| 415 Unsupported Media Type | Der Body wurde nicht als application/json gesendet (unsupported_media_type). |
| 422 Unprocessable Entity | Sie haben einen Idempotency-Key mit einer anderen Anfrage wiederverwendet (idempotency_key_reused), oder die KI hat im Text keine Produkte gefunden (no_items). |
| 429 Too Many Requests | Sie haben ein Limit an Anfragen pro Minute überschritten (rate_limited, siehe Anfragelimits), das monatliche API-Kontingent Ihres Tarifs (api_quota_exceeded) oder das KI-Kontingent (ai_quota_exceeded). Beachten Sie den Header Retry-After. |
| 502 Bad Gateway | Ein externer Anbieter hat den Vorgang abgelehnt oder nicht abgeschlossen: der Steueranbieter bei der Ausstellung (provider_error) oder der Versand einer E-Mail (send_failed). |
| 503 Service Unavailable | Ein Dienst, von dem der Vorgang abhängt, hat nicht geantwortet – zum Beispiel konnte kein Wechselkurs (fx_unavailable) oder kein Steuerkatalog (tax_catalog_unavailable) abgerufen oder Ihr Abonnement nicht geprüft werden (subscription_verification_unavailable). Cord erfindet nie einen Kurs: Kann er ihn nicht belegen, schlägt der Vorgang geschlossen fehl. Versuchen Sie es später erneut. |
Aufbau des Fehlerobjekts
Bei einem 4xx- oder 5xx-Fehler antwortet Cord immer mit einem flachen (nicht verschachtelten) JSON-Objekt mit zwei Feldern: error (eine lesbare Meldung zum Anzeigen oder Protokollieren) und code (eine stabile Zeichenkette für Ihre Fehlerbehandlung). Manche Fehler fügen je nach Fall weitere Felder hinzu (siehe Beispiele unten).
Beispiel für eine Fehlerantwort:
{
"error": "The company name is required",
"code": "invalid_request"
}
Beispiel mit zusätzlichen Feldern (Tariflimit, 402):
{
"error": "Your plan allows 50 clients. Free up space or upgrade your plan to continue.",
"code": "plan_limit_reached",
"resource": "clients",
"limit": 50,
"plan": "starter"
}
Verlassen Sie sich beim Parsen der Antwort nicht auf die verschachtelte Form error.code / error.message: error ist immer die Zeichenkette der Meldung, und code ist ein Geschwisterfeld auf derselben Ebene, keine Eigenschaft von error.
Jede Antwort von /api/v1 enthält den Header Cord-Request-Id (req_…). Bei einem Fehler wiederholt der Body ihn als request_id und ergänzt doc_url, einen Link zur Erklärung dieses Codes auf dieser Seite. Geben Sie die request_id an, wenn Sie sich an den Support wenden: Damit finden wir Ihre genaue Anfrage.
{
"error": "API key inválida o revocada.",
"code": "invalid_key",
"request_id": "req_3f9c2a1b7d4e6f8a0b1c2d3e",
"doc_url": "https://docs.cordhq.app/docs/desarrolladores/esenciales/errores#invalid_key"
}
Häufige Fehlercodes (code)
-
invalid_json: Der Body IhrerPOST-Anfrage ist kein gültiges JSON, oderContent-Type: application/jsonwurde nicht gesendet. -
invalid_request: Eine fachliche Validierung ist fehlgeschlagen (fehlendes Feld, Rabatt außerhalb des zulässigen Bereichs, ein Angebot ohne gültigen Kunden). Das Felderrornennt den genauen Grund. -
invalid_fiscal_data(400): Die Steuerdaten incliente.fiscalbestehen die Validierung des Landes nicht. Die Antwort enthältissues, eine Liste von{ field, code }. Siehe Steuerformular. -
missing_key/invalid_key: Der HeaderAuthorization: Bearerfehlt, oder der Schlüssel existiert nicht bzw. wurde widerrufen. -
token_expired: Die Anmeldedaten einer autorisierten Verbindung (Zapier, Make) sind abgelaufen. Die App erneuert sie selbst mit ihrem Refresh-Token. -
insufficient_scope: Ihr Schlüssel hat nicht den nötigen Geltungsbereich (ein nur lesender Schlüssel hat versucht zu schreiben, oder ein öffentlicher Schlüssel hat eine Route außerhalb seiner erlaubten Liste aufgerufen). -
insufficient_permissions(403): Ein eingeschränkter Schlüssel (rk_) hat keine Berechtigung für die Ressource dieser Route oder wurde mit MCP verwendet. Das Felderrornennt die Ressource. -
ip_not_allowed(403): Für den Schlüssel sind erlaubte IPs hinterlegt, und die Anfrage kam von einer anderen. Das Felderrorenthält die IP, die Cord gesehen hat. -
key_expired(401): Der Schlüssel ist abgelaufen, oder er wurde rotiert und seine Übergangsfrist ist beendet. Verwenden Sie den neuen Schlüssel oder erstellen Sie einen weiteren. -
not_found: Die angeforderte Ressource existiert in Ihrer Organisation nicht. -
subscription_required: Die Funktion erfordert einen höheren Tarif. Die Antwort enthältplan(den aktuellen) undplan_required. -
plan_limit_reached: Sie haben eine harte Grenze Ihres Tarifs erreicht (Kunden, Produkte oder aktive Angebote). Die Antwort enthältresource,limitundplan. -
integration_limit_reached(403): Ihre Integrationen haben bereits die 100 Webhook-Abonnements angelegt, die pro Organisation erlaubt sind. Löschen Sie die, die Sie nicht mehr verwenden. -
rate_limited/api_quota_exceeded: Limit für Anfragen pro Minute oder für das monatliche API-Kontingent. Versuchen Sie es unter Beachtung vonRetry-Aftererneut. -
fx_unavailable/tax_catalog_unavailable: Ein Drittanbieterdatum (Wechselkurs oder Steuerkatalog) ließ sich nicht verlässlich abrufen. Der Vorgang wurde nicht abgeschlossen – gehen Sie nicht davon aus, dass er stattgefunden hat. -
subscription_key_limit(402): Ihre Organisation hat mehr aktive Schlüssel, als ihr Tarif enthält (zum Beispiel nach einem Downgrade), und dieser Schlüssel liegt außerhalb des Kontingents; die ältesten funktionieren weiter. Widerrufen Sie Schlüssel, die Sie nicht mehr verwenden, oder upgraden Sie. Das Kontingent zählt aktive geheime, eingeschränkte und öffentliche Schlüssel, ohne per OAuth autorisierte Verbindungen: 2 im kostenlosen Tarif, 5 in Starter, 20 in Professional, 50 in Scale und 200 in Developer. -
subscription_verification_unavailable(503): Cord konnte Ihr Abonnement nicht prüfen oder die Nutzung des Aufrufs nicht erfassen. Der Vorgang wurde nicht ausgeführt; versuchen Sie es erneut. -
invalid_api_version(400): Der HeaderCord-Versionfordert eine Version an, die es nicht gibt. Die Meldung listet die verfügbaren auf. Siehe API-Versionen. -
invalid_cursor(400): Dercursorist ungültig. Verwenden Sie dennext_cursorder vorherigen Antwort unverändert. -
payload_too_large(413): Der JSON-Body ist größer als 1 MB, oder die anPOST /api/v1/elements/ai-draftgesendete Datei ist größer als 4 MB. -
unsupported_media_type(415): Der Body kommt nicht alsapplication/json(bzw. beiPOST /api/v1/elements/ai-draftnicht alsmultipart/form-data). -
test_mode_only(403): Die Simulatoren unter/api/v1/test_helpersfunktionieren nur mit einemsk_test_-Schlüssel und in der Testumgebung. -
credit_note_required(409): Die bereits gestempelte Rechnung kann nicht direkt storniert werden. Stellen Sie eine Gutschrift mitaction: "credit_note"aus. -
provider_error(502): Der Steueranbieter hat die Ausstellung abgelehnt oder nicht abgeschlossen. Das Felderrornennt den Grund. -
send_failed(502): Die E-Mail der Rechnung konnte nicht gesendet werden. Versuchen Sie den Versand erneut. -
ai_quota_exceeded(429) /no_items(422) /ai_unavailable(502 oder 503) /missing_text/text_too_long(400): Fehler der KI-Routen (POST /api/v1/cotizaciones/iaundPOST /api/v1/elements/ai-draft): Das KI-Kontingent Ihres Tarifs ist aufgebraucht, der Text enthielt keine Produkte, die KI ist nicht verfügbar oder konnte die Anfrage nicht verarbeiten, oder der Text fehlt bzw. überschreitet das Maximum. Beiai-draftkommen diese Codes als Ereigniserrorinnerhalb des Streams an. -
invalid_state: Die Ressource befindet sich nicht in einem Status, der den Vorgang erlaubt, oder sie hat sich während der Verarbeitung geändert. Es wurde nichts angewendet. -
invalid_url: Die URL eines Webhooks ist nichthttps://oder verweist auf einen internen Host. -
invalid_idempotency_key/idempotency_key_reused/idempotency_in_progress/idempotency_unavailable: Siehe nächster Abschnitt. -
secret_key_in_browser(403): Ein geheimer Schlüssel kam aus einem Browser. Er liegt bereits offen im Quellcode der Seite: Widerrufen Sie ihn im Tab Schlüssel der Cord Workbench und rufen Sie die API nur von Ihrem Server aus auf. -
missing_origin/unauthorized_origin/invalid_origin(403): Ein öffentlicher Schlüssel kam ohneOriginan oder von einer Domain, die nicht zu den erlaubten Domains Ihrer Organisation gehört (Einstellungen › Einbettbarer Angebotsrechner). -
origin_allowlist_required(403): Ein öffentlicher Live-Schlüssel funktioniert nur, wenn unter Einstellungen › Einbettbarer Angebotsrechner erlaubte Domains konfiguriert sind.pk_test_-Schlüssel funktionieren von jedem Ursprung aus.
Anfragelimits
Cord wendet diese Limits pro Zeitfenster von einer Minute an, sofern nicht anders angegeben. Wird eines überschritten, antwortet Cord mit 429 und code: "rate_limited", in der Regel mit dem Header Retry-After in Sekunden. Die als strikt markierten Limits lassen keine Anfragen durch, wenn Cord sie nicht zählen kann: Bei /api/v1/cotizaciones/{id} und /api/v1/elements/ai-draft antworten sie dann mit 503 und error: "access_temporarily_unavailable".
| Limit | Geltungsbereich | Gilt für |
|---|---|---|
| 120 pro Minute | Pro Quell-IP | Jede Anfrage an /api/v1 und an den MCP-Server, mit jedem Schlüssel, noch vor der Prüfung des Schlüssels. |
| 600 pro Minute | Pro geheimem Schlüssel (sk_, rk_ oder OAuth-Verbindung) |
Jede Anfrage an /api/v1 und an den MCP-Server. |
| 120 pro Minute | Pro öffentlichem Schlüssel (pk_) |
Die vier Routen, die ein pk_-Schlüssel akzeptiert. |
| 120 pro Minute (strikt) | Pro Organisation | POST und DELETE auf /api/v1/cotizaciones/{id} sowie die MCP-Tools, die den Status eines Angebots ändern. |
| 20 pro Minute | Pro Schlüssel | POST /api/v1/webhooks. |
| 20 pro Minute | Pro Organisation | POST /api/v1/cotizaciones/ia. |
| 6 pro Minute pro IP, 60 pro Minute und 500 pro Tag pro Organisation (strikt) | IP und Organisation | POST /api/v1/elements/ai-draft. |
| 6 pro Tag (strikt) | Pro Organisation | POST /api/v1/setup/plans und proponer_configuracion in MCP. |
Da das Limit pro IP niedriger ist als das eines geheimen Schlüssels, erreicht ein Server, der alles von einer einzigen IP sendet, zuerst die 120 pro Minute. Unabhängig von diesen Limits verbrauchen Live-Schlüssel das monatliche API-Kontingent Ihres Tarifs (api_quota_exceeded).
Sichere Wiederholungen mit Idempotency-Key
Bricht eine Anfrage, die etwas anlegt oder ändert (POST, PATCH, DELETE), wegen eines Netzwerkfehlers oder Timeouts ab, wissen Sie nicht, ob Cord sie ausgeführt hat. Senden Sie den Header Idempotency-Key mit einem eindeutigen Wert pro Vorgang (zum Beispiel eine selbst erzeugte UUID) und wiederholen Sie die Anfrage mit demselben Schlüssel und demselben Body:
curl -X POST "https://cordhq.app/api/v1/clientes" \
-H "Authorization: Bearer sk_live_tU..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5d9c2b7e-6f1a-4c3d-9e8b-2a1f0c7d6e5b" \
-d '{ "empresa": "ACME Corp" }'
- Wiederholung mit demselben Schlüssel und demselben Body: Cord gibt die ursprüngliche Antwort zurück, ohne den Vorgang erneut auszuführen oder ihn auf Ihr Kontingent anzurechnen. Die wiederholte Antwort enthält den Header
Idempotent-Replayed: true. - Derselbe Schlüssel mit anderem Body, anderer Methode oder Route:
422 idempotency_key_reused. Verwenden Sie für jeden anderen Vorgang einen neuen Schlüssel. - Die erste Anfrage ist noch nicht abgeschlossen:
409 idempotency_in_progress. Warten Sie und versuchen Sie es erneut. - Fehler
5xxund429: werden nicht gespeichert, Sie können also mit demselben Schlüssel erneut versuchen. - Der Schlüssel gilt pro API-Schlüssel, akzeptiert 1 bis 255 sichtbare Zeichen (sonst
invalid_idempotency_key) und verfällt nach 24 Stunden. - Kann Cord den Schlüssel nicht reservieren, antwortet es mit
503 idempotency_unavailable, ohne den Vorgang auszuführen.
Der Header ist optional: Ohne ihn wird jede Anfrage so ausgeführt, wie sie eintrifft.