Base URL & spec
All endpoints live under /api/v1. The machine-readable OpenAPI 3.1 spec is served live — use it to generate clients/SDKs.
Base URL: /api/v1
OpenAPI: /api/v1/openapi.jsonDevelopers
A transfer quote, booking and webhook API for travel agencies, OTAs and other business customers. This page summarises authentication, endpoints, idempotency and webhook signing; the machine-readable OpenAPI spec is served live.
Open the OpenAPI spec (/api/v1/openapi.json)All endpoints live under /api/v1. The machine-readable OpenAPI 3.1 spec is served live — use it to generate clients/SDKs.
Base URL: /api/v1
OpenAPI: /api/v1/openapi.jsonEvery request needs an API key. Send it as a Bearer token in the Authorization header, or in the X-API-Key header. Keys are issued by ClickToGoo (there is no self-service sign-up) — contact us to request access.
Each key carries one or more scopes; an insufficient scope returns 403, a missing/invalid key returns 401.
Authorization: Bearer <api-key>
— or —
X-API-Key: <api-key>With an API key, create a quote, then book the vehicle-class offer you choose by sending its quoteId and offerSnapshotId. Pickup dates and times are the airport's local time (Europe/Istanbul for airports in Türkiye), at least 3 hours and at most 365 days ahead; the quote and the booking name that zone in timeZone. The full request and response schemas are in the OpenAPI spec above.
curl -X POST https://<host>/api/v1/quotes \
-H "Authorization: Bearer <api-key>" \
-H "Content-Type: application/json" \
-d '{
"airport": { "code": "IST", "side": "from" },
"origin": { "query": "Istanbul Airport" },
"destination": { "query": "Taksim, Istanbul" },
"pickup": { "date": "2027-01-15", "time": "14:30" },
"passengers": { "count": 2 },
"trip": "one_way"
}'Each endpoint enforces a per-client, per-minute limit, and each client has daily and monthly quotas that reset at 00:00 UTC on each calendar day and month. Failed or unauthenticated requests count against a separate abuse limit; successfully authenticated requests do not consume that abuse budget. Exceeding an applicable limit returns 429 with a Retry-After header.
Create a quote first (POST /api/v1/quotes) — the response contains per-vehicle-class offer snapshots. Then create a booking with the chosen snapshot (POST /api/v1/bookings). You can read, cancel, or open a payment session for a booking.
GET /api/v1/airports
POST /api/v1/quotes
GET /api/v1/quotes/{quoteId}
POST /api/v1/bookings (Idempotency-Key required)
GET /api/v1/bookings/{bookingId}
POST /api/v1/bookings/{bookingId}/cancel
POST /api/v1/bookings/{bookingId}/payment-session
GET /api/v1/webhooks
POST /api/v1/webhooks (Idempotency-Key required)
DELETE /api/v1/webhooks/{webhookId}
POST /api/v1/webhooks/{webhookId}/rotate-secretPOST /api/v1/bookings and POST /api/v1/webhooks require an Idempotency-Key header of 8–200 characters with no spaces. Replaying the same key with the same body returns the original resource with status 200 and X-Idempotency-Replayed: true (the first call returns 201). Reusing the key with a different body returns 409.
Idempotency-Key: <unique-key>Events: api.quote_created, api.booking_created, api.booking_cancelled, api.booking_completed, api.booking_pickup_amended. Manage subscriptions via /api/v1/webhooks. Listing is cursor-paginated: limit defaults to 20 (maximum 100); when hasMore is true, pass nextCursor as the next cursor value.
Signing follows the Standard Webhooks spec. Each delivery carries webhook-id, webhook-timestamp and webhook-signature headers. The signature base is the string webhook-id.webhook-timestamp.<raw-json-body>; the signature is v1,<base64(hmac_sha256)> verified with your subscription secret (whsec_...).
Protect against replays: reject deliveries whose webhook-timestamp deviates more than 5 minutes from your clock (retries are re-signed with a fresh timestamp), and deduplicate on webhook-id with a window covering the full retry horizon — up to 10 attempts over roughly 76 hours (about 3.2 days) of cumulative backoff, so keep processed ids for at least 4 days. Operator replays and fanout deliveries can reuse a webhook-id beyond that schedule, so treat a remembered id as already processed.
Rotate the signing secret without downtime via POST /api/v1/webhooks/{webhookId}/rotate-secret. The new secret is returned exactly once. For 24 hours after rotation (previousSecretExpiresAt) each delivery's webhook-signature header carries two space-delimited v1 signatures — one per secret — and the delivery is authentic if either verifies. Disabling a subscription revokes the grace secret immediately.
webhook-id: <id>
webhook-timestamp: <unix>
webhook-signature: v1,<base64(hmac_sha256)>
base = webhook-id + "." + webhook-timestamp + "." + rawBody
rotation grace: webhook-signature: v1,<new> v1,<previous>
spec: https://www.standardwebhooks.comEvery error returns the same JSON shape — a stable code plus a human-readable message. 400 validation errors add a fieldErrors map keyed by field path; 429 responses add a Retry-After header (in seconds).
{
"code": "API_QUOTE_NOT_FOUND",
"message": "Quote was not found."
}{
"code": "INVALID_API_QUOTE_REQUEST",
"message": "Check origin, destination, pickup and passenger details.",
"fieldErrors": {
"pickup.date": ["Use YYYY-MM-DD format."]
}
}We set only the cookies this site needs to work — no analytics, no advertising, no third-party trackers. Cookie Policy