ChatBedsDevelopers
Resources

Errors

Every status code the partner API and the OAuth endpoints answer with, what it means, and what to do about it.

The API uses ordinary HTTP status codes. A 2xx means it worked; anything else carries a JSON body that says why.

The error body

Most errors carry a sentence in detail, written so you can log it or show it to the hotel:

409 Conflict
{
  "detail": "The price has changed: the total is now USD 180.00."
}

A 422 carries a list instead, one entry per field problem. loc is where the problem is:

422 Unprocessable Entity
{
  "detail": [
    { "loc": ["body", "departure"], "msg": "Field required", "type": "missing" },
    { "loc": ["body", "guest"], "msg": "Field required", "type": "missing" }
  ]
}

Check the type of detail before you read it: string or array.

Status codes

StatusMeaningWhat to do
200, 201Worked. 201 when a reservation was made
400The request is well formed but can't be done as asked: a past arrival, too much paid, card payments not set upRead detail. Retrying the same request gives the same answer
401No credential, or one that is wrong, revoked or expiredRefresh the access token, or ask for a new key. Don't retry as is
402The hotel's plan doesn't include this (card payment links)Hide the feature for this hotel
403The app's connection doesn't have the scope, or the hotel's account isn't activeAsk the hotel to connect again with the scope; see Scopes
404Not found, or not this credential's propertyCheck the ID and which property the credential is for
409Conflicts with the current state: price changed, duplicate external_ref, booking cancelled, an Idempotency-Key still in progressRead detail; usually show the guest something new
422A field is missing or the wrong shape, or an Idempotency-Key was reused for a different requestFix the request
429Too many callsWait Retry-After seconds; see Rate limits
502Stripe refused or didn't answer (payment links only)Nothing was made. Retry later
503The partner API is paused for this hotel or for everyoneWait Retry-After seconds (600)
500Something broke on our sideRetry with the same Idempotency-Key; tell us if it lasts

Errors you will meet

StatusdetailWhen
401A valid API key or access token is needed: Authorization: Bearer cbk_... or cbat_...No Authorization header, or a wrong, revoked or expired credential
403This connection was not allowed 'reservations:write'. Ask the hotel to connect the app again with that scope.The app token lacks the scope
403This hotel's ChatBeds account is not active.The hotel's account is suspended or closed
404Reservation not foundUnknown ID, or another property's booking
404Property not foundThe path's property_id is not the credential's property
409The price has changed: the total is now USD 180.00.expected_total no longer matches. Nothing was booked
409A booking with external_ref BK-104233 already exists (a589df05-30ad-4ee5-9832-16ff6c2c1d0e).You already booked this external_ref. Fetch it rather than booking again
409A request with this Idempotency-Key is already being processed.Two requests with one key at the same moment. Wait and retry
422This Idempotency-Key was used for a different request.Same key, different body or path
400Idempotency-Key must be 1 to 255 characters.
400Card payments are not set up for this hotel. An owner connects Stripe on the Finance page.No Stripe; don't offer card payment
429Too many calls for this key (at most 120 a minute). Wait 12 seconds and try again.Over the rate limit

Each operation in the API reference lists its own errors.

OAuth errors

The /oauth/* endpoints answer as RFC 6749 says: error is a fixed code, error_description says why.

401 Unauthorized
{
  "error": "invalid_client",
  "error_description": "Unknown client, or wrong client secret."
}
Statuserrorerror_description
401invalid_clientUnknown client, or wrong client secret. or This app is suspended.
400invalid_grantThe code is unknown, used or expired. Start the connection again.
400invalid_grantredirect_uri must be the one sent to /oauth/authorize.
400invalid_grantcode_verifier does not match the code_challenge.
400invalid_grantThe hotel disconnected the app.
400invalid_grantThis refresh token was already used. All tokens for this connection were stopped.
400invalid_grantThe connection was ended or the refresh token expired. Connect again.
400unsupported_grant_typegrant_type is authorization_code or refresh_token.
429slow_downToo many requests. Wait N seconds.

invalid_grant on a refresh means the connection is over: mark it disconnected in your app and ask the hotel to connect again. See OAuth.

Retrying safely

StatusRetry?
429, 503Yes, after Retry-After
500, 502, a timeout, a dropped connectionYes, with backoff and the same Idempotency-Key
409 (key in progress)Yes, after a second or two
Any other 4xxNo: change the request first

With an Idempotency-Key, a retry of a write that did go through returns the first answer instead of doing it twice. See Idempotency.

Building something?

On this page