ListNRideDevelopers
Primi passi

Autenticazione e modalità

Ogni richiesta richiede la tua chiave nell’intestazione Authorization: Bearer …. Assegniamo le chiavi dopo un breve colloquio – non è prevista la registrazione autonoma.

URL di base
https://api.listnride.com/v1
lnr_test_…

Bici e prezzi reali, prenotazioni simulate: il link apre una pagina di test, nessuno paga e il noleggiatore non viene avvisato.

lnr_live_…

Prenotazioni reali tramite il checkout di ListNRide.

Le chiavi restano sul tuo server. Non inserirle mai in un browser o in un’app – chi ha la tua chiave può prenotare a tuo nome.
curl
curl "https://api.listnride.com/v1/rides?lat=52.52&lng=13.40" \
  -H "Authorization: Bearer lnr_test_…"
Primi passi

Come funziona una prenotazione

Non ti serve un checkout tuo: il cliente prenota e paga da noi e poi torna sul tuo sito.

  1. Trovare le bici

    GET /v1/rides per luogo, periodo e categoria.

  2. Creare una sessione di checkout

    POST /v1/checkout/sessions – ricevi prezzo e link.

  3. Reindirizzare il cliente

    Prenotazione e pagamento nel checkout di ListNRide, poi ritorno da te.

  4. Ricevere lo stato

    Tramite webhook o con GET /v1/bookings/{id}.

Primi passi

La modalità test passo dopo passo

Con una chiave di test tutto funziona come dal vivo – solo che nessuno paga e nessun noleggiatore viene coinvolto. Prova l’intero percorso una volta prima di andare live.

  1. Creare una sessione

    POST /v1/checkout/sessions con lnr_test_…. Prezzi e disponibilità sono reali.

  2. Aprire il link

    L’url apre una pagina di test invece del checkout. Scegli «Complete test booking».

  3. Verificare il ritorno

    Il cliente arriva sulla tua return_url con booking=bkg_test_… e status=success.

  4. Verificare il webhook

    Se è impostato un URL webhook, booking.confirmed con "mode": "test" arriva entro un minuto.

Riferimento

Endpoint

GET/v1/ridesrides:read

Bici vicino a un luogo o di un noleggiatore. Con un periodo, availability.units_available indica le unità libere.

ParametroDescrizione
lat, lngCentro della ricerca (oppure lister)
radius_km0,1–100, predefinito 15
bboxArea della mappa minLng,minLat,maxLng,maxLat invece di lat/lng
from, toPeriodo, data o data-ora ISO
quantityNumero di bici uguali, predefinito 1
categoryad es. e-bike,cargo-bike
price_min
price_max
Prezzo al giorno in centesimi, commissione di servizio e assicurazione base incluse
rider_heightAltezza del ciclista in cm (150–210) – trova bici della misura giusta e unisize
frame_size
brand
Misura del telaio o marca esatta, ad es. M o Gazelle
accessoriesDotazione inclusa, deve esserci tutto: helmet,lock,lights,basket,childseat,trailer,gps,repair_kit
instant_booking
top_booked
true: solo conferma immediata / solo le più prenotate
min_rating
lister_type
type
Valutazione minima, business o private, bike o accessory
sortrecommended · distance · price_asc · price_desc · rating · popular
limit, cursorPaginazione, al massimo 100 per pagina
Risposta (abbreviata)
{
  "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"
}
GET/v1/rides/{id}rides:read

Una bici con descrizione, tutte le foto, dotazione, cauzione e assicurazione.

In più tutto ciò che serve a una pagina prodotto: prezzi totali da 1 a 28 giorni, altezza del ciclista, regole di prenotazione, orari, condizioni di cancellazione ed extra prenotabili con zone di consegna.

Risposta (abbreviata)
{
  "price": { "per_day": 2500, "tiers": [
    { "days": 1, "total": 2500 },
    { "days": 7, "total": 15599, "discount": 1400 } ] },
  "size": { "rider_height": { "range": "175-185" } },
  "booking_rules": { "min_days": 1, "time_slot_minutes": 30 },
  "opening_hours": { "monday": ["09:00-18:00"], … },
  "cancellation_policy": { "by_customer": [
    { "hours_before_pickup_min": 72, "refund_percent_of_rental": 100 }, … ] },
  "extras": [{ "code": "insurance_plus" }, { "code": "delivery" }]
}
GET/v1/rides/{id}/availabilityrides:read

Unità libere per giorno e fasce di ritiro e riconsegna in ora locale, fino a 92 giorni per richiesta. Giorni di chiusura e orari sono già considerati – ideale per il tuo selettore di date. La verifica vincolante avviene con POST /v1/quotes e nel checkout.

Risposta (abbreviata)
{
  "object": "availability",
  "units_total": 4,
  "days": [{
    "date": "2026-11-17",
    "units_available": 3,
    "closed": false,
    "pickup_windows": ["09:00-18:00"],
    "return_windows": ["09:00-18:00"]
  }, …]
}
GET/v1/rides/{id}/reviewsrides:read

Recensioni verificate di una bici, prima le più recenti, con media e numero totale. Gli autori compaiono con nome e iniziale. Tutte le recensioni di un noleggiatore: GET /v1/listers/{id}/reviews.

GET/v1/listers/{id}rides:read

Profilo pubblico di un noleggiatore: nome, località, valutazione, prenotazioni concluse, numero di bici, conferma immediata, regole di prenotazione, orari e zone di consegna. I privati compaiono con il nome e senza via.

GET/v1/cancellation-policyrides:read

Le condizioni di cancellazione valide per ogni prenotazione: da 72 ore prima del ritiro viene rimborsato tutto, sotto una quota del noleggio in base alla fascia. Se cancella il noleggiatore, il cliente riceve tutto indietro.

GET/v1/categoriesrides:read

Tutte le categorie con nome tedesco e inglese. Una categoria principale come e-bike include le sue sottocategorie nella ricerca.

GET/v1/placesrides:read

Tutte le località con bici prenotabili, prima quelle con più bici. Con q cerchi in tutte le lingue (ad es. q=monaco), con country filtri per paese e locale sceglie la lingua dei nomi. Singola località: GET /v1/places/{id}.

GET/v1/classesrides:read

Invece di una bici precisa, il tuo cliente prenota una classe – ad es. «E-bike, fascia media» a Berlino – e ListNRide trova un noleggiatore adatto. Interroga con place o lat/lng. Si prenota con una sessione di checkout con class e size (altezza del ciclista).

Risposta (abbreviata)
{
  "id": "berlin.e-bike.mid",
  "object": "class",
  "category": { "id": "e-bike" },
  "tier": { "id": "mid" },
  "price": { "currency": "EUR", "per_day": 3900 },
  "sizes": ["150-165", "165-175", "175-185", "185-205", "Unisize"],
  "listers_nearby": 12
}
POST/v1/quotesrides:read

Calcola il prezzo esatto come il checkout di ListNRide: noleggio, sconto, commissione di servizio, assicurazione base, extra (insurance_plus) e consegna a un indirizzo, senza prenotare nulla. Un preventivo comprende bici di un solo noleggiatore o una classe.

curl
curl -X POST https://api.listnride.com/v1/quotes \
  -H "Authorization: Bearer lnr_test_…" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "2026-11-17", "to": "2026-11-19",
    "items": [{ "ride": "ride_jK6n…", "quantity": 2,
                "extras": ["insurance_plus"] }],
    "delivery_address": "Torstraße 1, 10119 Berlin"
  }'

# → "amounts": { "rental": 6000, "service_fee": 1100,
#   "insurance_plus": 900, "delivery": 1500, "total": 9600 }
POST/v1/checkout/sessionsbookings:write

Crea una sessione di checkout. Il checkout di ListNRide verifica prezzo e disponibilità. Il link è valido 24 ore; quantità e orari sono preselezionati nel checkout.

CampoDescrizione
ride *ID della bici ride_…
class, sizeInvece di ride: una classe da GET /v1/classes e l’altezza del ciclista (165-175 … o Unisize)
from, to *Giorno di ritiro e di riconsegna, YYYY-MM-DD
pickup_time, return_timeHH:MM, predefinito 10:00 / 17:00
quantityQuantità, 1–50, predefinita 1
return_url *Dove torna il cliente dopo la prenotazione (https), con checkout_session, booking e status=success
cancel_urlFacoltativo, in caso di annullamento (https)
localede · en · fr · es · it · nl
client_referenceIl tuo riferimento
curl
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",
    "pickup_time": "09:00", "return_time": "17:00",
    "return_url": "https://tuo-sito.it/grazie",
    "locale": "it"
  }'

# → { "id": "cs_O8t1…", "amount_total": 7800,
#     "url": "https://www.listnride.it/api/go/p/BHTm…" }
GET/v1/checkout/sessions/{id}bookings:read

Stato della sessione: open, booked (con ID booking) o expired.

GET/v1/bookings/{id}bookings:read
statusDescrizione
awaiting_paymentIl cliente è nel checkout, non ha ancora pagato
requestedPagata o riservata, in attesa di conferma del noleggiatore
acceptedAccettata dal noleggiatore, pagamento in corso
confirmedConfermata
completedNoleggio concluso
canceled_by_lister · canceled_by_customer · canceledAnnullata
expiredNon pagata o non accettata in tempo
GET/v1/bookingsbookings:read

Tutte le prenotazioni delle tue sessioni di checkout, prima le più recenti. Filtra per status o per la tua client_reference. Una chiave di test elenca le prenotazioni di test, una chiave live quelle reali. Le prenotazioni annullate contengono cancellation con importo e stato del rimborso.

POST/v1/bookings/{id}/cancelbookings:cancel

Annulla una prenotazione per conto del tuo cliente – con le stesse regole di listnride.com: da 72 ore prima del ritiro viene rimborsato tutto, sotto una quota del noleggio. Il noleggiatore viene avvisato, ricevi booking.canceled_by_customer e il rimborso torna sul metodo di pagamento del cliente.

Verifica prima con GET /v1/bookings/{id}/cancellation: mostra se l’annullamento è possibile e il rimborso esatto, senza modificare nulla. Annullare richiede lo scope bookings:cancel, che attiviamo su richiesta. Facoltativi: reason (changed_mind, found_better, timing_issue, price_too_high, personal_reasons, other) e comment.

curl
# 1. Anteprima: si può annullare e quanto riceve indietro il cliente?
curl https://api.listnride.com/v1/bookings/bkg_gr9z…/cancellation \
  -H "Authorization: Bearer lnr_live_…"
# → "cancelable": true, "refund": { "amount": 7300 },
#   "breakdown": { "rental_refunded_percent": 75 }

# 2. Annullare
curl -X POST https://api.listnride.com/v1/bookings/bkg_gr9z…/cancel \
  -H "Authorization: Bearer lnr_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "timing_issue" }'
# → "status": "canceled_by_customer"
GET/v1/commissionsbookings:read

Aggiungi ?aff=TUOCODICE a qualsiasi link di ListNRide – ogni pagina, ogni lingua. Se il cliente prenota entro il periodo concordato, la prenotazione conta per te; vince l’ultimo clic. Le prenotazioni dalle tue sessioni di checkout contano sempre per te, anche senza clic.

La provvigione è concordata individualmente e si basa sulle commissioni che ListNRide guadagna sulla prenotazione. Conta quando il noleggio è terminato; se annulla il noleggiatore, non c’è provvigione. GET /v1/commissions mostra clic, prenotazioni, livello e provvigione per mese – senza dati dei clienti. La liquidazione è mensile tramite nota di accredito.

Link e report
# Link partner – funziona su ogni pagina
https://www.listnride.de/berlin/e-bike?aff=NEEDABIKE

# La tua provvigione di un mese
curl "https://api.listnride.com/v1/commissions?month=2026-09" \
  -H "Authorization: Bearer lnr_live_…"
# → "clicks": 4812, "bookings": 91, "tier": "Stufe 3 · 30 %",
#   "commission_net": { "amount": 54120 }, "status": "approved"
Altro

Webhook

Quando lo stato di una prenotazione cambia, inviamo un POST al tuo URL webhook, ad es. booking.confirmed. Rispondi con 2xx – altrimenti riproviamo dopo 1 min, 5 min, 30 min e fino a 24 h. Usa ping per testare la connessione; l’id dell’evento resta uguale nei nuovi tentativi.

Verifica ogni messaggio con l’intestazione LNR-Signature: t=…,v1=…: HMAC-SHA256 su t + "." + body con il tuo segreto whsec_…. Usa il corpo originale non modificato e rifiuta i messaggi il cui t ha più di 5 minuti.

Esempio: booking.confirmed
POST https://tuo-sito.it/hooks/listnride
LNR-Event: booking.confirmed
LNR-Signature: t=1791210000,v1=5f2c…

{
  "id": "evt_Qm3xT0bWl2kZ8yQe",
  "object": "event",
  "type": "booking.confirmed",
  "created": "2026-11-02T09:14:03.000Z",
  "data": { "object": {
    "id": "bkg_gr9z-CSUh4I8UrC9WEwW2Q",
    "object": "booking",
    "mode": "live",
    "status": "confirmed",
    "reference": "LNR-w4kKb",
    "checkout_session": "cs_O8t1fc2rdEG2GyYTqghvfA",
    "ride": "ride_jK6nvpDczET3Adx8AKKn1w",
    "from": "2026-11-17T08:00:00.000Z",
    "to": "2026-11-18T16:00:00.000Z",
    "quantity": 1,
    "amount_total": 7800,
    "currency": "EUR",
    "client_reference": "NB-1042"
  } }
}
Verificare la firma
const crypto = require("crypto");

// rawBody: il corpo originale, così come è arrivato
function verify(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 expected = crypto.createHmac("sha256", secret)
    .update(`${p.t}.${rawBody}`).digest("hex");
  return typeof p.v1 === "string" && p.v1.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(p.v1));
}
Altro

Errori e limiti

Gli errori hanno sempre la stessa forma. Con il request_id troviamo subito il tuo caso.

Limiti per chiave: un limite al minuto e una quota giornaliera (intestazioni X-Quota-Limit, X-Quota-Remaining). Una ricerca si può sfogliare al massimo fino a 500 risultati: restringila per località, raggio, categoria o periodo. La raccolta massiva e la rivendita dei dati non sono consentite.

Ripetizioni sicure: invia l’intestazione Idempotency-Key con POST /v1/checkout/sessions e POST /v1/bookings/{id}/cancel. Una ripetizione con la stessa chiave e lo stesso contenuto restituisce la prima risposta (intestazione Idempotent-Replayed: true) invece di agire due volte. Le chiavi restano valide 24 ore.

HTTPcode
400parameter_missing, parameter_invalid, outside_opening_hours, duration_too_short, duration_too_long, multiple_listers, delivery_unavailable, pagination_limit
401missing_api_key, invalid_api_key
403missing_scope
404resource_missing, route_not_found
409ride_unavailable, already_canceled, processing, already_started
429rate_limited, daily_quota_exceeded, too_many_failed_attempts – X-RateLimit-*, X-Quota-*, Retry-After
Risposta di errore
{ "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" } }
Altro

SDK e strumenti

Client ufficiali in un unico file, senza dipendenze – copiali nel tuo progetto. Gestiscono autenticazione, paginazione, nuovi tentativi in caso di 429/5xx, Idempotency-Key e verifica dei webhook.

Node.js
const { ListNRide } = require("./listnride");
const lnr = new ListNRide({ apiKey: process.env.LNR_API_KEY });

for await (const ride of lnr.rides.all({ lat: 52.52, lng: 13.40, category: "e-bike" })) {
  console.log(ride.name, ride.price.per_day);
}
const session = await lnr.checkoutSessions.create({ ride: "ride_…", from: "2026-11-17",
  to: "2026-11-19", return_url: "https://your-site.com/thanks" });  // l’Idempotency-Key viene aggiunta automaticamente
Altro

Versioni

La versione fa parte del percorso. In /v1 aggiungiamo solo campi – nulla viene rimosso o rinominato. Le modifiche sostanziali usciranno come /v2, e /v1 resterà attiva almeno 12 mesi. La descrizione leggibile dalle macchine (OpenAPI 3.1) è su /openapi.json e https://api.listnride.com/v1/openapi.json.

Altro

Modifiche

  1. Idempotency-Key per le chiamate di scrittura, collezione Postman, client ufficiali per Node.js, PHP e Python.

  2. Affiliazione: link partner con ?aff=CODE e GET /v1/commissions.

  3. GET /v1/bookings, anteprima di cancellazione e POST /v1/bookings/{id}/cancel (scope bookings:cancel).

  4. Filtri di ricerca (prezzo, altezza, dotazione, area della mappa …), scaglioni di prezzo, orari, condizioni di cancellazione, calendario di disponibilità, recensioni e profili dei noleggiatori.

  5. Località, classi di veicoli, POST /v1/quotes, prenotazione per classe e quota giornaliera per chiave.

  6. Lancio di v1: bici, categorie, sessioni di checkout, prenotazioni, webhook e modalità test.

Richiedi accesso

Raccontaci del tuo sito e di cosa hai in mente. Ricevi prima una chiave di test – il passaggio al live segue dopo una breve chiamata.

partner@listnride.com

Richiedi accesso

Raccontaci in breve chi sei e cosa hai in mente. Ricevi prima una chiave di test – il passaggio al live segue dopo una breve chiamata.

Preferisci l’e-mail? partner@listnride.com