Wenn etwas nicht geht: Fehlercodes und Abhilfe
Hier findest du Hilfe, wenn ein Programm keine Daten aus PetWorkers bekommt. Die Fehlermeldung nennt meist schon den Grund.
Wer hat Zugriff?
- Administratoren verwalten Zugänge unter System → API-Schlüssel und System → MCP.
- Programme brauchen einen aktiven, gültigen Schlüssel. Seine Stufe und Bereichsfreigaben begrenzen den Zugriff. Ein zugeordneter Kontakt muss aktiv sein; seine Rechte können zusätzlich einschränken.
- Schreibzugriffe brauchen zusätzlich Schreiben erlauben. Jeder Bereich hat eigene Lese- und Schreibrechte. Die Schnittstelle bietet nicht jede Funktion der Oberfläche an.
- Die Schnittstelle selbst legt keine API-Schlüssel an. Details: Rollen und Rechte.
Welche E-Mails werden verschickt?
- Lesen sowie Schlüssel anlegen, ändern oder sperren: keine E-Mails.
- Spezielle Assistent-Aktionen für Termine, Kunden und Tiere: keine Kundenmail und kein Rechnungsversand. Termine entstehen ohne Benachrichtigung.
- Andere Schreibaktionen: Beachte die Beschreibung des jeweiligen Bereichs. Eine Newsletter-Abmeldung kann beispielsweise eine Meldung an den Betreiber auslösen.
Kurz gesagt: Lies zuerst error.code und error.message in der Antwort. Öffne danach System → API-Schlüssel → Zugriffsprotokoll. Prüfe den betroffenen Aufruf.
Begriffe: API bedeutet Schnittstelle für andere Programme. Ein Endpunkt ist eine bestimmte Abrufadresse. JSON ist das Textformat der Antworten; eine Kennung (id) bezeichnet einen Eintrag.
So grenzt du den Fehler ein
- Lies in der Antwort
error.codeunderror.message. - Öffne als Administrator System → API-Schlüssel → Zugriffsprotokoll.
- Suche den Aufruf anhand von Uhrzeit und Pfad.
- Vergleiche den Fehler mit den folgenden Erklärungen.
Ein erfolgreicher neuer Versuch liefert statt error den Inhalt unter data.
1. So liest du die Fehlerantwort
Was macht das? Diese Fehlerantwort nennt die abgelehnte Absender-Adresse.
{
"error": {
"status": 403,
"code": "ip_not_allowed",
"message": "Der Zugriff von 203.0.113.99 ist für diesen Schlüssel nicht freigegeben."
}
}
- status — der HTTP-Statuscode, für die grobe Einordnung
- code — das Kürzel, auf das dein Programm reagieren sollte (es bleibt stabil, auch wenn sich der Wortlaut ändert)
- message — die Klartextmeldung, die du einem Benutzer zeigen kannst
- details — nur bei Prüffehlern: welche Felder betroffen sind und warum
2. So ordnest du häufige Fehlercodes ein
| Status | Kürzel | Bedeutung |
| 400 | bad_request | Unbekannter Parameter, ungültiger Vergleich, kaputtes JSON |
| 401 | unauthorized | Kein oder unbekannter Schlüssel |
| 403 | forbidden | Die Stufe des Schlüssels reicht nicht, der Bereich ist nicht freigegeben oder der Schlüssel darf nur lesen |
| 403 | key_expired | Der Schlüssel ist abgelaufen |
| 403 | key_not_yet_valid | Der Schlüssel gilt erst ab einem späteren Datum |
| 403 | ip_not_allowed | Die Absender-Adresse steht nicht in der Freigabeliste |
| 403 | https_required | Der Aufruf kam über unverschlüsseltes HTTP |
| 404 | not_found | Bereich oder Eintrag gibt es nicht |
| 405 | method_not_allowed | Diese Methode ist hier nicht möglich |
| 409 | conflict | Doppelter Wert, es hängen Daten daran, oder eine Fachregel greift (z. B. Zahlung auf einen Entwurf, Überzahlung) |
| 409 | record_locked | Der Eintrag ist gesperrt: festgeschriebene Rechnung, stornierte oder abgerechnete Buchung — die Meldung nennt den Ausweg |
| 410 | gone | Der Eintrag liegt im Papierkorb |
| 412 | precondition_failed | Zwischenzeitlich geändert (If-Match passt nicht mehr) |
| 413 | payload_too_large | Die Anfrage ist größer als 4 MB |
| 415 | unsupported_media_type | Falscher Content-Type — erwartet wird application/json |
| 422 | validation_failed | Prüffehler; details nennt die Felder |
| 429 | rate_limit_exceeded | Zu viele Anfragen je Minute |
| 429 | ip_blocked | Absender nach zu vielen Fehlversuchen gesperrt |
| 500 | internal_error | Interner Fehler; die Meldung enthält ein Kennzeichen für die Nachfrage |
| 503 | service_unavailable | Die Schnittstelle ist abgeschaltet (api.enabled) oder die Instanz läuft im Archivmodus |
| 409 | confirmation_required | Eine Fachaktion braucht eine ausdrückliche Bestätigung; die Meldung nennt den Parameter. |
| 409 | appointment_conflict / duplicate | Ein Assistent-Termin überschneidet sich oder besteht bereits; bei Kunde oder Tier gibt es eine mögliche Dublette. |
3. Die häufigsten Stolperstellen
„401, obwohl der Schlüssel stimmt“
Bei manchen Server-Einstellungen kommt die Kopfzeile Authorization nicht bei PHP an. Benutze dann ersatzweise:
Was macht das? Diese alternative Kopfzeile übergibt denselben Schlüssel ohne Authorization-Kopfzeile.
X-Api-Key: 3f7c9a2e-4b81-4d6f-9a03-7c5e12f8ab44
Das ist gleichwertig.
„403 ip_not_allowed“
Im Schlüssel ist eine IP-Freigabeliste hinterlegt, und dein Server steht nicht darin. Die Fehlerantwort nennt die erkannte Absender-Adresse. Du findest sie auch im Zugriffsprotokoll. Trage diese Adresse in die IP-Freigabeliste ein; solange sie gesperrt ist, funktioniert auch /api/v1/me nicht.
Achtung bei Anschlüssen mit wechselnder Adresse: Dort ist eine feste Freigabeliste unpraktisch. Nimm stattdessen den Bereich des Anbieters, oder verzichte auf die Liste und begrenze über Stufe und Laufzeit.
curl bricht bei Filtern ab
Der Schalter -g fehlt. Ohne ihn hält curl die eckigen Klammern für eine Bereichsangabe:
Was macht das? Dieser Befehl sucht Kontakte nach einem Teil ihres Nachnamens.
curl -g -H "Authorization: Bearer $KEY" "$BASE/contacts?lastname[like]=M%C3%BCl"
„400 Unbekannter Parameter oder Feld“
Ein Feldname stimmt nicht. Die richtigen Namen liefert:
Was macht das? Dieser Aufruf zeigt die Feldbeschreibung des Kontaktbereichs.
GET /api/v1/contacts/_schema
Die Namen sind die technischen Spaltennamen (lastname, nicht „Nachname“). Zu jedem steht die deutsche Bezeichnung dabei.
„409 record_locked“
Der Eintrag ist in einem Endzustand — eine festgeschriebene Rechnung, eine stornierte Buchung, ein abgerechneter Termin. Das ist kein Fehler deines Programms, sondern eine Regel der Software: Solche Einträge werden nicht mehr verändert. Die Meldung sagt dir, was stattdessen geht (Korrekturrechnung über /cancel, Notizfelder, oder die Oberfläche). Welche Bedingung sperrt, steht in /_schema unter meta.locked_when.
„422: … kann nicht geschrieben werden (nur lesbar — setzt die Fachlogik)“
Du versuchst, ein Zustandsfeld zu setzen — finalized, invoicenumber, paid, checkin, sent und ähnliche. Diese Felder vergibt die Software selbst. Für Rechnungen gibt es dafür die Aktionen /close und /cancel, für Zahlungen /cancel; alles andere läuft über die Oberfläche.
„405 … unterstützt kein Ändern“
Manche Bereiche sind absichtlich nur lesbar oder nur anlegbar: Zahlungen werden nie geändert oder gelöscht (nur storniert), E-Mails, Kassenbuch, Kundenkonten und Onlinebuchungen nur gelesen. Was ein Bereich kann, steht in /api/v1/ unter allowed.
„422 beim Anlegen“
Schau in details — dort steht für jedes Feld, was nicht stimmt. Pflichtfelder findest du vorher in /_schema: dort steht bei jedem Feld required: true oder false.
Leere Liste, obwohl Daten da sind
Zwei Möglichkeiten:
- Die Einträge liegen im Papierkorb. Probier
?deleted=include. - Ein Filter greift schärfer als gedacht. Lass ihn versuchsweise weg.
„429 rate_limit_exceeded“
Dein Programm fragt zu schnell. Zwei Wege:
- Auf
Retry-Afterreagieren und so lange warten. Das ist der richtige Weg, und alle Beispielskripte machen es so. - Das Kontingent des Schlüssels erhöhen (System → API-Schlüssel → Firewall → Anfragen je Minute).
Meist lässt sich die Anzahl der Aufrufe aber verkleinern: per_page erhöhen statt viele kleine Seiten zu holen, ?fields= benutzen, und mit ?modified[gte]= nur das Neue abfragen.
„500 internal_error“
Ein Fehler in der Software. Die Meldung enthält ein Kennzeichen wie 9A9CF305 — nenn es bei der Nachfrage, dann lässt sich der Vorgang im Protokoll finden.
4. Das Zugriffsprotokoll
Unter System → API-Schlüssel → Zugriffsprotokoll siehst du, was tatsächlich angekommen ist: Zeitpunkt, Schlüssel, Methode, Pfad, Statuscode, Dauer und Absender-Adresse.

Wenn du eine Fehlersuche machst, stell den betroffenen Schlüssel vorübergehend auf Jeden Aufruf mitschreiben. Danach zurückstellen — sonst wächst das Protokoll unnötig.
5. Was du selbst prüfen kannst
Vier Aufrufe, die die häufigsten Ursachen ausschließen:
Was macht das? Diese Befehle fragen Erreichbarkeit, Schlüsselrechte, Bereiche und Feldbeschreibung ab. Sie ändern keine Fachdaten.
# 1. Ist die Schnittstelle überhaupt erreichbar?
curl -sg -H "Authorization: Bearer $KEY" "$BASE/health"
# 2. Was darf mein Schlüssel, und wie sieht der Server mich?
curl -sg -H "Authorization: Bearer $KEY" "$BASE/me"
# 3. Kommt dieser Bereich in meiner Liste vor?
curl -sg -H "Authorization: Bearer $KEY" "$BASE/" | grep contacts
# 4. Wie heißen die Felder wirklich?
curl -sg -H "Authorization: Bearer $KEY" "$BASE/contacts/_schema"
Der zweite Aufruf beantwortet die meisten Fragen: Stufe, Restlaufzeit, Schreibrecht, erlaubte Bereiche, Tempo-Kontingent und die erkannte Absender-Adresse stehen alle in einer Antwort.
Wenn etwas nicht klappt
- 401 unauthorized: Kopiere den gültigen Schlüssel erneut. Verwende nötigenfalls X-Api-Key als alternative Kopfzeile.
- 403 ip_not_allowed: Übernimm die tatsächliche Absender-Adresse aus Fehlerantwort oder Protokoll in die Freigabeliste.
- 409 record_locked: Der Eintrag ist fachlich gesperrt. Nutze den in der Meldung genannten Weg, etwa eine Rechnungsstornierung.
- 429 rate_limit_exceeded oder ip_blocked: Warte Retry-After ab. Korrigiere zuerst die fehlerhaften Aufrufe, bevor du erneut startest.