Transfers

POST/v1/transfers/orders

Book a transfer

Books at the supplier immediately — there is no hold step, so a successful answer is a real booking.

Your account is checked and reserved BEFORE the supplier is contacted, so an insufficient balance costs you nothing. externalReference is the idempotency key: repeating a request with the same value returns the same order rather than buying a second transfer, which is what makes a retry after a timeout safe.

Auth
API key
Scope
transfers:book
Rate limit
BOOKING
Search quota
Free
Idempotency
Idempotency-Key

Request headers

HeaderTypeRequiredDescriptionExample
Idempotency-KeystringRequiredMandatory on every POST. The same request with the same key returns the stored response without reaching the supplier again. The same key with a DIFFERENT body is rejected with 409 idempotency_key_reuse. Retained for 24 hours.4f1c358f-6b2e-5acb-8ef5-0c3d0bcc35f5

Request body

CreateTransferOrderDto — required, sent as application/json.

Responses

Errors

Every one of these carries the same envelope. What each error.type means, and whether a retry can succeed, is on the error index — once, for all operations.

StatusWhen
401

No key, or an invalid, revoked or expired key, or a valid key sent to the other environment. error.type tells them apart: authentication_required, invalid_api_key, api_key_revoked, api_key_expired, wrong_environment. On wrong_environment the key is fine and the base URL is not — a vcb_live_… key was sent to the sandbox host or a vcb_test_… key to the live host; error.gatewayEnvironment names the host, error.keyEnvironment the key. Do not rotate the key, change the URL.

402

The balance does not cover this operation (insufficient_funds), or the account is not active (account_not_active). Do NOT retry — the answer only changes once a top-up happens. error.availableCents and error.requiredCents name the shortfall, error.currency the account's currency.

403

The key is not allowed to do this. On insufficient_scope, error.missingScope names the missing scope; on ip_not_allowed the request came from an address outside the allowlist.

409

The same idempotency key was used with a different body (idempotency_key_reuse), or a request with this key is still in flight (idempotency_key_in_progress). The second case may be retried after a short wait.

429

Quota exhausted. Retry-After and error.retryAfter give the wait in seconds. This response MAY be retried — after the stated time.

500

A failure on our side. The requestId in the response belongs in every support request.

503

A supplier is unreachable (upstream_unavailable). May be retried, with growing backoff.

Response headers

Set on every response of this operation, successful or not.

HeaderTypeMeaning
X-RateLimit-LimitintegerUpper limit of the class that applied to this request.
X-RateLimit-RemainingintegerRemaining requests in the running window.
X-RateLimit-ResetintegerUnix time at which the window starts anew.
X-Request-Idstring (uuid)Identifier of this request. Quote it in any support request — including on a successful response, in case the outcome becomes questionable later.

Example

POST /v1/transfers/orders
curl -sS -X POST "$VACABEE_API_URL/v1/transfers/orders" \
  -H "Authorization: Bearer $VACABEE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "quoteId": "qte_9dJ2…",
  "externalReference": "<string>",
  "holder": {
    "firstName": "<string>",
    "lastName": "<string>",
    "email": "<string>",
    "phone": "+351912345678"
  }
}'

Set VACABEE_API_URL to https://api.vacabee.com with a live key, or to https://sandbox-api.vacabee.com with a vcb_test_ key. Binding a host to one kind of key is planned and is not enforced by the host yet, so nothing stops a key from being answered at the wrong base URL — assert the prefix against your configured URL yourself. What the sandbox answers

TypeScript SDK

await vacabee.transfers.book(…);

The typed method sends the right headers, derives the idempotency key where one is required, and returns the response type generated from this document. Installing and using the SDK