Errors

Errors

Every Hostex OpenAPI v3 response uses the same envelope:

{
  "request_id": "RT2026052115252141408b3",
  "error_code": 200,
  "error_msg": "Done.",
  "data": {}
}
  • The HTTP status is 200 even for application-level errors. Always
    branch on error_code, not on the HTTP status.
  • error_code: 200 means success. Any other value is a failure.
  • data carries the endpoint's result and is omitted when the endpoint has
    nothing to return.
  • error_msg is a short human-readable English string. Do not parse it
    programmatically — match on error_code instead.
  • request_id should be quoted in any support ticket about a specific
    failing call. Every server-side log line is keyed by it.

Error code reference

The codes mirror standard HTTP status semantics so you can map them
straight into your own client.

error_codeClassWhenWhat to do
200successThe call succeeded.—
400bad requestInput is malformed — missing required body, wrong JSON, parameter conflict (e.g. entire scope + non-empty property_ids).Fix the request; do not retry.
401authToken is missing, invalid, deleted, or has the wrong scope. Also returned by OAuth endpoints on bad client_id / client_secret / code_verifier.Re-issue / re-authorize. See Authentication.
403forbiddenYou are authenticated, but the resource is not yours — e.g. accessing a conversation thread belonging to another operator.Stop attempting; the user does not own this resource.
404not foundThe resource id does not exist (or the path is misspelled).Verify the id; do not retry.
409conflictThe action would create a duplicate (e.g. creating a tag whose name already exists).Reconcile state and retry without the duplicate.
422validationBody parsed but failed validation rules (e.g. note too long, start_date after end_date, id_required value not in enum). error_msg includes the failing field.Fix the request; do not retry.
420account / subscriptionUnderlying Hostex account problem: subscription expired, Basic edition trying to use Pro-only feature, account suspended.Do not retry. Surface the message to the host — only they can fix it in the portal.
429rate-limitPer-account, per-endpoint, per-thread, or per-token throttle hit. May also come from OAuth brute-force guard.Back off according to Retry-After header. See Rate Limits.
500serverHostex-side bug, partial outage, or upstream channel timeout.Retry with exponential backoff; if it persists, file a support ticket with request_id.
501not implementedEndpoint exists but the feature is disabled for your account (e.g. dynamic OAuth client registration when no public client is configured).Surface to the user; do not retry.
502 / 503 / 504upstreamHostex is reachable but a downstream channel (Airbnb, Booking.com, etc.) failed.Retry. If repeated, file a ticket.

Common error scenarios — recipes

"Invalid access token" on the very first call

  • Header typo: Hostex-Access-Token (note the dash), not
    Hostex_Access_Token or Hostex-Access_Token.
  • Whitespace: trim the token before sending.
  • Token revoked or rotated in the Host Portal.

"Not authorized for this action"

Your access token is read-only. Token scope is fixed at creation
time — create a new writable token in the OpenAPI Settings page and
revoke the old one.

429 on POST /conversations/{id} even though you are well under 1200/min

You hit the per-thread message throttle (Layer 3 in
Rate Limits), not the Layer 1 per-account quota. Spread sends
across threads, or drop the cadence on automated replies in the same
thread.

409 when creating a reservation tag or property tag

A tag with the same name already exists (or was soft-deleted and will
be transparently restored — try a GET /reservation_tags?keyword=…
first). Names are unique within the operator's account.

420 on every call

The host's subscription expired or downgraded to Basic. The token is
fine; the host must renew / upgrade in the Host Portal. There is
nothing your integration can do server-side.

404 on DELETE /reservation_tags/{id}

The tag is a system default tag (is_default: true), which cannot
be deleted via the API. Only custom tags belonging to the operator can
be removed. Filter on is_default in the GET /reservation_tags
response before offering "delete" in your UI.

404 on DELETE /reservations/{code}

This endpoint cancels manually created reservations only. A booking
that came from a channel (Booking.com, Agoda, Ctrip, …) is not
addressable here and returns 404 with
Only manually created reservations can be cancelled through this endpoint. — cancel it on the channel side instead. A code prefix other
than 5- tells you up front that this call cannot succeed.

This resource is no longer available. on the same route means the code
really is unknown under your account.

Both are 404: verify and stop. Do not retry — before 2026-09-08
this case was reported as 500, which our own guidance says to retry.

429 from OAuth /oauth/authorizations

Brute-force guard. After 10 failed client_secret / code_verifier
attempts in 10 minutes for a single client_id, exchange calls are
rejected for the rest of the window. Make sure your refresh-token
flow has a deduplication mutex (one in-flight refresh per token).


When to file a support ticket

Include all of the following so the on-call team can reproduce the
issue in under a minute:

  1. The request_id from the failing response body.
  2. Approximate timestamp (UTC) of the failure.
  3. The HTTP method and path called (no need to redact the path — only
    the body / headers contain secrets).
  4. Whether you authenticated with an access token or OAuth bearer
    token (do not include the token itself).
  5. Expected behaviour vs observed behaviour.