Errors
Every error, on every endpoint, has the same shape:
Code
Branch on code, never on message. Codes are part of the contract;
messages are written for humans and may be reworded.
request_id
Every response carries one, and it is also written to our logs. Quote it when you contact support and we can pull up the exact request — including, if the workspace has debug capture enabled, the payload we received. It saves a round of "can you reproduce it?" every time.
Status codes
| Status | Meaning |
|---|---|
400 | The request was malformed or failed validation |
401 | Authentication failed — key missing, invalid, revoked or expired |
403 | Authenticated, but not allowed: scope, IP/origin, or revoked grant |
404 | No such resource — or it is outside the properties you were granted |
409 | Idempotency conflict, or a block over nights a stay already occupies |
429 | Rate limited |
5xx | Something broke on our side. Retry with backoff |
Codes
Authentication (401)
| Code | Meaning |
|---|---|
missing_credentials | No Authorization or X-Api-Key header |
invalid_credentials | The credential is not recognised |
key_revoked | The workspace revoked this key |
key_expired | The key passed its expiry date |
token_expired | The OAuth access token expired — refresh it and retry |
token_revoked | The OAuth access token was revoked; do not retry |
Authorisation (403)
| Code | Meaning |
|---|---|
insufficient_scope | Your effective scopes do not include what this endpoint needs |
grant_revoked | The workspace withdrew your access |
integration_suspended | Noé suspended your integration |
integration_not_approved | Your integration is not approved for API access |
app_mismatch | X-Noe-App does not match the key you authenticated with |
ip_not_allowed | Your address is not on the key's allowlist |
origin_not_allowed | Your browser origin is not on the key's allowlist |
tenant_suspended | The workspace itself is suspended |
Requests (400 / 404 / 409)
| Code | Meaning |
|---|---|
validation_failed | Payload or query parameters were rejected. See details.fields |
not_found | No such resource, or outside your property scope |
idempotency_key_required | A write arrived without Idempotency-Key |
idempotency_key_reused | That key was already used for a different payload |
idempotency_in_progress | An identical request is still being processed |
stay_conflict | A block would cover nights a stay already occupies. See details.conflicts |
Stay conflicts (409)
A block cannot be created over — or moved onto — nights that a reservation or
a long stay already occupies, on the property itself or on a property it shares
availability with. Nothing is written. details.conflicts lists what is in the
way, without any guest information:
Code
kind is reservation or mid_term; check_out is the departure day. For a
property outside your grant, property_id and reservation_id are null.
Shrinking a block, or changing only its reason, is never refused.
Which errors to retry
Retry 429 (honouring Retry-After), 5xx, and network timeouts —
timeouts are safe precisely because writes are idempotent.
Do not retry 400, 401, 403 or 404. Nothing about repeating the same
request changes the outcome; surface these so a human can fix the cause.
409 idempotency_in_progress is the exception: retry it, after a short pause.
Do not retry 409 stay_conflict: the nights stay occupied until that stay
moves or is cancelled.
Validation details
A 400 tells you which field was wrong rather than making you guess:
Code
Batch responses
Batch endpoints return 207 Multi-Status with a per-item result, because one
bad item should not discard ninety-nine good ones. Inspect every entry — the
HTTP status alone does not tell you whether anything failed.
Code

