Anmeldung & Modi
Jede Anfrage braucht deinen Schlüssel im Kopf Authorization: Bearer …. Schlüssel vergeben wir nach einem kurzen Gespräch – es gibt keine Selbstregistrierung.
Echte Räder und Preise, Buchungen nur simuliert: Der Link führt auf eine Testseite, es gibt keine Zahlung und keine Nachricht an den Vermieter.
Echte Buchungen über die ListNRide-Kasse.
curl "https://api.listnride.com/v1/rides?lat=52.52&lng=13.40" \
-H "Authorization: Bearer lnr_test_…"Ablauf einer Buchung
Du brauchst keine eigene Kasse: der Kunde bucht und bezahlt bei uns und landet danach wieder auf deiner Seite.
Räder finden
GET /v1/ridesnach Ort, Zeitraum und Kategorie.Kassensitzung anlegen
POST /v1/checkout/sessions– du bekommst Preis und Link.Kunden weiterleiten
Buchen und Bezahlen in der ListNRide-Kasse, dann zurück zu dir.
Status erhalten
Per Benachrichtigung oder
GET /v1/bookings/{id}.
Endpunkte
Räder in der Nähe eines Ortes oder eines Vermieters. Mit Zeitraum zeigt availability.units_available die freien Einheiten.
| Parameter | Bedeutung |
|---|---|
| lat, lng | Mittelpunkt der Suche (oder lister) |
| radius_km | 0,1–100, Standard 15 |
| from, to | Zeitraum, ISO-Datum oder -Zeitpunkt |
| quantity | Anzahl gleicher Räder, Standard 1 |
| category | z. B. e-bike,cargo-bike |
| sort | recommended · distance · price_asc · price_desc · rating |
| limit, cursor | Blättern, höchstens 100 je Seite |
{
"object": "list",
"data": [{
"id": "ride_oEbNgLPApUJf52PkgHU49A",
"name": "KRZBERG – Single Speed",
"category": { "id": "single-speed" },
"price": { "currency": "EUR", "per_day": 2500 },
"lister": { "id": "lis_VTknvPc20LBQbXE9p7dt6A" },
"instant_booking": true,
"distance_km": 1.46
}],
"has_more": true, "next_cursor": "eyJvIjoyMH0"
}Ein Rad mit Beschreibung, allen Bildern, Ausstattung, Kaution und Versicherung.
Alle Kategorien mit deutschem und englischem Namen. Eine Oberkategorie wie e-bike schließt bei der Suche ihre Unterkategorien ein.
Legt eine Kassensitzung an. Preis und Verfügbarkeit prüft dabei die ListNRide-Kasse. Der Link ist 24 Stunden gültig.
| Feld | Bedeutung |
|---|---|
| ride * | Rad-ID ride_… |
| from, to * | Abhol- und Rückgabetag, YYYY-MM-DD |
| pickup_time, return_time | HH:MM, Standard 10:00 / 17:00 |
| quantity | Anzahl, 1–50, Standard 1 |
| return_url * | Hierhin kommt der Kunde nach der Buchung zurück (https), mit checkout_session, booking und status=success |
| cancel_url | Optional, für den Abbruch (https) |
| locale | de · en · fr · es · it · nl |
| client_reference | Deine eigene Nummer |
curl -X POST https://api.listnride.com/v1/checkout/sessions \
-H "Authorization: Bearer lnr_test_…" \
-H "Content-Type: application/json" \
-d '{
"ride": "ride_jK6nvpDczET3Adx8AKKn1w",
"from": "2026-11-17", "to": "2026-11-18",
"return_url": "https://deine-seite.de/danke",
"locale": "de"
}'
# → { "id": "cs_O8t1…", "amount_total": 7800,
# "url": "https://www.listnride.de/api/go/p/BHTm…" }Status der Sitzung: open, booked (mit booking-ID) oder expired.
| status | Bedeutung |
|---|---|
| awaiting_payment | Kunde ist in der Kasse, noch nicht bezahlt |
| requested | Bezahlt bzw. vorgemerkt, Vermieter muss zusagen |
| accepted | Vermieter hat zugesagt, Zahlung läuft |
| confirmed | Fest gebucht |
| completed | Miete abgeschlossen |
| canceled_by_lister · canceled_by_customer · canceled | Storniert |
| expired | Nicht bezahlt oder nicht rechtzeitig angenommen |
Benachrichtigungen
Ändert sich der Status einer Buchung, schicken wir ein POST an deine hinterlegte Adresse, z. B. booking.confirmed. Antworte mit 2xx – sonst versuchen wir es nach 1 Min., 5 Min., 30 Min. und bis zu 24 Std. erneut. Mit ping kannst du die Verbindung testen; die Ereignis-id bleibt bei Wiederholungen gleich.
Prüfe jede Nachricht mit der Kopfzeile LNR-Signature: t=…,v1=…: HMAC-SHA256 über t + "." + body mit deinem Geheimnis whsec_…. Weise Nachrichten ab, deren t älter als 5 Minuten ist.
const crypto = require("crypto");
function echt(rawBody, header, secret) {
const p = Object.fromEntries(header.split(",").map(x => x.split("=")));
if (Math.abs(Date.now() / 1000 - Number(p.t)) > 300) return false;
const soll = crypto.createHmac("sha256", secret)
.update(`${p.t}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(soll), Buffer.from(p.v1));
}Fehler & Limits
Fehler haben immer dieselbe Form. Mit der request_id finden wir deinen Fall schnell.
| HTTP | code |
|---|---|
| 400 | parameter_missing, parameter_invalid, outside_opening_hours, duration_too_short, duration_too_long |
| 401 | missing_api_key, invalid_api_key |
| 403 | missing_scope |
| 404 | resource_missing, route_not_found |
| 409 | ride_unavailable |
| 429 | rate_limited, too_many_failed_attempts – X-RateLimit-* und Retry-After |
{ "error": {
"type": "invalid_request_error",
"code": "ride_unavailable",
"message": "The ride is not available for this period and quantity.",
"param": "ride",
"request_id": "req_UqrIw8P5wzwT" } }Versionen
Die Version steht im Pfad. Innerhalb von /v1 kommen nur Felder dazu – nichts wird entfernt oder umbenannt. Größere Änderungen erscheinen als /v2, und /v1 läuft mindestens 12 Monate weiter. Die maschinenlesbare Beschreibung (OpenAPI 3.1) liegt unter /openapi.json bzw. https://api.listnride.com/v1/openapi.json.
Zugang anfragen
Schreib uns mit deiner Website und was du vorhast. Du bekommst zuerst einen Testschlüssel – live geht es nach einem kurzen Gespräch.
partner@listnride.com