Die Schnittstelle im Einzelnen
Jeder Pfad, jedes Feld, jede Fehlerantwort. Stand: 2026-10-31.
Von null bis zum ersten Angebot
Kennung und Geheimnis holt ihr euch in eurem Konto unter „Schnittstelle". Das Token daraus gilt eine Stunde und gehört in jede weitere Anfrage.
# 1. Token holen
curl -X POST https://www.kids-ontour.de/api/v1/anmeldung \
-H 'Content-Type: application/json' \
-d '{"grant_type":"client_credentials","client_id":"kot_live_…","client_secret":"…"}'
# 2. Rubriken ansehen
curl https://www.kids-ontour.de/api/v1/rubriken \
-H 'Authorization: Bearer DAS_TOKEN'
# 3. Ein Angebot anlegen
curl -X POST https://www.kids-ontour.de/api/v1/angebote \
-H 'Authorization: Bearer DAS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"category_id":7,"title":"Ferienhaus an der Schlei",
"excerpt":"Ein Haus für vier bis sechs Personen, zweihundert Meter hinter dem Deich.",
"description":"Zwei Schlafzimmer, Küche, eingezäunter Garten. Fünf Minuten zum Wasser.",
"postal_code":"24376","city":"Kappeln","state":"Schleswig-Holstein",
"age_from":0,"age_to":18,"external_id":"OBJ-4711"}' Die Pfade
Die Pfade sind deutsch wie die Adressen der Seite, die Feldnamen englisch wie die Datenbank. Die Fassung steht im Pfad: was dazukommt, kommt dazu, und was sich ändert, bekommt eine Zwei.
/api/v1/anmeldung ohne Token · 200 Zugangsdaten gegen ein Token
Kennung und Geheimnis herein, ein Token hinaus. Es gilt eine Stunde und trägt die Rechte des Schlüssels.
Mögliche Absagen: 400 , 401 , 429
Beispielantwort
{
"access_token": "a1b2c3d4e5f6a7b8c9.4f3e2d1c0b9a8f7e6d5c4b3a2910ff8877665544332211aabbccddeeff0011",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "lesen schreiben"
} /api/v1/rubriken braucht lesen · 200 Der Katalog
Die Rubriken mit ihren Kennungen und den Merkmalen, die sie führen, dazu die Zielgruppen. Damit niemand eine Kennung rät.
Mögliche Absagen: 401 , 429 , 403
Beispielantwort
{
"rubriken": [
{
"id": 1,
"name": "Ausflugsziele",
"merkmale": [
"is_free",
"is_indoor",
"is_outdoor"
],
"zeitraum": false
},
{
"id": 7,
"name": "Familienurlaub",
"merkmale": [],
"zeitraum": true
}
],
"zielgruppen": [
"kleinkinder",
"kinder",
"teenager",
"schulklassen"
]
} /api/v1/angebote braucht lesen · 200 Die eigenen Angebote
Blätterbar mit „seite“ und „pro_seite“ (höchstens 50), eingrenzbar mit „stand“. Ohne Beschreibung: wer blättert, will die Titel sehen.
Mögliche Absagen: 401 , 429 , 403
Beispielantwort
{
"angebote": [
{
"external_id": "OBJ-4711",
"category_id": 7,
"title": "Ferienhaus an der Schlei",
"is_free": false,
"price_from": 480,
"price_to": null,
"age_from": 0,
"age_to": 18,
"street": "Am Deich 3",
"postal_code": "24376",
"city": "Kappeln",
"state": "Schleswig-Holstein",
"country": "DE",
"phone": "04642 123456",
"email": "urlaub@beispiel.test",
"website": "https://www.beispiel.test",
"facebook_url": "",
"instagram_url": "",
"video_url": "",
"is_year_round": true,
"runs_from": null,
"runs_to": null,
"is_accessible": false,
"dogs_allowed": true,
"is_indoor": false,
"is_outdoor": false,
"id": 12345,
"status": "pending",
"slug": "ferienhaus-an-der-schlei",
"district": "Schleswig-Flensburg",
"latitude": "54.661000",
"longitude": "9.932000",
"completeness": 78,
"paused_at": null,
"terms_accepted_at": "2026-10-31 09:12:00",
"created_at": "2026-10-31 09:12:00",
"updated_at": "2026-10-31 09:12:00",
"url": null
}
],
"gesamt": 41,
"seite": 1,
"pro_seite": 20,
"seiten": 3
} /api/v1/angebote braucht schreiben · 201 Ein neues Angebot
Legt an und antwortet mit 201 und der Adresse des Angebots. Es steht danach in der Prüfung, nie direkt online.
Mögliche Absagen: 401 , 429 , 415 , 402 , 422 , 403
Beispielantwort
{
"angebot": {
"external_id": "OBJ-4711",
"category_id": 7,
"title": "Ferienhaus an der Schlei",
"excerpt": "Ein Haus für vier bis sechs Personen, zweihundert Meter hinter dem Deich.",
"description": "<p>Das Haus hat zwei Schlafzimmer, eine Küche und einen eingezäunten Garten.</p>",
"is_free": false,
"price_from": 480,
"price_to": null,
"price_info": "Pro Woche, Nebensaison ab 380 Euro.",
"age_from": 0,
"age_to": 18,
"street": "Am Deich 3",
"postal_code": "24376",
"city": "Kappeln",
"state": "Schleswig-Holstein",
"country": "DE",
"phone": "04642 123456",
"email": "urlaub@beispiel.test",
"website": "https://www.beispiel.test",
"facebook_url": "",
"instagram_url": "",
"video_url": "",
"opening_hours_text": "",
"is_year_round": true,
"runs_from": null,
"runs_to": null,
"is_accessible": false,
"dogs_allowed": true,
"is_indoor": false,
"is_outdoor": false,
"id": 12345,
"status": "pending",
"slug": "ferienhaus-an-der-schlei",
"district": "Schleswig-Flensburg",
"latitude": "54.661000",
"longitude": "9.932000",
"completeness": 78,
"paused_at": null,
"terms_accepted_at": "2026-10-31 09:12:00",
"created_at": "2026-10-31 09:12:00",
"updated_at": "2026-10-31 09:12:00",
"url": null,
"schlagwoerter": [
"Ferienhaus",
"Ostsee"
],
"zielgruppen": [
"kinder",
"teenager"
],
"bilder": []
},
"sofort_frei": false
} /api/v1/angebote/{id} braucht lesen · 200 Ein Angebot
Mit allem, was dazugehört: Bilder, Schlagwörter, Zielgruppen, Stand.
Mögliche Absagen: 401 , 429 , 404 , 403
Beispielantwort
{
"angebot": {
"external_id": "OBJ-4711",
"category_id": 7,
"title": "Ferienhaus an der Schlei",
"excerpt": "Ein Haus für vier bis sechs Personen, zweihundert Meter hinter dem Deich.",
"description": "<p>Das Haus hat zwei Schlafzimmer, eine Küche und einen eingezäunten Garten.</p>",
"is_free": false,
"price_from": 480,
"price_to": null,
"price_info": "Pro Woche, Nebensaison ab 380 Euro.",
"age_from": 0,
"age_to": 18,
"street": "Am Deich 3",
"postal_code": "24376",
"city": "Kappeln",
"state": "Schleswig-Holstein",
"country": "DE",
"phone": "04642 123456",
"email": "urlaub@beispiel.test",
"website": "https://www.beispiel.test",
"facebook_url": "",
"instagram_url": "",
"video_url": "",
"opening_hours_text": "",
"is_year_round": true,
"runs_from": null,
"runs_to": null,
"is_accessible": false,
"dogs_allowed": true,
"is_indoor": false,
"is_outdoor": false,
"id": 12345,
"status": "pending",
"slug": "ferienhaus-an-der-schlei",
"district": "Schleswig-Flensburg",
"latitude": "54.661000",
"longitude": "9.932000",
"completeness": 78,
"paused_at": null,
"terms_accepted_at": "2026-10-31 09:12:00",
"created_at": "2026-10-31 09:12:00",
"updated_at": "2026-10-31 09:12:00",
"url": null,
"schlagwoerter": [
"Ferienhaus",
"Ostsee"
],
"zielgruppen": [
"kinder",
"teenager"
],
"bilder": []
},
"sofort_frei": false
} /api/v1/angebote/{id} braucht schreiben · 200 Eine Teiländerung
Nur die Felder, die dabeistehen; alles andere bleibt. Ein Feld ausdrücklich auf leer zu setzen geht, solange es kein Pflichtfeld ist.
Mögliche Absagen: 401 , 429 , 415 , 404 , 422 , 403 , 409
Beispielantwort
{
"angebot": {
"external_id": "OBJ-4711",
"category_id": 7,
"title": "Ferienhaus an der Schlei",
"excerpt": "Ein Haus für vier bis sechs Personen, zweihundert Meter hinter dem Deich.",
"description": "<p>Das Haus hat zwei Schlafzimmer, eine Küche und einen eingezäunten Garten.</p>",
"is_free": false,
"price_from": 480,
"price_to": null,
"price_info": "Pro Woche, Nebensaison ab 380 Euro.",
"age_from": 0,
"age_to": 18,
"street": "Am Deich 3",
"postal_code": "24376",
"city": "Kappeln",
"state": "Schleswig-Holstein",
"country": "DE",
"phone": "04642 123456",
"email": "urlaub@beispiel.test",
"website": "https://www.beispiel.test",
"facebook_url": "",
"instagram_url": "",
"video_url": "",
"opening_hours_text": "",
"is_year_round": true,
"runs_from": null,
"runs_to": null,
"is_accessible": false,
"dogs_allowed": true,
"is_indoor": false,
"is_outdoor": false,
"id": 12345,
"status": "pending",
"slug": "ferienhaus-an-der-schlei",
"district": "Schleswig-Flensburg",
"latitude": "54.661000",
"longitude": "9.932000",
"completeness": 78,
"paused_at": null,
"terms_accepted_at": "2026-10-31 09:12:00",
"created_at": "2026-10-31 09:12:00",
"updated_at": "2026-10-31 09:12:00",
"url": null,
"schlagwoerter": [
"Ferienhaus",
"Ostsee"
],
"zielgruppen": [
"kinder",
"teenager"
],
"bilder": []
},
"sofort_frei": false
} /api/v1/angebote/{id} braucht loeschen · 204 Zurückziehen
Das Angebot geht aus Listen, Karte und Suche heraus und bleibt zurückzuholen. Endgültig gelöscht wird über die Schnittstelle nichts.
/api/v1/angebote/extern/{kennung} braucht schreiben · 201 Anlegen oder ersetzen
Unter eurer eigenen Objektnummer. Zweimal geschickt heißt einmal angelegt: 201 beim ersten Mal, danach 200.
Mögliche Absagen: 401 , 429 , 415 , 404 , 402 , 422 , 403 , 409
Beispielantwort
{
"angebot": {
"external_id": "OBJ-4711",
"category_id": 7,
"title": "Ferienhaus an der Schlei",
"excerpt": "Ein Haus für vier bis sechs Personen, zweihundert Meter hinter dem Deich.",
"description": "<p>Das Haus hat zwei Schlafzimmer, eine Küche und einen eingezäunten Garten.</p>",
"is_free": false,
"price_from": 480,
"price_to": null,
"price_info": "Pro Woche, Nebensaison ab 380 Euro.",
"age_from": 0,
"age_to": 18,
"street": "Am Deich 3",
"postal_code": "24376",
"city": "Kappeln",
"state": "Schleswig-Holstein",
"country": "DE",
"phone": "04642 123456",
"email": "urlaub@beispiel.test",
"website": "https://www.beispiel.test",
"facebook_url": "",
"instagram_url": "",
"video_url": "",
"opening_hours_text": "",
"is_year_round": true,
"runs_from": null,
"runs_to": null,
"is_accessible": false,
"dogs_allowed": true,
"is_indoor": false,
"is_outdoor": false,
"id": 12345,
"status": "pending",
"slug": "ferienhaus-an-der-schlei",
"district": "Schleswig-Flensburg",
"latitude": "54.661000",
"longitude": "9.932000",
"completeness": 78,
"paused_at": null,
"terms_accepted_at": "2026-10-31 09:12:00",
"created_at": "2026-10-31 09:12:00",
"updated_at": "2026-10-31 09:12:00",
"url": null,
"schlagwoerter": [
"Ferienhaus",
"Ostsee"
],
"zielgruppen": [
"kinder",
"teenager"
],
"bilder": []
},
"sofort_frei": false
} /api/v1/angebote/{id}/bilder braucht lesen · 200 Die Bilder eines Angebots
Mit drei Breiten je Bild, damit niemand Ordnernamen zusammensetzen muss.
Mögliche Absagen: 401 , 429 , 404 , 403
Beispielantwort
{
"bilder": [
{
"id": 90210,
"copyright": "Foto: Ferienhof Beispiel",
"alt_text": "",
"rights_confirmed_at": "2026-10-31 09:12:00",
"klein": "https://www.kids-ontour.de/bilder/angebote/breit400/a1b2c3.jpg",
"mittel": "https://www.kids-ontour.de/bilder/angebote/breit800/a1b2c3.jpg",
"gross": "https://www.kids-ontour.de/bilder/angebote/breit1600/a1b2c3.jpg"
}
]
} /api/v1/angebote/{id}/bilder braucht schreiben · 201 Ein Bild hochladen
Als „multipart/form-data“ mit „bild“, „copyright“ und „rechte=1“, ein Bild je Anfrage. Ohne Nachweis und ohne Bestätigung der Rechte kein Bild.
Mögliche Absagen: 401 , 429 , 415 , 404 , 402 , 422 , 403
Beispielantwort
{
"bilder": [
{
"id": 90210,
"copyright": "Foto: Ferienhof Beispiel",
"alt_text": "",
"rights_confirmed_at": "2026-10-31 09:12:00",
"klein": "https://www.kids-ontour.de/bilder/angebote/breit400/a1b2c3.jpg",
"mittel": "https://www.kids-ontour.de/bilder/angebote/breit800/a1b2c3.jpg",
"gross": "https://www.kids-ontour.de/bilder/angebote/breit1600/a1b2c3.jpg"
}
]
} /api/v1/angebote/{id}/bilder/{bild} braucht loeschen · 204 Ein Bild wegnehmen
Die Datei geht mit, auch die gerechneten Größen.
/api/v1/angebote/{id}/schlagwoerter braucht schreiben · 200 Die Schlagwörter setzen
Die ganze Liste auf einmal, höchstens acht. Was es noch nicht gibt, entsteht und wartet auf die Freigabe der Redaktion.
Mögliche Absagen: 401 , 429 , 415 , 404 , 422 , 403
Beispielantwort
{
"schlagwoerter": [
"Ferienhaus",
"Ostsee"
],
"zielgruppen": [
"kinder",
"teenager"
]
} /api/v1/angebote/{id}/zielgruppen braucht schreiben · 200 Die Zielgruppen setzen
Ebenfalls die ganze Liste. Kleinkinder, Kinder und Teenager folgen sonst aus dem Alter; die Schulklassen sind die eine, die das nicht tut.
Mögliche Absagen: 401 , 429 , 415 , 404 , 422 , 403
Beispielantwort
{
"schlagwoerter": [
"Ferienhaus",
"Ostsee"
],
"zielgruppen": [
"kinder",
"teenager"
]
} Die Felder
Was hier nicht steht, wird übergangen, auch wenn ihr es schickt. Die Längen sind die der Prüfung; ein Zeichen darüber, und die Zeile fällt durch.
| Feld | Typ | Von bis | Pflicht | Was hineingehört |
|---|---|---|---|---|
external_id | string | 1 bis 120 | nein | Eure eigene Objektnummer. Eindeutig je Konto, und der Schlüssel für „PUT /angebote/extern/{kennung}“. |
category_id | integer | ab 1 | ja | Die Rubrik. Die Kennungen stehen unter „/api/v1/rubriken“. |
title | string | 5 bis 180 | ja | Der Name des Angebots, so wie Familien ihn lesen. |
excerpt | string | 20 bis 400 | ja | Ein Anriss für die Kachel in der Liste. Reiner Text. |
description | string | 50 bis 20000 | ja | Die Beschreibung. Einfaches HTML ist erlaubt und läuft durch unseren Filter; was er nicht kennt, fällt weg. |
is_free | boolean | nein | Eintritt frei. Setzt ihn, bleiben Preis und Preishinweis leer, auch wenn ihr sie schickt. | |
price_from | integer | 0 bis 99999 | nein | Der Preis ab, in ganzen Euro. |
price_to | integer | 0 bis 99999 | nein | Der obere Preis. Er darf nicht unter dem unteren liegen. |
price_info | string | bis 2000 | nein | Alles zum Preis, was keine Zahl ist: Saisontabelle, Gruppenpreise, was im Preis steckt. |
age_from | integer | 0 bis 18 | ja | Ab welchem Alter es passt. Auch für ein Ferienhaus Pflicht; dann nehmt 0. |
age_to | integer | 0 bis 18 | ja | Bis zu welchem Alter. Aus beiden entstehen die Zielgruppen. |
street | string | bis 160 | nein | Straße und Hausnummer. |
postal_code | string | 5 | ja | Im Inland fünf Ziffern, und es muss sie geben: an ihr hängen Koordinate, Landkreis und Bundesland. Im Ausland 2 bis 12 Zeichen. |
city | string | 2 bis 120 | ja | Der Ort. |
state | auswahl | ja | Eines der sechzehn Bundesländer, ausgeschrieben, oder „no_bdland“ für das Ausland. Zur Wahl: Baden-Württemberg, Bayern, Berlin, Brandenburg, Bremen, Hamburg, Hessen, Mecklenburg-Vorpommern, Niedersachsen, Nordrhein-Westfalen, Rheinland-Pfalz, Saarland, Sachsen, Sachsen-Anhalt, Schleswig-Holstein, Thüringen, no_bdland | |
country | auswahl | nein | Nur mit „state=no_bdland“, und dann Pflicht. Zwei Buchstaben nach ISO 3166. Deutschland steht nicht zur Wahl: wer es meint, nimmt ein Bundesland. Zur Wahl: AL, AD, AU, BE, BA, BG, DK, EE, FI, FR, GR, IE, IS, IT, CA, HR, LV, LI, LT, LU, MT, MD, MC, ME, NL, NZ, MK, NO, AT, PL, PT, RO, SM, SE, CH, RS, SK, SI, ES, ZA, CZ, TR, HU, US, GB, CY | |
phone | string | bis 60 | nein | Die Telefonnummer für Familien. |
email | string | bis 190 | nein | Die Adresse, an die Anfragen gehen. Wir speichern keine Anfrage, wir leiten sie weiter. |
website | string | bis 255 | nein | Eure Webseite, mit oder ohne „https://“. |
facebook_url | string | bis 255 | nein | Die Facebook-Seite. |
instagram_url | string | bis 255 | nein | Die Instagram-Seite. |
video_url | string | bis 255 | nein | Ein YouTube-Verweis, wie er in der Adresszeile steht. Gehört zu Premium. |
opening_hours_text | string | bis 2000 | nein | Die Öffnungszeiten als Text. |
is_year_round | boolean | nein | Ganzjährig geöffnet. | |
runs_from | datum | nein | Beginn des Zeitraums, „JJJJ-MM-TT“. Für Camps und Ferienangebote. | |
runs_to | datum | nein | Ende des Zeitraums. Nach Ablauf nimmt die Wartung das Angebot heraus. | |
is_accessible | boolean | nein | Barrierefrei. | |
dogs_allowed | boolean | nein | Hunde erlaubt. | |
is_indoor | boolean | nein | Drinnen. Nur in Rubriken, die das Merkmal führen; sonst fällt der Haken weg. | |
is_outdoor | boolean | nein | Draußen, mit derselben Regel. | |
schlagwoerter | string | bis 400 | nein | Als Text, durch Kommas getrennt, höchstens acht. Eigener Weg: „PUT /angebote/{id}/schlagwoerter“. |
Was nur herauskommt
Diese Felder setzt das Portal selbst. Sie stehen in jeder Antwort und lassen sich nicht schreiben.
| Feld | Was darin steht |
|---|---|
id | Unsere Kennung des Angebots. |
status | draft, pending, published, rejected, expired oder archived. |
slug | Der Adressteil, den wir aus dem Titel bilden. |
district | Der Landkreis, aus der Postleitzahl. |
latitude | Breitengrad, aus der Anschrift gerechnet. |
longitude | Längengrad. |
completeness | Wie vollständig der Eintrag ist, 0 bis 100. |
paused_at | Gesetzt, solange das Angebot pausiert. |
terms_accepted_at | Wann die Bedingungen für dieses Angebot galten. |
created_at | Angelegt am. |
updated_at | Zuletzt geändert am. |
url | Die Adresse im Portal, sobald das Angebot online steht, sonst null. |
Die Fehler
Alle nach RFC 9457, als application/problem+json. Bei einer Prüfung steht in fields eine Meldung je Feld, und zwar dieselbe, die im Formular darunter stünde.
| Stand | Typ | Wann sie kommt |
|---|---|---|
| 400 | format | Der Rumpf war kein JSON, oder eine Angabe fehlt, die kein Feld ist. |
| 415 | inhaltstyp | Beim Schreiben fehlte `Content-Type: application/json`. |
| 401 | anmeldung | Kein Token, falsches Token, abgelaufen, widerrufen, oder von einer Adresse, die nicht in der Liste steht. |
premium | Das elfte Angebot ohne Premium, oder ein Bild über der Zahl, die zum Konto gehört. | |
| 403 | rechte | Der Schlüssel trägt dieses Recht nicht. Welche er hat, steht in der Antwort. |
| 404 | nicht-gefunden | Dieses Angebot, dieses Bild oder diesen Pfad gibt es in diesem Konto nicht. |
| 405 | verfahren | Den Pfad gibt es, aber nicht mit diesem Verfahren. |
| 409 | zurueckgezogen | Das Angebot ist zurückgezogen. Es nimmt erst wieder etwas an, wenn jemand es im Konto zurückholt. |
| 422 | pruefung | Ein Feld oder mehrere fallen durch. Welche, steht in `fields`, eine Meldung je Feld. |
| 429 | bremse | Zu viele Anfragen. `Retry-After` sagt, wann es weitergeht. |
| 500 | server | Bei uns ist etwas schiefgegangen. Versucht es noch einmal; bleibt es dabei, schreibt uns. |
{
"type": "https://www.kids-ontour.de/api/doku.html#fehler-pruefung",
"title": "Die Angaben stimmen so nicht.",
"status": 422,
"detail": "2 Felder stimmen nicht.",
"fields": {
"title": "Bitte gebt einen Titel an.",
"age_from": "Bitte gebt das Alter, ab dem es passt, an."
}
} Die Grenzen
Über der Bremse antwortet die Schnittstelle mit 429 und sagt in Retry-After, wann es weitergeht.
| Was | Wie viel |
|---|---|
| Anfragen je Stunde und Schlüssel | 600 |
| davon schreibende | 60 |
| Laufzeit eines Tokens | 60 Minuten |
| Angebote ohne Premium | 10 |
| Bilder je Angebot | 8, mit Premium 15 |
| Schlagwörter je Angebot | 8 |
| Größe des JSON-Rumpfes | 2 MB |
| Zeilen je Seite der Liste | höchstens 50 |
Die Beschreibung als Datei
Wer einen Erzeuger benutzt, nimmt sie von hier und tippt nichts ab.
Stand der Beschreibung: 2026-10-31