Daten lesen: filtern, sortieren, blättern, suchen
Hier liest du Kontakte, Tiere und andere freigegebene Einträge aus PetWorkers. Du lernst, die Auswahl einzugrenzen und größere Listen vollständig abzurufen.
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: Beginne mit einer kleinen Kontaktliste. Wähle nur die benötigten Felder aus. Bei mehreren Seiten rufst du jede Seite einzeln ab.
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 beginnst du mit einer Leseabfrage
- Frage
/api/v1/memit deinem Schlüssel ab. - Prüfe, ob der benötigte Bereich freigegeben ist.
- Rufe die Kontaktliste mit
per_page=5ab. - Kontrolliere
dataundmeta.pagesin der Antwort.
1. Die Antwort hat immer dieselbe Form
Egal welchen Bereich du abfragst — die Hülle ist gleich. Bei Erfolg:
Was macht das? Dieser gekürzte Antwortausschnitt erklärt die Angaben zur Seitennummer und Gesamtzahl. Die eigentlichen Einträge sind hier weggelassen.
{
"data": [],
"meta": { "page": 1, "per_page": 50, "count": 50, "total": 1234, "pages": 25 }
}
Bei einem Fehler:
Was macht das? Diese Fehlerantwort zeigt ein ungültiges Feld und den zugehörigen Grund.
{
"error": {
"status": 422,
"code": "validation_failed",
"message": "Die übergebenen Daten sind ungültig.",
"details": [
{ "field": "email",
"message": "E-Mail-Adresse ist keine gültige E-Mail-Adresse." }
]
}
}
Dein Programm kann also immer gleich prüfen: Steht data drin, hat es geklappt. Steht error drin, nicht.
2. So rufst du eine Liste ab
Was macht das? Dieser Aufruf liest die erste Seite der Kontakte.
GET /api/v1/contacts
Das liefert die ersten 50 Kontakte. Mehr auf einmal geht mit per_page, höchstens 500:
Was macht das? Dieser Aufruf liest die zweite Seite mit höchstens 200 Kontakten.
GET /api/v1/contacts?per_page=200&page=2
In meta.pages steht, wie viele Seiten es insgesamt gibt. Zusätzlich trägt die Antwort die Kopfzeilen X-Total-Count und Link mit den Adressen der ersten, vorherigen, nächsten und letzten Seite.
3. Nur die Felder holen, die du brauchst
Ein Kontakt hat über 140 Felder. Wenn du nur Namen und E-Mail brauchst, sag es:
Was macht das? Dieser Aufruf liest nur Kennung, Nachname, Vorname und E-Mail-Adresse.
GET /api/v1/contacts?fields=id,lastname,firstname,email
Das macht die Antwort um ein Vielfaches kleiner und schneller. Bei großen Beständen lohnt es sich immer.
4. Sortieren
Was macht das? Diese Aufrufe zeigen verschiedene Sortierungen. Das Minus dreht die Reihenfolge um.
GET /api/v1/contacts?sort=lastname
GET /api/v1/contacts?sort=-created (Minus = absteigend)
GET /api/v1/contacts?sort=lastname,-created (mehrere Felder)
Wonach du sortieren kannst, sagt dir /api/v1/contacts/_schema unter sortable.
5. Filtern
Der einfachste Filter ist ein genauer Vergleich:
Was macht das? Dieser Aufruf liest Kontakte mit dem Ort Berlin.
GET /api/v1/contacts?city=Berlin
Für alles andere schreibst du den Vergleich in eckige Klammern:
| Was du willst | So schreibst du es |
| enthält | ?lastname[like]=M%C3%BCl |
| beginnt mit | ?lastname[start]=Sch |
| endet auf | ?email[end]=@example.de |
| größer/gleich | ?created[gte]=2026-01-01 |
| kleiner/gleich | ?created[lte]=2026-12-31 |
| größer | ?id[gt]=100 |
| kleiner | ?id[lt]=100 |
| ungleich | ?city[ne]=Berlin |
| einer von mehreren | ?id[in]=1,2,3 |
| keiner von mehreren | ?id[nin]=4,5 |
| zwischen zwei Werten | ?id[between]=10,20 |
| ist leer | ?email[null]=1 |
| ist gefüllt | ?email[notnull]=1 |
Mehrere Filter werden mit UND verknüpft. Zwei Vergleiche am selben Feld sind erlaubt — so baust du einen Zeitraum:
Was macht das? Dieser Aufruf grenzt Einzeltermine auf den angegebenen Zeitraum ein.
GET /api/v1/coachingappointments
?appointment_date[gte]=2026-09-01
&appointment_date[lte]=2026-09-30
Wichtig bei curl: Der Schalter -g muss dazu. Ohne ihn hält curl die eckigen Klammern für eine Bereichsangabe und bricht ab:
Was macht das? Dieser Terminalbefehl sucht nach einem Teil des Nachnamens.
curl -g -H "Authorization: Bearer <Schlüssel>" \
"https://deine-adresse.de/api/v1/contacts?lastname[like]=M%C3%BCl"
6. Suchen
Wenn du nicht weißt, in welchem Feld etwas steht:
Was macht das? Dieser Aufruf durchsucht die dafür freigegebenen Suchfelder.
GET /api/v1/contacts?q=Müller
Das durchsucht die dafür vorgesehenen Felder des Bereichs. Bei Kontakten sind das Nachname, Vorname, Firma, E-Mail, Kundennummer und Ort. Welche Felder ein Bereich durchsucht, steht in /_schema unter searchable.
7. Verknüpftes gleich mitholen
Statt erst den Kontakt und dann seine Tiere zu holen, geht beides in einem Aufruf:
Was macht das? Dieser Aufruf liest einen Kontakt samt verknüpften Tieren und Rechnungen, soweit erlaubt.
GET /api/v1/contacts/42?include=pets,invoices
Oder als eigene, blätterbare Liste:
Was macht das? Dieser Aufruf liest die Tiere des angegebenen Kontakts.
GET /api/v1/contacts/42/pets
Welche Verknüpfungen es bei einem Bereich gibt, sagt /_schema unter relations.
8. So liest du Einträge aus dem Papierkorb
Die Papierkorb-Parameter gelten nur für Bereiche mit Papierkorb. Andere Bereiche löschen endgültig oder verbieten das Löschen. Lies dafür die Bereichsbeschreibung und die Löschantwort.
In Bereichen mit Papierkorb blendet die Schnittstelle gelöschte Einträge standardmäßig aus:
?deleted=exclude | Papierkorb ausblenden (Vorgabe) |
?deleted=include | Papierkorb mit anzeigen |
?deleted=only | nur den Papierkorb |
Für einen Abgleich mit einem Fremdsystem ist ?deleted=only nützlich: Damit liest du die momentan gelöschten Einträge. Der Parameter allein grenzt keinen Zeitraum ein.
9. So liest du alle Ergebnisseiten
Bei großen Beständen holst du nicht alles auf einmal, sondern blätterst. Das Muster ist immer gleich:
Was macht das? Dieser Ablaufplan zeigt, wie dein Programm alle Ergebnisseiten nacheinander verarbeitet. Er ist keine ausführbare Programmiersprache.
Seite = 1
Wiederhole:
Antwort = GET /api/v1/contacts?page=<Seite>&per_page=200
verarbeite Antwort.data
Wenn Seite >= Antwort.meta.pages: fertig
Seite = Seite + 1
Prüfe bei jedem Beispiel, ob es alle Seiten abruft. Kurze Einzelabfragen liefern nur eine Seite.
10. Nur das Neue holen
Für einen laufenden Abgleich brauchst du nicht jedes Mal alles. Prüfe zuerst im Bereichsschema, ob created und modified als Filter verfügbar sind. Dann kannst du danach filtern:
Was macht das? Dieser Aufruf liest Kontakte ab dem angegebenen Änderungszeitpunkt.
GET /api/v1/contacts?modified[gte]=2026-08-17%2004%3A00%3A00&sort=modified&per_page=200
Merke dir nach jedem Lauf den Zeitpunkt und setze ihn beim nächsten Mal als untere Grenze. So überträgst du nur, was sich wirklich geändert hat.
Wenn etwas nicht klappt
- Es fehlen Kontakte: Die Antwort ist seitenweise. Lies weitere Seiten bis zur letzten Seite.
- 400 bad_request: Ein Feld oder Vergleich ist unbekannt. Rufe die Feldbeschreibung mit /contacts/_schema ab.
- 403 forbidden: Der Schlüssel darf diesen Bereich nicht lesen. Das gilt auch für Pfade wie
/contacts/42/invoices. Prüfe Stufe und Bereichsfreigaben. - Bei
includestehtnull: Die Stufe des Schlüssels reicht für den verknüpften Bereich nicht. Prüfe die Berechtigungsstufe.