REST API e webhook per il tuo sito NCC
Prenotazioni, preventivi, clienti e catalogo in JSON, sul dominio del tuo sito. Webhook firmati per ogni evento. Inclusa nei piani Pro+ e Leader, senza costi a chiamata.
Richiesta
curl https://tuodominio.it/connect/api/v1/site \
-H "Authorization: Bearer $TOSIU_API_KEY"$ch = curl_init('https://tuodominio.it/connect/api/v1/site');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('TOSIU_API_KEY')],
CURLOPT_RETURNTRANSFER => true,
]);
$site = json_decode(curl_exec($ch), true)['data'];const res = await fetch('https://tuodominio.it/connect/api/v1/site', {
headers: { Authorization: `Bearer ${process.env.TOSIU_API_KEY}` },
});
const { data: site } = await res.json();Risposta 200 OK
{
"data": {
"name": "Example Transfers",
"domain": "tuodominio.it",
"languages": {
"primary": "it",
"supported": [
"it",
"en"
]
},
"currency": "EUR",
"timezone": "Europe/Rome",
"booking_mode": "vehicle_class",
"pricing_method": "manual",
"payment_methods": {
"cash": true,
"card_on_arrival": false,
"online_providers": [
"stripe"
]
},
"booking_rules": {
"max_passengers": 16,
"min_booking_days": 0,
"cancellation_hours": 24
},
"tours_available": true,
"api_version": "v1"
}
}- Base URL
https://tuodominio.it/connect/api/v1- Formato
- JSON, UTF-8, solo HTTPS
- Autenticazione
- Bearer token con permessi
- Versione
- v1, aggiornata il 15 settembre 2026
- Endpoint
- 28 endpoint, 8 eventi
Panoramica
Ogni sito Tosiu espone la sua API sul proprio dominio. Le prenotazioni create dall'API passano dalla stessa catena del sito: stesso calcolo del prezzo, stesse email al cliente, stesse regole di disponibilità. Nello storico della prenotazione resta scritto quale chiave l'ha creata.
La usa il tuo gestionale per restare sincronizzato, la usa il tuo sviluppatore per un'app o un listino, la usano i partner che prenotano per conto dei loro clienti.
Dove sta cosa
- API
tuodominio.it/connect/api/v1- Chiavi, permessi, registro chiamate
- Pannello, Integrazioni, API pubblica
- Documentazione completa
tuodominio.it/connect/docs- Contratto OpenAPI
tuodominio.it/connect/openapi.json
Risorse
| Risorsa | Endpoint | Permessi |
|---|---|---|
| Profilo del sito | 1 | qualsiasi chiave |
| Prenotazioni | 7 | bookings:read bookings:write |
| Preventivi | 2 | quotes:read quotes:write |
| Catalogo | 6 | catalog:read |
| Disponibilità | 3 | availability:read |
| Clienti | 4 | customers:read customers:write |
| Autisti e flotta | 2 | drivers:read fleet:read |
| Webhook | 3 | webhooks:manage |
Autenticazione
Ogni richiesta porta la chiave nell'header Authorization, mai nell'indirizzo. In alternativa si può usare l'header X-Api-Key. Del valore in chiaro resta solo la copia che ti mostriamo alla creazione: noi conserviamo l'impronta.
curl https://tuodominio.it/connect/api/v1/bookings \
-H "Authorization: Bearer tsk_live_3kP9..."curl https://tuodominio.it/connect/api/v1/bookings \
-H "X-Api-Key: tsk_live_3kP9..."- Una chiave vale per un solo dominio: usata altrove risponde
403site_mismatch. - Puoi limitarla agli indirizzi IP del tuo fornitore.
- Ogni chiave ha solo i permessi che le dai: senza il permesso giusto la risposta è
403missing_scope, con il nome del permesso. - La revoca dal pannello è immediata e definitiva. Per ruotare una chiave ne crei una nuova e revochi la vecchia.
Permessi
| Permesso | Cosa sblocca |
|---|---|
| qualsiasi chiave | GET /site |
| bookings:read | GET /bookingsGET /bookings/{ref}GET /bookings/{ref}/events |
| bookings:write | POST /bookingsPATCH /bookings/{ref}POST /bookings/{ref}/cancelPOST /bookings/{ref}/payment-link |
| quotes:read | GET /quotes/{number} |
| quotes:write | POST /quotes |
| customers:read | GET /customersGET /customers/{id} |
| customers:write | POST /customersPATCH /customers/{id} |
| webhooks:manage | GET /webhooksPOST /webhooksDELETE /webhooks/{id} |
| catalog:read | GET /locationsGET /routesGET /vehicle-classesGET /extrasGET /toursGET /shuttles |
| availability:read | GET /tours/{slug}/availabilityGET /shuttles/{slug}/runsGET /schedule-blocks |
| drivers:read | GET /drivers |
| fleet:read | GET /fleet |
Richieste e risposte
Poche regole, uguali per tutti gli endpoint.
- Importi come stringhe
- Sempre testo ("180.00") con il codice valuta accanto: nessun arrotondamento in virgola mobile.
- Ora locale del sito
- Pickup e rientro sono l'orologio del posto. I filtri
updated_sincesono ISO 8601 in UTC. - Liste paginate
- page e
per_page(massimo 100), con data e meta in ogni risposta. - Lingua
?lang=sceglie la lingua dei nomi di catalogo, tra quelle attive sul sito.
{
"data": [
{
"booking_ref": "TCV1042",
"status": "confirmed",
"pickup_datetime": "2026-08-02 10:30:00",
"price": {
"currency": "EUR",
"total": "180.00"
}
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 41,
"has_more": true
}
}Errori
Ogni errore torna con lo stato HTTP giusto e un oggetto error: un codice stabile, un messaggio leggibile e, quando serve, il campo che non va. Il tuo programma legge il codice: dentro la v1 non cambia mai.
{
"error": {
"code": "invalid_parameter",
"message": "pickup_datetime must be YYYY-MM-DD HH:MM",
"field": "pickup_datetime"
}
}Stati HTTP
400- Richiesta non valida: JSON rotto o HTTP senza S.
401- Chiave mancante, sconosciuta, scaduta o revocata.
403- Dominio, indirizzo IP o permesso sbagliato.
404- Risorsa inesistente su questo sito.
409- Conflitto di stato, per esempio una prenotazione già annullata.
422- Parametro mancante o fuori intervallo, oppure il motore ha rifiutato la richiesta.
429- Limite al minuto superato: Retry-After dice quanto attendere.
5xx- Errore da parte nostra o del provider di pagamento: non è stato cambiato nulla.
Tutti i 45 codici di errore
| Codice | Stato | Significato |
|---|---|---|
https_required | 400 | La richiesta è arrivata su HTTP non cifrato. Questa API accetta solo HTTPS. |
missing_key | 401 | Nessuna chiave API inviata. Usare Authorization: Bearer oppure l'header X-Api-Key. |
invalid_key | 401 | La chiave è malformata o sconosciuta. |
key_revoked | 401 | La chiave è stata revocata dal gestore del sito. La revoca è definitiva: chiedere una chiave nuova. |
key_expired | 401 | La chiave ha superato la data di scadenza. |
site_mismatch | 403 | La chiave appartiene a un sito diverso dal dominio a cui è stata inviata. Una chiave vale per un solo dominio. |
ip_not_allowed | 403 | La chiave ha una lista di IP consentiti è la richiesta non proviene da quella lista. |
missing_scope | 403 | La chiave non ha lo scope richiesto da questo endpoint. Il nome dello scope è nel corpo della risposta. |
rate_limited | 429 | La chiave ha superato il limite al minuto. Retry-After indica quanto attendere. |
not_found | 404 | Endpoint inesistente nella v1. |
unknown_api_version | 404 | Il percorso indica una versione dell'API che questo sito non serve. La versione attuale è la v1. |
method_not_allowed | 405 | La risorsa esiste ma non con quel metodo. L'header Allow elenca i metodi accettati. |
invalid_json | 400 | Il corpo della richiesta non è JSON valido. |
invalid_parameter | 422 | Un parametro manca, è malformato o fuori intervallo. Quello in questione è indicato in "field". |
invalid_idempotency_key | 422 | Idempotency-Key deve essere di 1-128 caratteri fra A-Z a-z 0-9 . _ : e - |
idempotency_key_reuse | 422 | Questa Idempotency-Key è già stata usata su questo endpoint con un corpo diverso. Usare una chiave nuova per una richiesta nuova. |
idempotency_in_progress | 409 | La richiesta originale con questa Idempotency-Key è ancora in corso. Riprovare dopo i secondi indicati in Retry-After; non inviare una chiave nuova, si rischia una seconda prenotazione. |
booking_not_found | 404 | Nessuna prenotazione con quel riferimento su questo sito. Le ricerche abbandonate e le prenotazioni cestinate non vengono mai esposte. |
booking_not_editable | 409 | La prenotazione è in uno stato che non permette più modifiche (per esempio già annullata). |
booking_not_cancellable | 409 | La prenotazione è in uno stato che non può essere annullato. |
booking_not_awaiting_payment | 409 | La prenotazione non è in attesa di un pagamento online, quindi non c'è nessun link di pagamento da inviare. |
payment_not_online | 409 | La prenotazione usa un metodo di pagamento offline (contanti, bonifico): niente da pagare online. |
email_failed | 502 | L'email al cliente non è stata inviata (il trasporto mail del sito l'ha rifiutata). Il link di pagamento resta valido. |
booking_conflict | 409 | Il motore di prenotazione ha rifiutato per un conflitto, per esempio una partenza tour esaurita mentre la richiesta era in corso. |
booking_create_failed | 422 | Il motore di prenotazione ha rifiutato di creare la prenotazione. Il messaggio spiega il motivo. |
booking_confirm_failed | 422 | Il viaggio è stato quotato ma il passaggio di conferma è stato rifiutato. Non è stato creato nulla. |
quote_failed | 422 | Non è stato possibile calcolare il prezzo: di solito un indirizzo fuori zona di servizio, o una tratta che il sito non vende. |
reprice_failed | 422 | La modifica non è stata ricalcolata dal motore di prezzo del sito, quindi non è stato cambiato nulla. |
luggage_does_not_fit | 422 | I bagagli e le attrezzature richieste non entrano nella classe di veicolo scelta. Scegliere una classe più grande. |
location_not_found | 422 | Nessuna località attiva con quell'id su questo sito. Vedere GET /locations. |
vehicle_class_required | 422 | Questo sito vende per classe di veicolo, quindi vehicle_class_id è obbligatorio. Vedere GET /vehicle-classes. |
vehicle_class_not_found | 422 | Nessuna classe di veicolo attiva con quell'id su questo sito. |
invalid_payment_method | 422 | Quel metodo di pagamento non è attivo su questo sito. Vedere GET /site. |
payment_provider_unavailable | 503 | Il provider di pagamento online non è raggiungibile, quindi la prenotazione non è stata creata. Riprovare, o usare un metodo di pagamento offline. |
tour_extra_invalid | 422 | Un extra del tour è stato indicato con una chiave o una quantità malformata. |
tour_not_found | 404 | Nessun tour attivo con quello slug su questo sito. Vedere GET /tours. |
quote_not_found | 404 | Nessun preventivo con quel numero su questo sito. I preventivi eliminati non vengono mai esposti. |
shuttle_not_found | 404 | Nessuna navetta attiva con quello slug su questo sito. Vedere GET /shuttles. |
tour_not_bookable | 409 | Il tour è venduto su richiesta (sale_mode "request" in GET /tours): non ha disponibilità né checkout online. |
customer_not_found | 404 | Nessun cliente con quell'id su questo sito. |
customer_email_taken | 409 | Un altro cliente attivo di questo sito usa già quell'indirizzo email. |
webhook_not_found | 404 | Nessuna sottoscrizione webhook con quell'id su questo sito. |
webhook_url_exists | 409 | Esiste già una sottoscrizione per quell'URL. Eliminarla prima; è anche così che si ruota un secret. |
webhook_limit_reached | 422 | Un sito può avere al massimo 10 sottoscrizioni webhook. |
internal_error | 500 | Qualcosa è fallito su questo server. Non è stato cambiato nulla. Se persiste, contattare il gestore del sito. |
Limiti e idempotenza
Ogni chiave ha un limite di richieste al minuto, scelto nel pannello. Ogni risposta dice quante ne restano; oltre il limite arriva un 429 in JSON con Retry-After. Le POST accettano una Idempotency-Key: se la stessa richiesta parte due volte, per esempio dopo un timeout, la seconda riceve la risposta originale e non crea una seconda prenotazione.
curl -X POST https://tuodominio.it/connect/api/v1/bookings \
-H "Authorization: Bearer $TOSIU_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-8812" \
-d @booking.jsonHTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Retry-After: 18
{"error":{"code":"rate_limited","message":"..."}}Idempotency-Key: da 1 a 128 caratteri, valida 24 ore.- Stessa chiave e stesso corpo: risposta identica, con
Idempotency-Replay: true. - Stessa chiave e corpo diverso:
422idempotency_key_reuse.
Webhook
Registri un indirizzo HTTPS con POST /webhooks e scegli gli eventi. A ogni evento ti arriva la prenotazione completa, con la stessa struttura di GET /bookings/{ref}, firmata con il secret che ricevi una volta sola alla registrazione.
Header di ogni consegna
X-Tosiu-Event- il nome dell'evento
X-Tosiu-Delivery- id univoco, per scartare i doppioni
X-Tosiu-Timestamp- secondi Unix del tentativo
X-Tosiu-Signature- sha256= HMAC di timestamp.corpo
Nuovi tentativi
Una consegna è riuscita se il tuo server risponde 2xx entro 10 secondi. Altrimenti riproviamo:
- 11 min
- 25 min
- 330 min
- 42 ore
- 56 ore
Dal pannello vedi il registro delle consegne e puoi reinviarne una. Fino a 10 indirizzi per sito.
Consegne webhookhttps://gestionale.tuosito.it/hooks/tosiu
-
booking.createdora consegnato -
booking.payment_updated12 min consegnato -
booking.assigned41 min consegnato
Verificare la firma
import crypto from 'node:crypto';
// rawBody: the request body exactly as received, before JSON.parse
function isFromTosiu(rawBody, headers, secret) {
const ts = headers['x-tosiu-timestamp'];
const expected = 'sha256=' + crypto.createHmac('sha256', secret)
.update(ts + '.' + rawBody).digest('hex');
const given = headers['x-tosiu-signature'] || '';
return given.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}$body = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_TOSIU_TIMESTAMP'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $secret);
if (!hash_equals($expected, $_SERVER['HTTP_X_TOSIU_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
$event = json_decode($body, true);Eventi
booking.created | Una prenotazione è stata creata e confermata (lo stato può essere awaiting_payment per i metodi online). Per una prenotazione tour parte anche tour.booked. |
booking.updated | Una prenotazione è stata modificata: date, passeggeri, prezzo, stato o qualsiasi altro campo. La consegna contiene l'oggetto prenotazione aggiornato. |
booking.cancelled | Una prenotazione è stata annullata (annullamento visibile al cliente, mai una cancellazione). |
booking.payment_updated | Un pagamento ha cambiato lo stato di pagamento della prenotazione (es. un pagamento online completato). |
booking.assigned | Un autista o partner è stato assegnato a una tratta della prenotazione (o la tratta è stata rimossa dall'assegnazione). |
booking.deleted | Una prenotazione è stata spostata nel cestino dall'operatore. A differenza di booking.cancelled è un'azione di back office: la prenotazione scompare dalle letture API. Un ripristino genera booking.updated. |
quote.accepted | Un preventivo è stato accettato e convertito in prenotazione; il payload contiene il numero del preventivo è il nuovo booking_ref. |
tour.booked | Un tour è stato prenotato (parte insieme a booking.created quando service_type è tour). |
Endpoint
Generato dal contratto pubblico dell'API: quando la v1 cambia, cambia anche questo elenco. Apri un endpoint per vedere parametri ed esempi.
Nessun endpoint per questo filtro.
Profilo del sito
GET/siteIl profilo pubblico del sito: lingue, valuta, modalità di prenotazione, metodo di prezzo, metodi di pagamento, regole. Da chiamare PER PRIMA: dice quale forma di richiesta accetta questo sito.qualsiasi chiave
Il profilo pubblico del sito: lingue, valuta, modalità di prenotazione, metodo di prezzo, metodi di pagamento, regole. Da chiamare PER PRIMA: dice quale forma di richiesta accetta questo sito.
curl https://tuodominio.it/connect/api/v1/site \
-H "Authorization: Bearer tsk_live_..."{
"data": {
"name": "Example Transfers",
"domain": "tuodominio.it",
"languages": {
"primary": "it",
"supported": [
"it",
"en"
]
},
"currency": "EUR",
"timezone": "Europe/Rome",
"booking_mode": "vehicle_class",
"pricing_method": "manual",
"payment_methods": {
"cash": true,
"card_on_arrival": false,
"online_providers": [
"stripe"
]
},
"booking_rules": {
"max_passengers": 16,
"min_booking_days": 0,
"cancellation_hours": 24
},
"tours_available": true,
"api_version": "v1"
}
}Prenotazioni
GET/bookingsElenco prenotazioni, dal pickup più recente (o dalla modifica più vecchia con updated_since, per i client di sincronizzazione). Le ricerche abbandonate e le prenotazioni nel cestino non compaiono mai.bookings:read
Elenco prenotazioni, dal pickup più recente (o dalla modifica più vecchia con updated_since, per i client di sincronizzazione). Le ricerche abbandonate e le prenotazioni nel cestino non compaiono mai.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
page | query | integer | Numero di pagina, da 1. |
per_page | query | integer | Righe per pagina, 1-100 (default 25). |
status | query | string | Uno tra: pending, awaiting_payment, confirmed, cancelled, completed, no_show. |
service_type | query | string | "transfer", "tour" o "shuttle". |
from_date | query | string | YYYY-MM-DD, data di pickup in ora locale del sito (limite inferiore incluso). |
to_date | query | string | YYYY-MM-DD, data di pickup in ora locale del sito (limite superiore incluso). |
customer_email | query | string | Email cliente esatta (senza distinzione maiuscole). |
booking_ref | query | string | Riferimento prenotazione esatto. |
updated_since | query | string | Timestamp ISO 8601 (UTC se senza offset); l'ordinamento passa a updated_at crescente. |
curl "https://tuodominio.it/connect/api/v1/bookings?status=confirmed&per_page=2" \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"booking_ref": "TCV1042",
"status": "confirmed",
"payment_status": "pending",
"service_type": "transfer",
"trip_type": "one_way",
"pickup_datetime": "2026-08-02 10:30:00",
"return_datetime": null,
"from": {
"location_id": 12,
"address": null,
"place_id": null,
"iata": "TRN",
"lat": 45.2008000000000009777068044058978557586669921875,
"lng": 7.64970000000000016626700016786344349384307861328125
},
"to": {
"location_id": 15,
"address": null,
"place_id": null,
"iata": null,
"lat": 45.9365999999999985448084771633148193359375,
"lng": 7.6296999999999997044142219237983226776123046875
},
"passengers": {
"adults": 2,
"children": 0,
"infants": 0,
"total": 2
},
"price": {
"currency": "EUR",
"total": "180.00",
"base": "180.00",
"amount_online": null,
"amount_due": "180.00"
},
"payment_method": "cash",
"created_at": "2026-07-28 09:12:44",
"updated_at": "2026-07-28 09:13:02"
}
],
"meta": {
"page": 1,
"per_page": 2,
"total": 41,
"has_more": true
}
}GET/bookings/{ref}Una prenotazione tramite il suo riferimento. La stessa struttura che ogni consegna webhook porta in data.booking.bookings:read
Una prenotazione tramite il suo riferimento. La stessa struttura che ogni consegna webhook porta in data.booking.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
refobbligatorio | percorso | string | Il riferimento della prenotazione (es. TCV1042). |
curl https://tuodominio.it/connect/api/v1/bookings/TCV1042 \
-H "Authorization: Bearer tsk_live_..."{
"data": {
"booking_ref": "TCV1042",
"status": "confirmed",
"payment_status": "pending",
"service_type": "transfer",
"trip_type": "one_way",
"pickup_datetime": "2026-08-02 10:30:00",
"from": {
"location_id": 12,
"lat": 45.2008000000000009777068044058978557586669921875,
"lng": 7.64970000000000016626700016786344349384307861328125
},
"to": {
"location_id": 15,
"lat": 45.9365999999999985448084771633148193359375,
"lng": 7.6296999999999997044142219237983226776123046875
},
"passengers": {
"adults": 2,
"children": 0,
"infants": 0,
"total": 2
},
"vehicle": {
"vehicle_class_id": 3,
"class_key": "sedan",
"name": "Berlina",
"max_passengers": 3,
"luggage": 3,
"quantity": 1,
"price_per_vehicle": "180.00"
},
"customer": {
"first_name": "Mario",
"last_name": "Rossi",
"email": "mario.rossi@example.com",
"phone": "+39333000000",
"language": "it"
},
"flight_number": "AZ1234",
"pickup_sign": "Rossi family",
"price": {
"currency": "EUR",
"total": "180.00"
},
"payment_method": "cash",
"payment_link": null,
"extras": [],
"created_at": "2026-07-28 09:12:44",
"updated_at": "2026-07-28 09:13:02"
}
}GET/bookings/{ref}/eventsLo storico modifiche della prenotazione, dal più vecchio: creazione, modifiche, cambi di stato, pagamenti, annullamenti, assegnazioni, email inviate - con chi ha agito (sito, operatore, etichetta della chiave API) e quando.bookings:read
Lo storico modifiche della prenotazione, dal più vecchio: creazione, modifiche, cambi di stato, pagamenti, annullamenti, assegnazioni, email inviate - con chi ha agito (sito, operatore, etichetta della chiave API) e quando.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
refobbligatorio | percorso | string | Il riferimento della prenotazione. |
page, per_page | query | integer | Paginazione standard. |
curl https://tuodominio.it/connect/api/v1/bookings/TCV1042/events \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 901,
"event": "created",
"actor": {
"type": "customer",
"name": null
},
"summary": "Booking created",
"note": null,
"created_at": "2026-07-28 09:12:44"
},
{
"id": 905,
"event": "edited",
"actor": {
"type": "api",
"name": "My integration"
},
"summary": "Pickup time changed",
"note": null,
"created_at": "2026-07-28 10:02:11"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 2,
"has_more": false
}
}POST/bookingsCrea E conferma una prenotazione in una sola chiamata, con il prezzo calcolato dal motore del sito (un prezzo inviato non viene mai accettato).bookings:write
Crea E conferma una prenotazione in una sola chiamata, con il prezzo calcolato dal motore del sito (un prezzo inviato non viene mai accettato). Risponde 201 con la prenotazione, il suo manage_url e payment_url quando un metodo online richiede che il cliente completi il pagamento (la prenotazione resta in awaiting_payment). Inviare un Idempotency-Key: un nuovo tentativo dopo un timeout non deve prenotare una seconda auto.
accetta Idempotency-Key
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
Idempotency-Key | header | string | Chiave univoca scelta dal chiamante (1-128 caratteri). Una ripetizione entro 24h restituisce la risposta originale e non crea nulla. |
from_location_id / from_place_idobbligatorio | corpo | integer / string | Partenza: un id località (GET /locations) su ogni sito; un place id Google (+ etichetta from_address) solo sui siti con prezzo a formula. |
to_location_id / to_place_idobbligatorio | corpo | integer / string | Destinazione, stesse regole della partenza. |
pickup_datetimeobbligatorio | corpo | string | "YYYY-MM-DD HH:MM", ora locale del sito. |
trip_type | corpo | string | "one_way" (default) o "round_trip" (allora return_datetime è obbligatorio). |
adults, children, infants | corpo | integer | Composizione passeggeri (adults default 1). |
vehicle_class_id | corpo | integer | Obbligatorio sui siti booking_mode=vehicle_class (GET /vehicle-classes). |
customerobbligatorio | corpo | object | {first_name, last_name, email, phone}, tutti obbligatori. |
language | corpo | string | La lingua del cliente (tra quelle supportate dal sito); determina le email di conferma. |
payment_methodobbligatorio | corpo | string | Uno dei payment_methods di GET /site (es. "cash", "stripe"). |
payment_option | corpo | string | "full" (default) o "deposit" dove il sito lo offre. |
extras | corpo | array | [{extra_type_id, quantity}] da GET /extras. |
promo_code | corpo | string | Un codice promo da applicare (validato dal motore). |
flight_number, pickup_address, dropoff_address, customer_notes, ... | corpo | string | Dettagli di viaggio, incl. i gemelli return_* sull'andata e ritorno; internal_notes è solo per l'operatore. |
pickup_sign | corpo | string | Nome sul cartello in aeroporto dell'autista per i pickup in aeroporto, opzionale, max 80; vuoto = il nome della prenotazione. |
curl -X POST https://tuodominio.it/connect/api/v1/bookings \
-H "Authorization: Bearer tsk_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4f9d2c1e-order-8812" \
-d '{
"from_location_id": 12, "to_location_id": 15,
"pickup_datetime": "2026-08-02 10:30",
"adults": 2, "vehicle_class_id": 3,
"customer": {"first_name": "Mario", "last_name": "Rossi",
"email": "mario.rossi@example.com", "phone": "+39333000000"},
"payment_method": "cash"
}'{
"data": {
"booking_ref": "TCV1043",
"status": "confirmed",
"payment_status": "pending",
"price": {
"currency": "EUR",
"total": "180.00",
"amount_due": "180.00"
},
"manage_url": "https://tuodominio.it/booking/TCV1043?pass=..."
}
}PATCH/bookings/{ref}Modifica una prenotazione: gli stessi campi della console operatore (contatti, indirizzi, dettagli viaggio, passeggeri, date, trip_type, vehicle_class_id, extras, promo_code, payment_method, price_override), riprezzata dallo stesso motore.bookings:write
Modifica una prenotazione: gli stessi campi della console operatore (contatti, indirizzi, dettagli viaggio, passeggeri, date, trip_type, vehicle_class_id, extras, promo_code, payment_method, price_override), riprezzata dallo stesso motore. Una chiave ASSENTE lascia il valore salvato, extras compresi; un [] esplicito li svuota. Un price_override BLOCCA il totale (price_locked=true nella prenotazione): le modifiche successive lo mantengono qualunque cosa cambi; inviare price_override "" o null per sbloccare e riprezzare. Un importo online incassato non viene mai riscritto; il saldo si adegua. notify_customer=true invia l'email "prenotazione aggiornata" dell'operatore.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
refobbligatorio | percorso | string | Il riferimento della prenotazione. |
notify_customer | corpo | boolean | Invia al cliente l'email di prenotazione aggiornata (default false). |
pickup_sign | corpo | string | Nome sul cartello in aeroporto dell'autista per i pickup in aeroporto, max 80; "" o null lo azzera (l'autista usa il nome della prenotazione). |
curl -X PATCH https://tuodominio.it/connect/api/v1/bookings/TCV1043 \
-H "Authorization: Bearer tsk_live_..." \
-H "Content-Type: application/json" \
-d '{"pickup_datetime": "2026-08-02 11:15", "notify_customer": true}'{
"data": {
"booking_ref": "TCV1043",
"status": "confirmed",
"pickup_datetime": "2026-08-02 11:15:00",
"price": {
"currency": "EUR",
"total": "180.00"
}
},
"notified": true
}POST/bookings/{ref}/cancelAnnulla una prenotazione (visibile al cliente; l'API non cancella mai). Codice motivo, nota e refund_amount opzionali; notify_customer=true invia l'email di annullamento.bookings:write
Annulla una prenotazione (visibile al cliente; l'API non cancella mai). Codice motivo, nota e refund_amount opzionali; notify_customer=true invia l'email di annullamento.
accetta Idempotency-Key
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
refobbligatorio | percorso | string | Il riferimento della prenotazione. |
reason | corpo | string | Uno tra: customer_request, no_show, duplicate, payment_failed, unavailable, weather, other. |
note | corpo | string | Nota libera salvata sull'annullamento. |
refund_amount | corpo | number | Rimborso registrato; un importo positivo imposta payment_status a refunded. |
notify_customer | corpo | boolean | Invia l'email di annullamento (default false). |
curl -X POST https://tuodominio.it/connect/api/v1/bookings/TCV1043/cancel \
-H "Authorization: Bearer tsk_live_..." \
-H "Content-Type: application/json" \
-d '{"reason": "customer_request", "notify_customer": true}'{
"data": {
"booking_ref": "TCV1043",
"status": "cancelled",
"cancellation_reason": "customer_request",
"cancelled_at": "2026-07-30 15:04:11"
},
"notified": true
}POST/bookings/{ref}/payment-linkReinvia il link di pagamento di una prenotazione ancora in attesa del pagamento online (carta rifiutata, cliente che ha chiuso la scheda del gateway).bookings:write
Reinvia il link di pagamento di una prenotazione ancora in attesa del pagamento online (carta rifiutata, cliente che ha chiuso la scheda del gateway). Invia al cliente l'email "completa il pagamento" e restituisce payment_link: la pagina della prenotazione del cliente, il cui "Paga ora" riavvia il checkout del gateway, quindi lo stesso link funziona finché il pagamento non va a buon fine (condivisibile anche via WhatsApp o SMS). 409 booking_not_awaiting_payment su ogni altro stato; 409 payment_not_online con un metodo offline.
accetta Idempotency-Key
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
refobbligatorio | percorso | string | Il riferimento della prenotazione. |
send_email | corpo | boolean | Invia al cliente l'email con il link di pagamento (default true). false restituisce soltanto il link. |
curl -X POST https://tuodominio.it/connect/api/v1/bookings/TCV1043/payment-link \
-H "Authorization: Bearer tsk_live_..." \
-H "Content-Type: application/json" \
-d '{"send_email": true}'{
"data": {
"booking_ref": "TCV1043",
"status": "awaiting_payment",
"payment_status": "failed",
"payment_method": "sumup",
"payment_link": "https://tuodominio.it/my-booking?ref=TCV1043&pass=..."
},
"emailed": true
}Preventivi
GET/quotes/{number}Un preventivo tramite il suo numero (es. PREV-0001): viaggio, passeggeri, prezzo, validità, cliente, cronologia di invio e il booking_ref una volta accettato.quotes:read
Un preventivo tramite il suo numero (es. PREV-0001): viaggio, passeggeri, prezzo, validità, cliente, cronologia di invio e il booking_ref una volta accettato. `expired` è derivato da valid_until al momento della lettura. I preventivi eliminati non vengono mai restituiti. Da non confondere con POST /quotes, che calcola il prezzo di un viaggio senza creare nulla.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
numberobbligatorio | percorso | string | Il numero del preventivo come mostrato all'operatore e al cliente (non distingue maiuscole). |
curl https://tuodominio.it/connect/api/v1/quotes/PREV-0001 \
-H "Authorization: Bearer tsk_live_..."{
"data": {
"quote_number": "PREV-0001",
"status": "sent",
"valid_until": "2026-08-10",
"trip_type": "one_way",
"pickup_datetime": "2026-08-05 10:30:00",
"return_datetime": null,
"from": {
"location_id": 12,
"address": null,
"place_id": null,
"lat": 45.92999999999999971578290569595992565155029296875,
"lng": 7.62000000000000010658141036401502788066864013671875
},
"to": {
"location_id": 15,
"address": null,
"place_id": null,
"lat": 45.469999999999998863131622783839702606201171875,
"lng": 9.1899999999999995026200849679298698902130126953125
},
"distance_km": 98.400000000000005684341886080801486968994140625,
"duration_minutes": 95,
"passengers": {
"adults": 2,
"children": 0,
"infants": 0,
"total": 2
},
"vehicle_class_id": 3,
"price": {
"total": "180.00",
"currency": "EUR"
},
"customer": {
"first_name": "Mario",
"last_name": "Rossi",
"email": "mario.rossi@example.com",
"phone": "+39333000000"
},
"notes": null,
"booking_ref": null,
"created_at": "2026-07-30 09:12:00",
"sent_at": "2026-07-30 09:15:02",
"viewed_at": null,
"accepted_at": null
}
}POST/quotesCalcola il prezzo di un viaggio SENZA creare nulla: il dettaglio completo (base, extra, sconti, acconto) dallo stesso motore del checkout.quotes:write
Calcola il prezzo di un viaggio SENZA creare nulla: il dettaglio completo (base, extra, sconti, acconto) dallo stesso motore del checkout. Stessa forma del viaggio di POST /bookings; extras, promo_code e payment_method opzionali sono inclusi nel calcolo.
accetta Idempotency-Key
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
(trip fields)obbligatorio | corpo | object | Come POST /bookings: from/to (id località, o place id sui siti a formula), pickup_datetime, trip_type, passeggeri, vehicle_class_id dove serve. |
curl -X POST https://tuodominio.it/connect/api/v1/quotes \
-H "Authorization: Bearer tsk_live_..." \
-H "Content-Type: application/json" \
-d '{"from_location_id": 12, "to_location_id": 15,
"pickup_datetime": "2026-08-02 10:30", "adults": 2, "vehicle_class_id": 3}'{
"data": {
"currency": "EUR",
"trip": {
"from_location_id": 12,
"to_location_id": 15,
"pickup_datetime": "2026-08-02 10:30:00",
"return_datetime": null,
"trip_type": "one_way",
"passengers": {
"adults": 2,
"children": 0,
"infants": 0
},
"vehicle_class_id": 3,
"distance_km": 98.400000000000005684341886080801486968994140625,
"duration_minutes": 95
},
"breakdown": {
"base_price": "180.00",
"route_discount": "0.00",
"outbound_price": "180.00",
"outbound_night_supplement": null,
"return_price": null,
"return_night_supplement": null,
"roundtrip_discount": null,
"extras": [],
"extras_total": "0.00",
"promo_code": null,
"promo_discount": null,
"payment_discount": null,
"grand_total": "180.00"
},
"payment": {
"method": null,
"payment_type": "full",
"deposit_percent": null,
"amount_online": null,
"amount_due": "180.00"
}
}
}Catalogo
GET/locationsLe località attive del sito (gli id from/to accettati da POST /quotes e POST /bookings). ?lang= sceglie la lingua di visualizzazione.catalog:read
Le località attive del sito (gli id from/to accettati da POST /quotes e POST /bookings). ?lang= sceglie la lingua di visualizzazione.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
lang | query | string | Una delle lingue supportate dal sito. |
page, per_page | query | integer | Paginazione standard. |
curl https://tuodominio.it/connect/api/v1/locations \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 12,
"name": "Torino Airport",
"slug": "torino-airport",
"type": "Airport",
"iata": "TRN",
"lat": 45.2008000000000009777068044058978557586669921875,
"lng": 7.64970000000000016626700016786344349384307861328125,
"country": "IT",
"fixed_address": null
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 9,
"has_more": false
}
}GET/routesLe tratte attive del sito con i prezzi salvati dove il sito li pubblica (per fascia flotta in modalità capacity, per classe veicolo altrimenti; i siti a formula non espongono prezzi salvati - usare POST /quotes).catalog:read
Le tratte attive del sito con i prezzi salvati dove il sito li pubblica (per fascia flotta in modalità capacity, per classe veicolo altrimenti; i siti a formula non espongono prezzi salvati - usare POST /quotes).
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
lang, page, per_page | query | mixed | Lingua di visualizzazione + paginazione standard. |
curl https://tuodominio.it/connect/api/v1/routes \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 31,
"slug": "torino-airport-cervinia",
"from": {
"location_id": 12,
"name": "Torino Airport"
},
"to": {
"location_id": 15,
"name": "Cervinia"
},
"distance_km": 98.400000000000005684341886080801486968994140625,
"duration_minutes": 95,
"class_prices": [
{
"vehicle_class_id": 3,
"price": "180.00"
}
]
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 14,
"has_more": false
}
}GET/vehicle-classesLe classi veicolo abilitate su un sito booking_mode=vehicle_class: capienza, bagagli, l'id richiesto da POST /bookings.catalog:read
Le classi veicolo abilitate su un sito booking_mode=vehicle_class: capienza, bagagli, l'id richiesto da POST /bookings.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
lang, page, per_page | query | mixed | Lingua di visualizzazione + paginazione standard. |
curl https://tuodominio.it/connect/api/v1/vehicle-classes \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 3,
"class_key": "sedan",
"category": "sedan",
"name": "Berlina",
"min_passengers": 1,
"max_passengers": 3,
"luggage": 3,
"carryon": 3,
"models": "Mercedes E-Class",
"badge": null
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 4,
"has_more": false
}
}GET/extrasGli extra prenotabili (seggiolini, bagagli, attrezzatura): extra_type_id, prezzo, flag gratuito, quantità massima è unita di spazio bagagliaio che il motore applica.catalog:read
Gli extra prenotabili (seggiolini, bagagli, attrezzatura): extra_type_id, prezzo, flag gratuito, quantità massima è unita di spazio bagagliaio che il motore applica.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
lang, page, per_page | query | mixed | Lingua di visualizzazione + paginazione standard. |
curl https://tuodominio.it/connect/api/v1/extras \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"extra_type_id": 10,
"name": "Baby seat (0-13 kg)",
"category": "child_safety",
"child_related": true,
"free": true,
"price": null,
"max_quantity": 2,
"qty_basis": "per_booking",
"space_units": 0
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 7,
"has_more": false
}
}GET/toursI tour attivi del sito con le loro varianti e prezzi, e l'URL pubblico di ogni pagina tour.catalog:read
I tour attivi del sito con le loro varianti e prezzi, e l'URL pubblico di ogni pagina tour. sale_mode indica come un tour viene venduto: "book" (online, tramite l'endpoint di disponibilità e il checkout) oppure "request" (solo su richiesta: nessuna disponibilità, nessun prezzo online).
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
lang, page, per_page | query | mixed | Lingua di visualizzazione + paginazione standard. |
curl https://tuodominio.it/connect/api/v1/tours \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 5,
"slug": "wine-tour",
"title": "Wine Tour",
"subtitle": "A day among the vineyards",
"category": "food_wine",
"tour_type": "private",
"sale_mode": "book",
"duration_minutes": 480,
"min_participants": 2,
"max_participants": 8,
"url": "https://tuodominio.it/tours/wine-tour",
"options": [
{
"id": 11,
"name": "Full day",
"price_model": "per_group",
"price_group": "550.00",
"duration_minutes": 480
}
]
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 3,
"has_more": false
}
}GET/shuttlesLe navette condivise attive del sito (servizi a posto singolo, venduti sul sito su /shuttle): evento, modalità di pickup, regole sul numero di passeggeri, cutoff d'imbarco, la tariffa minima a persona per tratta (price_from, null se non c'è ancora un prezzo), l'URL della pagina pubblica, le origini servite (fermate fisse o zone porta a porta, ognuna un fare_id con il proprio stato) e la destinazione.catalog:read
Le navette condivise attive del sito (servizi a posto singolo, venduti sul sito su /shuttle): evento, modalità di pickup, regole sul numero di passeggeri, cutoff d'imbarco, la tariffa minima a persona per tratta (price_from, null se non c'è ancora un prezzo), l'URL della pagina pubblica, le origini servite (fermate fisse o zone porta a porta, ognuna un fare_id con il proprio stato) e la destinazione. ?lang= sceglie la lingua di visualizzazione. Le prenotazioni shuttle si leggono con GET /bookings e service_type "shuttle"; la v1 non ha endpoint di scrittura shuttle - i posti si vendono nel checkout del sito.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
lang, page, per_page | query | mixed | Lingua di visualizzazione + paginazione standard. |
curl https://tuodominio.it/connect/api/v1/shuttles \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 1,
"slug": "navetta-monsterland-2026",
"name": "Navetta Monsterland 2026",
"status": "active",
"event": {
"id": 2,
"name": "Halloween Imola 2026",
"starts_on": "2026-10-31",
"ends_on": "2026-11-01"
},
"pickup_mode": "stops",
"min_pax_per_booking": 2,
"max_pax_per_booking": 16,
"boarding_cutoff_min": 15,
"price_from": "20.00",
"url": "https://tuodominio.it/shuttle/navetta-monsterland-2026",
"origins": [
{
"fare_id": 7,
"type": "stop",
"name": "Faenza - Stazione FS",
"status": "active"
},
{
"fare_id": 8,
"type": "zone",
"name": "Castel San Pietro Terme",
"status": "active"
}
],
"destination": {
"stop_id": 5,
"name": "Imola - Hub Evento Autodromo"
}
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"has_more": false
}
}Disponibilità
GET/tours/{slug}/availabilityDisponibilità in tempo reale di un tour, dallo stesso motore del checkout: non mostra mai uno slot che il passaggio di conferma rifiuterebbe.availability:read
Disponibilità in tempo reale di un tour, dallo stesso motore del checkout: non mostra mai uno slot che il passaggio di conferma rifiuterebbe. ?month=YYYY-MM risponde con una griglia per giorno (available / sold_out / closed con conteggio slot e posti; un mese completamente chiuso include anche next_open, la prossima data in cui il calendario riapre, oppure null); ?date=YYYY-MM-DD risponde con gli orari prenotabili per variante, con i posti rimasti. Un tour su richiesta (sale_mode "request") risponde 409 tour_not_bookable.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
slugobbligatorio | percorso | string | Lo slug del tour (GET /tours). |
month | query | string | YYYY-MM: serve month oppure date. |
date | query | string | YYYY-MM-DD: serve month oppure date. |
option | query | integer | Un id variante da GET /tours; 0 o assente significa qualsiasi variante. |
curl "https://tuodominio.it/connect/api/v1/tours/wine-tour/availability?date=2026-08-12" \
-H "Authorization: Bearer tsk_live_..."{
"data": {
"tour_id": 5,
"slug": "wine-tour",
"date": "2026-08-12",
"window": {
"first": "2026-07-30",
"last": "2027-01-26"
},
"options": [
{
"option_id": 11,
"slots": [
{
"time": "09:00",
"seats_left": 8,
"sold_out": false
}
]
}
]
}
}GET/shuttles/{slug}/runsDisponibilità in tempo reale delle corse di una navetta, dallo stesso motore usato dal checkout del sito: non mostra mai una corsa che il passaggio di conferma rifiuterebbe.availability:read
Disponibilità in tempo reale delle corse di una navetta, dallo stesso motore usato dal checkout del sito: non mostra mai una corsa che il passaggio di conferma rifiuterebbe. Senza ?date= risponde con le prossime date di servizio per direzione (out / ret), ognuna con il numero di corse vendibili. Con ?date=YYYY-MM-DD risponde con le corse di quel giorno: orario fisso o fascia oraria, l'orario definitivo una volta fissato, capienza, posti rimasti, lo stato derivato (available / nearly_full / sold_out), il flag confirming (partenza sotto il minimo, ancora in raccolta) e confirmed (partenza confermata), e le tariffe a persona adulto e bambino. ?direction= restringe a una direzione. Una navetta sconosciuta o non attiva risponde 404 shuttle_not_found.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
slugobbligatorio | percorso | string | Lo slug della navetta (GET /shuttles). |
date | query | string | YYYY-MM-DD: il giorno di cui elencare le corse. Assente = la mappa delle date per direzione. |
direction | query | string | "out" (verso la destinazione) o "ret" (il ritorno). Assente = entrambe. |
curl "https://tuodominio.it/connect/api/v1/shuttles/navetta-monsterland-2026/runs?date=2026-10-31&direction=out" \
-H "Authorization: Bearer tsk_live_..."{
"data": {
"shuttle_id": 1,
"slug": "navetta-monsterland-2026",
"date": "2026-10-31",
"runs": [
{
"id": 10,
"fare_id": 7,
"direction": "out",
"timing_mode": "window",
"depart_time": null,
"window_start": "15:00",
"window_end": "17:00",
"final_time": null,
"capacity_max": 8,
"min_seats": 2,
"seats_left": 6,
"state": "available",
"confirming": true,
"confirmed": false,
"fare": {
"adult": "25.00",
"child": "25.00"
}
},
{
"id": 11,
"fare_id": 7,
"direction": "out",
"timing_mode": "window",
"depart_time": null,
"window_start": "17:00",
"window_end": "19:00",
"final_time": null,
"capacity_max": 8,
"min_seats": 2,
"seats_left": 0,
"state": "sold_out",
"confirming": false,
"confirmed": true,
"fare": {
"adult": "25.00",
"child": "25.00"
}
}
]
}
}GET/schedule-blocksI blocchi calendario dell'operatore: finestre di date in cui le prenotazioni transfer sono bloccate o limitate (block_type, finestra oraria giornaliera opzionale, max_bookings opzionale). Utile prima di proporre una data di pickup.availability:read
I blocchi calendario dell'operatore: finestre di date in cui le prenotazioni transfer sono bloccate o limitate (block_type, finestra oraria giornaliera opzionale, max_bookings opzionale). Utile prima di proporre una data di pickup.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
from_date | query | string | YYYY-MM-DD: solo i blocchi che toccano questa data o successive. |
to_date | query | string | YYYY-MM-DD: solo i blocchi che toccano questa data o precedenti. |
page, per_page | query | integer | Paginazione standard. |
curl "https://tuodominio.it/connect/api/v1/schedule-blocks?from_date=2026-08-01" \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 36,
"date_start": "2026-08-15",
"date_end": "2026-08-16",
"time_start": null,
"time_end": null,
"time_mode": "daily",
"block_type": "blocked",
"max_bookings": null,
"reason": "Ferragosto",
"created_at": "2026-07-22 00:49:26"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"has_more": false
}
}Clienti
GET/customersElenco del registro clienti dell'operatore. Filtri: email (esatta), search (nome, azienda, email, telefono), updated_since, paginazione.customers:read
Elenco del registro clienti dell'operatore. Filtri: email (esatta), search (nome, azienda, email, telefono), updated_since, paginazione.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
email | query | string | Corrispondenza email esatta. |
search | query | string | Cerca in nome, azienda, email o telefono. |
updated_since | query | string | Timestamp ISO 8601; l'ordinamento passa a updated_at crescente. |
page, per_page | query | integer | Paginazione standard. |
curl "https://tuodominio.it/connect/api/v1/customers?search=rossi" \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 88,
"type": "private",
"first_name": "Mario",
"last_name": "Rossi",
"email": "mario.rossi@example.com",
"phone": "+39333000000",
"language": "it",
"created_at": "2026-06-01 10:00:00"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 1,
"has_more": false
}
}GET/customers/{id}Un cliente tramite id.customers:read
Un cliente tramite id.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
idobbligatorio | percorso | integer | L'id del cliente. |
curl https://tuodominio.it/connect/api/v1/customers/88 \
-H "Authorization: Bearer tsk_live_..."{
"data": {
"id": 88,
"type": "private",
"first_name": "Mario",
"last_name": "Rossi",
"email": "mario.rossi@example.com",
"phone": "+39333000000",
"language": "it",
"vat_number": null,
"created_at": "2026-06-01 10:00:00"
}
}POST/customersCrea un cliente. Almeno uno tra first_name, last_name e company_name. Un cliente attivo che già possiede l'email risponde 409 customer_email_taken; uno eliminato viene ripristinato.customers:write
Crea un cliente. Almeno uno tra first_name, last_name e company_name. Un cliente attivo che già possiede l'email risponde 409 customer_email_taken; uno eliminato viene ripristinato.
accetta Idempotency-Key
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
type | corpo | string | "private" (default), "business", "association" (APS, ASD, onlus: company_name + tax_code, vat_number facoltativa; se italiana sdi_code "0000000"), "ncc" (azienda NCC che acquista servizi) o "airline". In lettura può valere anche agency, hotel, apartment o collaborator. |
first_name, last_name, company_name, email, phone, language, vat_number, tax_code, sdi_code, pec_email, billing_* | corpo | string | I campi del registro; billing_country è un codice ISO. |
curl -X POST https://tuodominio.it/connect/api/v1/customers \
-H "Authorization: Bearer tsk_live_..." \
-H "Content-Type: application/json" \
-d '{"first_name": "Mario", "last_name": "Rossi", "email": "mario.rossi@example.com"}'{
"data": {
"id": 89,
"type": "private",
"first_name": "Mario",
"last_name": "Rossi",
"email": "mario.rossi@example.com",
"created_at": "2026-07-30 15:20:00"
}
}PATCH/customers/{id}Modifica un cliente: le chiavi assenti restano invariate; stessa regola di collisione email della POST.customers:write
Modifica un cliente: le chiavi assenti restano invariate; stessa regola di collisione email della POST.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
idobbligatorio | percorso | integer | L'id del cliente. |
curl -X PATCH https://tuodominio.it/connect/api/v1/customers/88 \
-H "Authorization: Bearer tsk_live_..." \
-H "Content-Type: application/json" \
-d '{"phone": "+39334000000"}'{
"data": {
"id": 88,
"first_name": "Mario",
"last_name": "Rossi",
"phone": "+39334000000"
}
}Autisti e flotta
GET/driversIl registro autisti dell'operatore, per un'integrazione di dispatch: nome, contatti, numero patente, colore calendario, stato, e l'id partner per gli autisti forniti da un partner.drivers:read
Il registro autisti dell'operatore, per un'integrazione di dispatch: nome, contatti, numero patente, colore calendario, stato, e l'id partner per gli autisti forniti da un partner.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
page, per_page | query | integer | Paginazione standard. |
curl https://tuodominio.it/connect/api/v1/drivers \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 30,
"type": "own",
"first_name": "Luca",
"last_name": "Bianchi",
"email": "luca@example.com",
"phone": "+39333000000",
"licence_number": null,
"colour": "#2563eb",
"status": "active",
"partner_id": null,
"created_at": "2026-07-18 18:53:56",
"updated_at": "2026-07-18 18:53:56"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 4,
"has_more": false
}
}GET/fleetI veicoli reali dell'operatore (marca, modello, targa, posti, bagagli, proprietà, stato) - non le classi prenotabili, che sono GET /vehicle-classes. vehicle_class_id collega un'auto alla classe che serve.fleet:read
I veicoli reali dell'operatore (marca, modello, targa, posti, bagagli, proprietà, stato) - non le classi prenotabili, che sono GET /vehicle-classes. vehicle_class_id collega un'auto alla classe che serve.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
page, per_page | query | integer | Paginazione standard. |
curl https://tuodominio.it/connect/api/v1/fleet \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 12,
"make": "Mercedes",
"model": "Classe V",
"plate": "GA123XY",
"year": null,
"colour": null,
"seats": 8,
"luggage": 6,
"ownership": "owned",
"status": "active",
"vehicle_class_id": 7,
"created_at": "2026-07-18 18:53:56",
"updated_at": "2026-07-18 18:53:56"
}
],
"meta": {
"page": 1,
"per_page": 25,
"total": 2,
"has_more": false
}
}Webhook
GET/webhooksElenco delle sottoscrizioni webhook di questo sito. Il secret non viene mai restituito qui: è mostrato una sola volta, nella risposta della POST.webhooks:manage
Elenco delle sottoscrizioni webhook di questo sito. Il secret non viene mai restituito qui: è mostrato una sola volta, nella risposta della POST.
curl https://tuodominio.it/connect/api/v1/webhooks \
-H "Authorization: Bearer tsk_live_..."{
"data": [
{
"id": 3,
"url": "https://example-gestionale.com/hooks/tosiu",
"events": [
"booking.created",
"booking.cancelled"
],
"status": "active",
"last_delivery": {
"at": "2026-07-30 15:00:12",
"status": 200,
"error": null
},
"created_at": "2026-07-30 12:00:00"
}
],
"meta": {
"total": 1
}
}POST/webhooksSottoscrive un URL HTTPS pubblico agli eventi. La risposta contiene il secret di firma UNA SOLA VOLTA: conservarlo, ogni consegna è firmata con esso. Massimo 10 sottoscrizioni per sito; una per URL (eliminare per ruotare il secret).webhooks:manage
Sottoscrive un URL HTTPS pubblico agli eventi. La risposta contiene il secret di firma UNA SOLA VOLTA: conservarlo, ogni consegna è firmata con esso. Massimo 10 sottoscrizioni per sito; una per URL (eliminare per ruotare il secret).
accetta Idempotency-Key
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
urlobbligatorio | corpo | string | Un URL HTTPS pubblico. Host privati e di loopback sono rifiutati. |
eventsobbligatorio | corpo | array | Lista non vuota dal catalogo eventi qui sopra. |
curl -X POST https://tuodominio.it/connect/api/v1/webhooks \
-H "Authorization: Bearer tsk_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://example-gestionale.com/hooks/tosiu",
"events": ["booking.created", "booking.cancelled"]}'{
"data": {
"id": 3,
"url": "https://example-gestionale.com/hooks/tosiu",
"events": [
"booking.created",
"booking.cancelled"
],
"status": "active",
"secret": "whsec_9f2c4a7e1b8d3f6c5a0e7b4d9c2f1a8e",
"created_at": "2026-07-30 12:00:00"
}
}DELETE/webhooks/{id}Elimina una sottoscrizione. Le consegne in attesa vengono scartate; lo storico resta visibile nella dashboard.webhooks:manage
Elimina una sottoscrizione. Le consegne in attesa vengono scartate; lo storico resta visibile nella dashboard.
Parametri
| Nome | Dove | Tipo | Descrizione |
|---|---|---|---|
idobbligatorio | percorso | integer | L'id della sottoscrizione (GET /webhooks). |
curl -X DELETE https://tuodominio.it/connect/api/v1/webhooks/3 \
-H "Authorization: Bearer tsk_live_..."{
"data": {
"id": 3,
"deleted": true
}
}Widget per partner
Per chi non ha uno sviluppatore c'è la maschera di prenotazione da incorporare: la metti sul sito di un hotel o di un'agenzia e le loro prenotazioni arrivano a te, già attribuite a quel partner.
- Un widget per partner, con le sue tratte e i suoi prezzi
- Colori, lingua e passaggi si configurano dal pannello
- Si mette in pausa senza togliere il codice dal loro sito
<iframe src="https://tuodominio.it/connect/iframe/LA_CHIAVE_DEL_WIDGET"
width="100%" height="720" style="border:0"
title="Prenota un transfer"></iframe>Versioni e modifiche
La v1 è un contratto pubblicato: i campi si aggiungono, non spariscono e non cambiano nome. Una modifica che rompe le integrazioni diventerà una v2, e la v1 continuerà a rispondere. Le ultime aggiunte:
Il link di pagamento. I payload delle prenotazioni (letture e consegne webhook) includono
payment_link: la pagina "completa il pagamento" del cliente, valorizzata solo mentre la prenotazione è inawaiting_paymentcon un metodo online; il suo "Paga ora" riavvia il checkout del gateway, quindi lo stesso link funziona finché il pagamento non va a buon fine.Due valori additivi di
service_typesulle prenotazioni inserite dall'operatore dall'app: "disposal" (auto a disposizione) e "other" (servizio a testo libero), più la stringa opzionaleservice_labelsu ogni payload di prenotazione (letture e consegne webhook; vuota sui transfer).I payload delle prenotazioni (letture e consegne webhook) includono
pickup_sign: il nome che l'autista scrive sul cartello in aeroporto per i pickup in aeroporto (max 80), null quando l'autista usa il nome della prenotazione.Payload delle prenotazioni (letture e consegne webhook): l'oggetto vehicle porta due campi additivi, quantity (veicoli della classe scelta, 1 su ogni prenotazione precedente a questa data) e
price_per_vehicle.
Il registro completo è sulla documentazione del tuo dominio.
Come si parte
- 1Apri Integrazioni, API pubblica
Nel tuo pannello trovi chiavi, permessi, webhook e il registro delle chiamate.
- 2Crea la chiave
Dai un nome, scegli solo i permessi che servono, copia il valore: si vede una volta sola.
- 3Chiama GET /site
Ti dice lingue, valuta, metodi di pagamento e come questo sito vuole le richieste.
Il tuo sito NCC, pronto in pochi click.
Lo configuri tu, con l'AI che ti guida: non serve essere esperti. Nessun impegno, nessun rinnovo automatico.