Fehlercodes
Fehler liefern { ok: false, error: { code, message, field?, meta?, request_id } } mit passendem HTTP-Status, niemals 200. Die Liste für /v1 und Embed stammt aus dem Backend-Register.
Fehlerstruktur
http
HTTP/1.1 402 Payment Required
Content-Type: application/json
X-Request-Id: 018f2b00-0000-7000-8000-0000000000ff
{
"ok": false,
"error": {
"code": "wallet.insufficient_balance",
"message": "Số dư ví không đủ để thực hiện giao dịch.",
"field": null,
"meta": null,
"request_id": "018f2b00-0000-7000-8000-0000000000ff"
}
}Warum domain.reason statt 0000
HTTP-nativ: Proxys, Monitoring und REST-Clients verstehen bereits Standard-HTTP-Statuscodes.
Selbsterklärend: wallet.insufficient_balance ist ohne Tabelle verständlich; neue Codes brechen bestehende Abläufe nicht.
Altsystem erwartet Zahlen? Der unveränderliche Code ist ein stabiler Übersetzungsschlüssel.
4 Regeln zur Fehlerbehandlung
Erst HTTP-Status, dann Fehlercode
Status steuert Wiederholungen, Warnungen und Schutzschalter; error.code steuert Benutzermeldungen. Statuscodes sind stabiler.
Unbekannte Codes dürfen Abläufe nicht abbrechen
Bei unbekannten Codes HTTP-Status nutzen, Code und request_id protokollieren und Ersatzmeldung anzeigen. Keine unbehandelten Ausnahmen.
request_id immer protokollieren
X-Request-Id steht in jeder Antwort und im Fehler. Geben Sie ihn für die Anfrageanalyse an den Support weiter.
Retry-After bei 429 und 503 beachten
Retry-After lesen statt feste Wartezeiten verwenden. 429 enthält auch X-RateLimit-Limit / Remaining / Reset.
Code-HTTP-Zuordnung
Nach Domain gruppiert. Die API-Referenz zeigt die Fehlerzweige je Endpunkt.
91 / 91 Codes angezeigt
Authentifizierung, Schlüssel und Limits partner.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
partner.invalid_key | 401 | Ungültiger API-Schlüssel. | Nein: unverändert erneut erfolglos |
partner.invalid_signature | 401 | Ungültige Anfragesignatur. | Nein: unverändert erneut erfolglos |
partner.timestamp_expired | 401 | Der Zeitstempel der Anfrage weicht zu stark von der Serverzeit ab. | Nein: unverändert erneut erfolglos |
partner.nonce_reused | 401 | Dieser Nonce wurde bereits verwendet. | Nein: unverändert erneut erfolglos |
partner.ip_not_allowed | 403 | Diese IP-Adresse steht nicht auf der Zulassungsliste. | Nein: unverändert erneut erfolglos |
partner.scope_denied | 403 | Dieser API-Schlüssel hat keine Berechtigung für diesen Endpunkt. | Nein: unverändert erneut erfolglos |
partner.key_suspended | 403 | Dieser API-Schlüssel ist derzeit gesperrt. | Nein: unverändert erneut erfolglos |
partner.key_revoked | 403 | Dieser API-Schlüssel wurde widerrufen. | Nein: unverändert erneut erfolglos |
partner.endpoint_disabled | 503 | Diese Endpunktgruppe ist vorübergehend außer Betrieb. | Ja: unverändert wiederholen |
partner.rate_limited | 429 | Das Anfragelimit wurde überschritten. Versuchen Sie es später erneut. | Ja: unverändert wiederholen |
partner.package_not_visible | 404 | Dieses Paket kann mit Ihrem Schlüssel nicht gekauft werden. | Nein: unverändert erneut erfolglos |
partner.daily_quota_exceeded | 429 | Das tägliche Anfragekontingent ist aufgebraucht. Versuchen Sie es morgen erneut. | Ja: unverändert wiederholen |
partner.wrong_host | 403 | Dieser Schlüssel passt nicht zum Host. Verwenden Sie `https://api-testing.tongkhoesim.com` für `tke_test_` und `https://api.tongkhoesim.com` für `tke_live_`. | Nein: unverändert erneut erfolglos |
Allgemeine API-Fehler internal.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
internal.validation_failed | 400 | Die übermittelten Daten sind ungültig. | Nein: unverändert erneut erfolglos |
internal.invalid_filter | 400 | Ungültige Filterbedingung. | Nein: unverändert erneut erfolglos |
internal.invalid_sort_field | 400 | Ungültiges Sortierfeld. | Nein: unverändert erneut erfolglos |
internal.unauthenticated | 401 | Sie sind nicht angemeldet oder Ihre Sitzung ist abgelaufen. | Nein: unverändert erneut erfolglos |
internal.forbidden | 403 | Sie haben keine Berechtigung für diese Aktion. | Nein: unverändert erneut erfolglos |
internal.not_found | 404 | Die angeforderte Ressource wurde nicht gefunden. | Nein: unverändert erneut erfolglos |
internal.route_not_found | 404 | Dieser Pfad existiert nicht. Prüfen Sie Methode und Pfad in der Dokumentation. | Nein: unverändert erneut erfolglos |
internal.method_not_allowed | 405 | Diese HTTP-Methode wird nicht unterstützt. | Nein: unverändert erneut erfolglos |
internal.conflict | 409 | Ein Zustandskonflikt verhindert diese Aktion. | Nein: unverändert erneut erfolglos |
internal.unsupported_media_type | 415 | Dieser Inhaltstyp wird nicht unterstützt. | Nein: unverändert erneut erfolglos |
internal.rate_limited | 429 | Zu viele Anfragen. Versuchen Sie es später erneut. | Ja: unverändert wiederholen |
internal.server_error | 500 | Ein Systemfehler ist aufgetreten. Versuchen Sie es später erneut. | Ja: unverändert wiederholen |
internal.service_unavailable | 503 | Der Dienst ist vorübergehend nicht verfügbar. Versuchen Sie es später erneut. | Ja: unverändert wiederholen |
internal.limit_exceeded | 422 | Das zulässige Limit ist erreicht. Entfernen Sie einige Einträge und versuchen Sie es erneut. | Nein: unverändert erneut erfolglos |
internal.money_frozen | 503 | Finanztransaktionen sind zur Prüfung des Hauptbuchs vorübergehend ausgesetzt. Versuchen Sie es später erneut. | Ja: unverändert wiederholen |
Tarifkatalog catalog.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
catalog.cursor_mismatch | 400 | Dieser Cursor passt nicht zu den aktuellen Filtern. Beginnen Sie ohne cursor-Parameter auf der ersten Seite. | Nein: unverändert erneut erfolglos |
Angebote und Bestellungen order.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
order.quote_not_found | 404 | Angebot nicht gefunden. | Nein: unverändert erneut erfolglos |
order.quote_expired | 409 | Dieses Angebot ist abgelaufen. Erstellen Sie ein neues. | Nein: unverändert erneut erfolglos |
order.quote_already_committed | 409 | Dieses Angebot wurde bereits in eine Bestellung umgewandelt. | Nein: unverändert erneut erfolglos |
order.package_not_allowed | 400 | Dieses Paket existiert nicht oder ist nicht zum Kauf verfügbar. | Nein: unverändert erneut erfolglos |
order.not_deliverable | 409 | Diese Bestellung ist noch nicht abgeschlossen; die Aktion ist daher nicht verfügbar. | Nein: unverändert erneut erfolglos |
order.quantity_limit_exceeded | 400 | Die Anzahl der eSIMs überschreitet das Limit pro Bestellung. | Nein: unverändert erneut erfolglos |
order.fulfillment_config_changed | 409 | Die Bereitstellungskonfiguration des Pakets hat sich geändert. Erstellen Sie ein neues Angebot. | Nein: unverändert erneut erfolglos |
order.refund_suggestion_pending | 409 | Für diese Bestellung wartet ein Erstattungsvorschlag auf Freigabe. Bearbeiten Sie diesen zuerst. | Nein: unverändert erneut erfolglos |
eSIM esim.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
esim.out_of_stock | 409 | Für dieses Paket ist nicht genügend Bestand vorhanden. | Nein: unverändert erneut erfolglos |
esim.not_cancellable | 409 | Der Status dieser eSIM erlaubt keine Stornierung. | Nein: unverändert erneut erfolglos |
esim.lpa_not_available | 409 | Diese eSIM hat noch keinen LPA-Code (noch nicht aktiviert oder registriert). | Nein: unverändert erneut erfolglos |
esim.not_eligible | 409 | Diese eSIM ist nicht für eine Aufladung berechtigt. | Nein: unverändert erneut erfolglos |
esim.not_activated | 409 | Diese eSIM ist noch nicht installiert. Installieren und aktivieren Sie sie vor der Aufladung. | Nein: unverändert erneut erfolglos |
esim.topup_not_supported | 409 | Dieses Paket unterstützt keine Aufladungen. | Nein: unverändert erneut erfolglos |
esim.topup_provider_mismatch | 409 | Dieses Aufladepaket gehört zu einem anderen Anbieter. Wählen Sie ein für diese eSIM angebotenes Paket. | Nein: unverändert erneut erfolglos |
esim.refund_not_eligible | 409 | Diese eSIM ist nicht für einen Erstattungsantrag berechtigt. | Nein: unverändert erneut erfolglos |
esim.refund_request_pending | 409 | Für diese eSIM ist bereits ein Erstattungsantrag offen. | Nein: unverändert erneut erfolglos |
esim.suspended | 409 | Diese eSIM ist gesperrt. Reaktivieren Sie sie vor dieser Aktion. | Nein: unverändert erneut erfolglos |
Wallet wallet.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
wallet.frozen | 409 | Dieses Wallet ist eingefroren und kann nicht belastet werden. | Nein: unverändert erneut erfolglos |
wallet.velocity_hold | 409 | Dieses Wallet ist zur Prüfung gesperrt. Wenden Sie sich an den Support. | Nein: unverändert erneut erfolglos |
wallet.insufficient_balance | 402 | Das Wallet-Guthaben reicht für diese Transaktion nicht aus. | Nein: unverändert erneut erfolglos |
wallet.deleted | 409 | Das Ziel-Wallet ist ungültig (gelöscht). | Nein: unverändert erneut erfolglos |
wallet.velocity_exceeded | 429 | Die Transaktionsgrenze wurde in kurzer Zeit überschritten. Das Wallet wurde zur Prüfung gesperrt. | Nein: unverändert erneut erfolglos |
Erstattungsanträge refund.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
refund.note_required | 400 | Geben Sie einen Grund für die Ablehnung der Erstattung an. | Nein: unverändert erneut erfolglos |
Verkaufspreise pricing.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
pricing.no_price_for_buyer | 409 | Für Sie ist noch kein Verkaufspreis für dieses Paket festgelegt. | Nein: unverändert erneut erfolglos |
eSIM-Anbieter provider.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
provider.disabled | 409 | Der Anbieter dieses Pakets ist deaktiviert; ein Verkauf ist nicht möglich. | Nein: unverändert erneut erfolglos |
provider.api_group_disabled | 409 | Diese Dienstgruppe des Anbieters ist deaktiviert. | Nein: unverändert erneut erfolglos |
provider.not_registered | 500 | Für diesen Anbieter ist kein Konnektor eingerichtet. | Ja: unverändert wiederholen |
provider.unsupported | 400 | Dieser Anbieter unterstützt diese Aktion nicht. | Nein: unverändert erneut erfolglos |
provider.timeout | 504 | Die Antwort des Anbieters hat zu lange gedauert. Versuchen Sie es später erneut. | Ja: unverändert wiederholen |
provider.auth_failed | 502 | Die Authentifizierung beim Anbieter ist fehlgeschlagen. | Ja: unverändert wiederholen |
provider.rate_limited | 429 | Der Anbieter begrenzt Anfragen. Versuchen Sie es später erneut. | Ja: unverändert wiederholen |
provider.malformed_response | 502 | Der Anbieter hat ungültige Daten zurückgegeben. | Ja: unverändert wiederholen |
provider.call_failed | 502 | Der Aufruf beim Anbieter ist fehlgeschlagen. | Ja: unverändert wiederholen |
provider.out_of_stock | 409 | Dieses Paket ist beim Anbieter ausverkauft. | Nein: unverändert erneut erfolglos |
provider.msisdn_taken | 409 | Diese MSISDN gehört beim Anbieter bereits zu einem anderen Teilnehmer. | Nein: unverändert erneut erfolglos |
provider.msisdn_exhausted | 409 | Beim Anbieter ist keine verwendbare MSISDN mehr verfügbar. | Nein: unverändert erneut erfolglos |
Idempotency idempotency.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
idempotency.conflict | 409 | Dieser Idempotency-Key wurde bereits mit anderem Inhalt verwendet. | Nein: unverändert erneut erfolglos |
Anbieterfunktionen capability.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
capability.not_supported | 422 | Dieses Paket unterstützt die angeforderte Funktion nicht. | Nein: unverändert erneut erfolglos |
Testmodus / Simulation testmode.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
testmode.live_key_forbidden | 403 | Dieser Endpunkt erfordert einen Testschlüssel (`tke_test_`) auf api-testing. Verwenden Sie statt des Live-Schlüssels einen Testschlüssel derselben Organisation. | Nein: unverändert erneut erfolglos |
testmode.not_test_item | 422 | Diese eSIM ist ein Live-Datensatz; der Testmodus bearbeitet nur Test-eSIMs. Beantragen Sie für eine echte Bestellung eine Erstattung. | Nein: unverändert erneut erfolglos |
testmode.invalid_scenario | 422 | Ungültiges Szenario. Senden Sie mindestens eines von `data_used_mb`, `status`, `expire_now`, `throttled`; `status` erlaubt nur released|installed|enabled|disabled. | Nein: unverändert erneut erfolglos |
testmode.no_sellable_package | 422 | Zum Erstellen von Beispieldaten fehlt ein Paketpreis. Mindestens ein verkäufliches Paket mit Preis ist erforderlich. | Nein: unverändert erneut erfolglos |
Webhook webhook.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
webhook.health_check_failed | 422 | Die Webhook-URL hat beim Funktionstest nicht gültig geantwortet. | Nein: unverändert erneut erfolglos |
webhook.url_not_allowed | 422 | Diese Webhook-URL ist nicht zulässig. Sie muss öffentlich sein und https verwenden. | Nein: unverändert erneut erfolglos |
webhook.not_configured | 404 | Für diesen API-Schlüssel ist kein Webhook eingerichtet. | Nein: unverändert erneut erfolglos |
webhook.delivery_not_found | 404 | Webhook-Zustellung nicht gefunden. | Nein: unverändert erneut erfolglos |
webhook.already_configured | 409 | Dieser API-Schlüssel hat bereits einen Webhook (einen pro Schlüssel). Ändern Sie ihn mit `PUT /v1/webhooks/{id}` oder löschen Sie ihn mit `DELETE /v1/webhooks/{id}`, bevor Sie einen neuen erstellen. | Nein: unverändert erneut erfolglos |
webhook.not_found | 404 | Dieser Webhook-Endpunkt gehört nicht zum aufrufenden API-Schlüssel. | Nein: unverändert erneut erfolglos |
Organisationsstatus org.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
org.invoice_profile_incomplete | 422 | Das Rechnungsprofil der Organisation ist unvollständig (Firmenname, Steuernummer, Adresse). | Nein: unverändert erneut erfolglos |
org.suspended | 403 | Diese Organisation ist derzeit gesperrt. | Nein: unverändert erneut erfolglos |
org.closed | 403 | Diese Organisation ist geschlossen. | Nein: unverändert erneut erfolglos |
Öffentliche Einbettung embed.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
embed.invalid_token | 401 | Ungültiges Einbettungstoken. | Nein: unverändert erneut erfolglos |
embed.token_revoked | 410 | Dieser Einbettungskanal ist nicht mehr aktiv. | Nein: unverändert erneut erfolglos |
embed.rate_limited | 429 | Dieser Einbettungskanal ruft zu schnell auf. Versuchen Sie es später erneut. | Ja: unverändert wiederholen |
embed.package_not_visible | 404 | Paket nicht gefunden. | Nein: unverändert erneut erfolglos |
MwSt.-Rechnungen invoice.*
| code | HTTP | Bedeutung | Wiederholbar? |
|---|---|---|---|
invoice.order_not_settled | 409 | Die Bestellung ist wegen einer laufenden Erstattung noch nicht abgerechnet. Versuchen Sie die Rechnungsstellung in einigen Minuten erneut. | Ja: unverändert wiederholen |
invoice.profile_incomplete | 422 | Das Rechnungsprofil der Organisation ist unvollständig. Ergänzen Sie es vor der Rechnungsstellung. | Nein: unverändert erneut erfolglos |
invoice.already_requested | 409 | Für diese Bestellung liegt bereits eine Rechnung vor. | Nein: unverändert erneut erfolglos |
invoice.nothing_to_invoice | 409 | Nach Abzug der Erstattungen bleibt kein Rechnungsbetrag übrig. | Nein: unverändert erneut erfolglos |
invoice.amount_changed | 409 | Eine neue Erstattung hat den Bestellbetrag geändert. Prüfen Sie den Betrag und stellen Sie die Rechnung erneut aus. | Ja: unverändert wiederholen |
invoice.buyer_invalid | 422 | Die Angaben des Rechnungsempfängers sind unvollständig oder die Steuernummer ist ungültig. | Nein: unverändert erneut erfolglos |