Authentication
API keys
The API authenticates the partner, not the traveller. One credential — an API key — identifies your account, decides what you may call, and is the thing every invoice line traces back to.
Sending a key
Pass the key as a bearer token on every request. There is no session, no login call and no token exchange.
GET /v1/account HTTP/1.1
Authorization: Bearer vcb_live_7Kq2xY…
Accept: application/jsonFor the WebSocket at /v1/stream, browsers and most clients cannot set headers on the handshake, so the key travels in the subprotocol instead:
Sec-WebSocket-Protocol: vcb, vcb_live_7Kq2xY…Keys never leave your servers
Two environments
The two are not interchangeable: a test key on the live host and a live key on the sandbox host are both rejected with 401. That is deliberate — a deployment that has the wrong key configured should fail on its first call, not on its first real booking.
Scopes
Every key carries an explicit list of scopes, and every endpoint requires one. A key with no scope for a route is rejected before the request reaches any supplier.
Scopes are named <resource>:<action>. The resources follow the product areas — hotels, flights, esim — plus account for your own account and ledger, and webhooks for endpoint management. The actions are read and write:
The scopes actually granted to a key are shown on the key in the portal, and a rejected call names the one it was missing, so you never have to guess:
{
"error": {
"type": "missing_scope",
"message": "This key does not have the hotels:write scope.",
"requestId": "req_01JD8Z…",
"docUrl": "…/docs/authentication"
}
}Grant the narrowest set that does the job. A key used only by a price-comparison page should not be able to book, and a key used by a nightly reconciliation job should not be able to cancel.
IP allow lists
Each key can be pinned to a list of source addresses or CIDR ranges. A request from anywhere else is refused regardless of how valid the key is. This is the cheapest mitigation there is for a leaked credential, and it costs nothing if your egress addresses are stable.
Leave the list empty and the key is accepted from anywhere. If your egress is dynamic, prefer short-lived keys and rotation over a wide range.
Rotation
Keys are stored as a SHA-256 hash. We cannot show you an existing secret, recover one, or read one out of a log — the plaintext exists exactly once, in the response that created it. Store it in your secret manager at that moment.
- Rotating a key issues a new secret and gives the old one an expiry in the near future, so both work while you roll out. Deploy the new secret, confirm traffic has moved using the key's last-used timestamp, then let the old one lapse or revoke it early.
- Revocation is immediate: the gateway caches the key catalogue for 60 seconds but is invalidated on revoke, so a killed key stops working in under a second.
- Use separate keys per system — checkout, back office, batch jobs. One compromised component then costs you one rotation, not a coordinated one across your estate.
- Every key operation is written to an audit trail on your partner account, with the portal user who performed it.
Travellers
Your travellers do not have Vacabee accounts and never authenticate with us. You identify them with your own stable identifier in the X-Partner-Customer-Ref header; we keep the mapping so bookings, modifications and cancellations for the same traveller line up.
Use an opaque, stable reference — not an email address, not a name. When a traveller exercises a deletion request, DELETE /v1/customers/{ref} removes the traveller record on our side.