Enquiries Channel manager Bookings Your website Booking engine Pricing
v2026-09

Errors

Every error this API returns. Branch on code, never on message — codes are part of the contract, messages are written for people and may be reworded.

The failure shape

json
{
    "success": false,
    "code": "UNIT_INACTIVE",
    "message": "units.0 refers to a unit that is no longer sellable.",
    "errors": {
        "units.0": {
            "inventory_id": 31,
            "is_active": false
        }
    }
}

errors is present only when there is structured detail to give. Its shape depends on the code and is documented per code below.

All codes

Status Code Meaning
422 VALIDATION_FAILED The request body failed validation. errors is Laravel's field bag: an object keyed by field path, each holding an array of messages.
422 IDEMPOTENCY_KEY_REQUIRED POST /bookings was sent without a usable Idempotency-Key header.
422 IDEMPOTENCY_KEY_REUSED The key has already been used, with a different request body. Doorloom fingerprints the body (SHA-256 over key-sorted JSON), so key order does not matter but any value change does.
409 IN_PROGRESS An identical request is still being processed. Two requests raced; the first one is still inside its transaction.
422 PROPERTY_NOT_MAPPED The property reference is missing, unknown, or outside your integration's coverage. Coverage is set by Doorloom staff and only ever includes properties the brand owner owns outright, never cohosted ones.
422 PROPERTY_ARCHIVED The property exists and is covered, but the host has archived it. Archived properties are off-market and cannot take bookings.
422 UNIT_NOT_MAPPED A units[] line names a unit alias Doorloom does not know, or one that belongs to a different property.
422 UNIT_INACTIVE The unit is mapped but no longer sellable — deactivated or deleted by the host.
409 UNAVAILABLE There is no free unit for the whole stay, or a unit you pinned is taken. Nothing was written. Doorloom never silently swaps a pinned unit for another.
409 BOOKING_CANCELLED A cancelled booking is terminal. It cannot be modified or un-cancelled.
412 REVISION_MISMATCH You sent If-Match and the booking has changed since you read it. The revision increments on every change, including host-side edits made in the Doorloom app.
429 SYNC_TOO_SOON A full re-sync was requested too recently. One is allowed every 24 hours.
429 RATE_LIMITED You exceeded one of the rate limits. The standard Retry-After and X-RateLimit-* headers are set on the response.
404 NOT_FOUND No such booking or property for this integration. Another integration's booking is not found rather than forbidden, so ids cannot be probed across partners.
401 UNAUTHENTICATED No API key, or a key that is not valid. Rotating your API key invalidates the previous one immediately.
403 NOT_INTEGRATION_TOKEN The bearer token is valid but is not an integration API key — it belongs to another Doorloom token surface. Integration keys are the only credential this API accepts.
403 INTEGRATION_DISABLED Doorloom staff disabled this integration. No events are recorded and no API call succeeds. This is distinct from paused: a paused integration keeps full API access and only stops receiving webhooks.

Retrying safely

Field Type Description
429 retry Back off for Retry-After (or errors.retry_after) seconds, then retry the same request.
409 IN_PROGRESS retry A race with your own earlier request. Retry in a few seconds.
5xx retry Retry with backoff. On a create, reuse the same Idempotency-Key so a request that actually succeeded is not duplicated.
4xx (everything else) do not retry The request is wrong, or the world is. Fix it or surface it. Retrying unchanged produces the same answer.

A refused create replays, it does not re-race

A 409 or 422 from POST /bookings is stored against your idempotency key. Retrying with the same key returns the same refusal rather than attempting the booking again. To genuinely retry after fixing the problem, use a new key.

Reference

VALIDATION_FAILED

422 The request body failed validation. errors is Laravel's field bag: an object keyed by field path, each holding an array of messages.

What to do: Read errors; each key is the dotted path of the offending field.

Messages:

  • Validation failed
  • The same unit is referenced by more than one line.
  • Unknown type '{type}'.

errors

Field Type Description
{field path} array of strings, e.g. guest.mobile, units.0.adults
units ["duplicate unit"] when two lines name the same unit

IDEMPOTENCY_KEY_REQUIRED

422 POST /bookings was sent without a usable Idempotency-Key header.

What to do: Send Idempotency-Key: <8–128 characters>. A UUID per create attempt is ideal.

Message: Send an Idempotency-Key header (8–128 characters) with every booking create.

IDEMPOTENCY_KEY_REUSED

422 The key has already been used, with a different request body. Doorloom fingerprints the body (SHA-256 over key-sorted JSON), so key order does not matter but any value change does.

What to do: Use a new key for a new booking. Reuse a key only to retry the identical request.

Message: This Idempotency-Key was already used with a different request body.

IN_PROGRESS

409 An identical request is still being processed. Two requests raced; the first one is still inside its transaction.

What to do: Retry the same request in a few seconds. A claim left in progress for 60 seconds is taken over automatically.

Messages:

  • A request with this Idempotency-Key is still being processed. Retry shortly.
  • A booking with this external id is being created. Retry shortly.

PROPERTY_NOT_MAPPED

422 The property reference is missing, unknown, or outside your integration's coverage. Coverage is set by Doorloom staff and only ever includes properties the brand owner owns outright, never cohosted ones.

What to do: Call GET /properties for the authoritative list of what you cover.

Messages:

  • Provide property.doorloom_id or property.external_id.
  • This property is not covered by your integration.
  • This property no longer exists.
  • The booking no longer references a property.
  • One or more property_ids are not covered by your integration.

errors

Field Type Description
property the reference you sent, echoed back
property_ids array of the uncovered ids, on POST /sync

PROPERTY_ARCHIVED

422 The property exists and is covered, but the host has archived it. Archived properties are off-market and cannot take bookings.

What to do: Stop selling it. A property.changed event with status: "archived" announces this.

Message: This property is archived and cannot be booked.

errors

Field Type Description
property {"doorloom_id": 902}

UNIT_NOT_MAPPED

422 A units[] line names a unit alias Doorloom does not know, or one that belongs to a different property.

What to do: Aliases are set by Doorloom staff and published on inventory.changed and GET /properties. Re-read them, or omit the unit reference to let Doorloom allocate any free unit.

Messages:

  • units.{i}.external_unit_id is not mapped for this property.
  • units.{i} does not belong to this property.

errors

Field Type Description
units.{i} the offending line, echoed back

UNIT_INACTIVE

422 The unit is mapped but no longer sellable — deactivated or deleted by the host.

What to do: Retire the alias. inventory.changed carries inactive and deleted units with is_active and deleted flags so you can do this ahead of time.

Message: units.{i} refers to a unit that is no longer sellable.

errors

Field Type Description
units.{i} {"inventory_id": 31, "is_active": false}

UNAVAILABLE

409 There is no free unit for the whole stay, or a unit you pinned is taken. Nothing was written. Doorloom never silently swaps a pinned unit for another.

What to do: Apply errors.availability to your calendar in the same breath, then re-quote. Note its window.to is the last NIGHT, i.e. check_out minus one day.

Message: (passed through from the booking engine, naming the listing)

errors

Field Type Description
availability a per-night snapshot of the property across the stay — the same shape as an availability.changed payload, minus units[]

BOOKING_CANCELLED

409 A cancelled booking is terminal. It cannot be modified or un-cancelled.

What to do: Create a new booking. Cancelling an already-cancelled booking is not an error — that stays a 200.

Message: A cancelled booking cannot be modified.

REVISION_MISMATCH

412 You sent If-Match and the booking has changed since you read it. The revision increments on every change, including host-side edits made in the Doorloom app.

What to do: Re-read the booking, re-apply your change on top, and retry. If-Match is optional; omit it to force the write.

Message: The booking was modified since you last read it.

errors

Field Type Description
current_revision integer — the revision the booking is actually at

SYNC_TOO_SOON

429 A full re-sync was requested too recently. One is allowed every 24 hours.

What to do: Wait errors.retry_after seconds — which may be most of a day. If you are catching up on missed events, use GET /events?after_sequence= instead: it has no interval and gives you exactly what you missed.

Message: A full sync was requested {time} ago; wait {n} seconds.

errors

Field Type Description
retry_after integer seconds

RATE_LIMITED

429 You exceeded one of the rate limits. The standard Retry-After and X-RateLimit-* headers are set on the response.

What to do: Back off for Retry-After seconds. Limits are per integration, so they are yours alone to manage.

Message: Too many requests. Retry after {n} seconds.

errors

Field Type Description
retry_after integer seconds

NOT_FOUND

404 No such booking or property for this integration. Another integration's booking is not found rather than forbidden, so ids cannot be probed across partners.

What to do: Check the id, and check that the property is still covered.

Messages:

  • No such booking for this integration.
  • No booking with that external id.
  • No covered property with that id.

UNAUTHENTICATED

401 No API key, or a key that is not valid. Rotating your API key invalidates the previous one immediately.

What to do: Send Authorization: Bearer <your API key>.

Message: Send your integration API key as: Authorization: Bearer <key>.

NOT_INTEGRATION_TOKEN

403 The bearer token is valid but is not an integration API key — it belongs to another Doorloom token surface. Integration keys are the only credential this API accepts.

What to do: Use the API key Doorloom issued for this integration.

Message: This endpoint accepts integration API keys only.

INTEGRATION_DISABLED

403 Doorloom staff disabled this integration. No events are recorded and no API call succeeds. This is distinct from paused: a paused integration keeps full API access and only stops receiving webhooks.

What to do: Contact Doorloom.

Message: This integration has been disabled.

Two responses that are not in this shape

Both are outside the envelope by nature rather than by oversight, and neither comes from the application.

Field Type Description
404 with an empty body platform The Brand Integration API is switched off for the environment you are calling. Not a credential problem. Ask Doorloom.
404 HTML, or a gateway error page infrastructure You are not reaching the application at all. Check the host and path.

Something unclear or wrong on this page? Write to [email protected] and tell us which page — we would rather fix the doc than answer the ticket twice.