In this volume · VOLUME 14
Appendices
Error Codes Status Codes

Appendix 14.2 — Error Codes

1. Purpose

This appendix is the canonical catalog of error codes returned by the API and surfaced in logs, validation reports, and UI dialogs. Codes are stable identifiers; their human-readable messages may evolve, but the code is the consumer-stable contract.

2. Code naming convention

<DOMAIN>_<CONDITION> — uppercase, snake_case.

  • Domain is the functional area: BOOKING, INVOICE, JE, RECON, TAX, AUTH, etc.
  • Condition is the precise failure.

Examples: BOOKING_HOLD_EXPIRED, JE_UNBALANCED, TAX_RULE_OVERLAP.

3. Severity & retry advice

Each code carries: - HTTP status when surfaced via API. - Severity: INFO / WARN / ERROR / CRITICAL. - Retry advice: non_retryable / retryable_after_short / retryable_after_long / requires_user_action.

4. Authentication & authorization

Code HTTP Severity Retry Description
AUTH_INVALID_CREDENTIALS 401 WARN requires_user_action Username/password failed
AUTH_MFA_REQUIRED 401 INFO requires_user_action MFA challenge needed
AUTH_MFA_INVALID 401 WARN requires_user_action Code didn't match
AUTH_SESSION_EXPIRED 401 INFO requires_user_action Re-authenticate
AUTH_TOKEN_INVALID 401 ERROR non_retryable Bearer token malformed / unknown
AUTH_TOKEN_REVOKED 401 ERROR non_retryable Token explicitly revoked
AUTH_TOKEN_EXPIRED 401 INFO requires_user_action Token aged out
AUTH_ACCOUNT_LOCKED 403 ERROR requires_user_action Excessive failed attempts
AUTH_PASSWORD_EXPIRED 403 INFO requires_user_action Rotation overdue
PERM_DENIED 403 ERROR non_retryable Caller lacks required permission
PERM_SCOPE_INSUFFICIENT 403 ERROR non_retryable Token's scope does not include this resource
PARTNER_MISMATCH 403 CRITICAL non_retryable Resource belongs to a different partner

5. Validation (generic)

Code HTTP Severity Description
FIELD_REQUIRED 400 WARN Required field missing
FIELD_INVALID_FORMAT 400 WARN Format failed (e.g., bad email)
FIELD_OUT_OF_RANGE 400 WARN Numeric/date out of valid range
FIELD_TOO_LONG 400 WARN String exceeds limit
FIELD_UNKNOWN_VALUE 400 WARN Enum value not recognised
BODY_MALFORMED 400 ERROR Could not parse
IDEMPOTENCY_KEY_CONFLICT 409 ERROR Same key, different body
IDEMPOTENCY_KEY_MISSING 400 WARN Required for this endpoint
RATE_LIMITED 429 INFO Retry after Retry-After
MAINTENANCE_MODE 503 INFO Platform in maintenance window

6. Booking & ticketing

Code HTTP Description
BOOKING_OFFER_NOT_FOUND 404 Offer ID unknown or expired
BOOKING_OFFER_EXPIRED 409 Offer cache TTL passed
BOOKING_HOLD_EXPIRED 409 Supplier hold lapsed
BOOKING_CUSTOMER_REQUIRED 400 No customer linked
BOOKING_INSUFFICIENT_PASSENGERS 400 Pax count mismatch
BOOKING_PRICE_CHANGED 409 Re-pricing returned a different amount
BOOKING_SCHEDULE_CHANGED 409 Underlying flight time changed
BOOKING_NOT_IN_ISSUABLE_STATE 409 State machine rejects issuance from current state
BOOKING_CREDIT_DENIED 402 Customer credit hold / over limit
BOOKING_REQUIRES_APPROVAL 202 Over threshold; pending approver
BOOKING_PAYMENT_PENDING 402 Payment not yet captured
TICKETING_TIMELIMIT_EXPIRED 409 Fare TL passed
TICKETING_VOID_WINDOW_CLOSED 409 Cannot void after window
TICKETING_SUPPLIER_ERROR 502 Supplier rejected issuance
TICKETING_SUPPLIER_TIMEOUT 504 Supplier did not respond
TICKETING_DUPLICATE_ISSUANCE 409 Already issued

7. Refunds & cancellations

Code HTTP Description
REFUND_NOT_ELIGIBLE 409 Fare rules prohibit
REFUND_AMOUNT_EXCEEDS_PAID 422 Cannot refund more than paid
REFUND_QUOTE_STALE 409 Quote older than allowed
REFUND_SUPPLIER_REJECTED 502 Supplier said no
VOID_AFTER_HOURS_WINDOW 409 Past void cutoff
EXCHANGE_FARE_DIFFERENCE_UNPAID 402 Customer must pay difference first
EXCHANGE_NOT_REISSUABLE_FARE 409 Fare type forbids reissue

8. Customers & suppliers

Code HTTP Description
CUSTOMER_DUPLICATE 409 Same identifying details exist
CUSTOMER_INACTIVE 409 Marked inactive
CUSTOMER_CREDIT_HOLD 402 Hold flag set
CUSTOMER_CREDIT_LIMIT_EXCEEDED 402 Booking would breach limit
CUSTOMER_KYC_INCOMPLETE 422 Required docs missing
CUSTOMER_SANCTIONS_HIT 451 Screening match — block & escalate
SUPPLIER_INACTIVE 409 Marked inactive
SUPPLIER_BANK_HOLD 409 Recent bank change; payout hold active
SUPPLIER_COMMISSION_RULE_NONE 422 No rule found at booking time
SUPPLIER_CREDENTIALS_INVALID 502 Auth with supplier failed

9. Journal entries & ledger

Code HTTP Severity Description
JE_UNBALANCED 422 CRITICAL Debit ≠ Credit
JE_PERIOD_CLOSED 409 ERROR Target period closed
JE_ACCOUNT_DISABLED 422 ERROR Account marked inactive
JE_NEGATIVE_AMOUNT 422 ERROR Lines must be positive (sign via DR/CR)
JE_FX_RATE_MISSING 422 ERROR No rate for foreign-currency line
JE_DIMENSION_MISMATCH 422 ERROR Account requires dimension not supplied
JE_REVERSAL_TARGET_NOT_FOUND 404 ERROR Trying to reverse non-existent JE
JE_ALREADY_REVERSED 409 ERROR Already reversed
COA_ACCOUNT_NOT_FOUND 404 ERROR Unknown account code
COA_HIERARCHY_INVALID 422 ERROR Parent/child structure broken

10. Invoicing & payments

Code HTTP Description
INVOICE_ALREADY_GENERATED 409 Booking already invoiced
INVOICE_TEMPLATE_MISSING 422 No template configured
INVOICE_NUMBER_SEQUENCE_EXHAUSTED 500 Internal — escalate
PAYMENT_AMOUNT_MISMATCH 422 Doesn't match invoice/booking
PAYMENT_CURRENCY_MISMATCH 422 Currency conflict
PAYMENT_GATEWAY_DECLINED 402 Card/method declined
PAYMENT_GATEWAY_TIMEOUT 504 Gateway no response
PAYMENT_DUPLICATE 409 Same gateway transaction id seen
PAYMENT_INVOICE_OVERAPPLIED 422 Application exceeds invoice

11. Reconciliation

Code HTTP Description
RECON_FILE_DUPLICATE 409 Same checksum imported
RECON_FILE_FORMAT_INVALID 422 Parse failed
RECON_OPENING_BALANCE_MISMATCH 422 Doesn't continue from prior closing
RECON_MANUAL_MATCH_CONFLICT 409 Chosen pair already matched
RECON_VARIANCE_EXCEEDS_THRESHOLD 422 Requires manual review
RECON_PERIOD_CLOSED 409 Adjustment hits closed period

12. Tax

Code HTTP Description
TAX_RULE_OVERLAP 422 Two rules of same priority match
TAX_RATE_INVALID 422 Negative or >100%
TAX_JURISDICTION_NOT_SUPPORTED 422 Partner not configured
TAX_RULE_MISSING 422 Required rule absent for booking
TAX_RETURN_PERIOD_OVERLAP 409 Already filed

13. Period close

Code HTTP Description
PERIOD_PRECLOSE_GATE_FAILED 422 Unsatisfied items
PERIOD_TRIAL_BALANCE_UNBALANCED 422 Critical — cannot close
PERIOD_CLOSE_SAME_USER 403 Maker = Checker
PERIOD_REOPEN_LOCKED 409 Locked; cannot reopen
PERIOD_FUTURE_CLOSE 422 Period not yet ended

14. Memos (ADM/ACM)

Code HTTP Description
MEMO_NOT_FOUND 404 Unknown memo
MEMO_DISPUTE_WINDOW_CLOSED 409 Cannot dispute now
MEMO_ALREADY_SETTLED 409 Lifecycle terminal
MEMO_LINK_TARGET_INVALID 422 Cannot link to that ticket

15. Recognition & commission

Code HTTP Description
RECOGNITION_BOOKING_NO_SERVICE_DATE 422 Missing service_date
RECOGNITION_DOUBLE_ATTEMPT 409 Idempotency stopped re-entry
RECOGNITION_PERIOD_CLOSED 409 Cannot recognise into closed period
COMMISSION_RATE_INVALID 422 Out of range
COMMISSION_RECALL_AMOUNT_MISMATCH 422 Recall ≠ accrual
COMMISSION_VARIANCE_EXCESSIVE 422 Above auto-resolve threshold

16. BSP / ARC

Code HTTP Description
BSP_FILE_HEADER_INVALID 422 Malformed header
BSP_FILE_DUPLICATE 409 Same checksum
BSP_FILE_AGENT_CODE_MISMATCH 422 Code ≠ partner accreditation
BSP_FILE_TOTAL_MISMATCH 422 Trailer total ≠ line sum
BSP_ORPHAN_RATE_HIGH 422 Operational concern

17. Imports

Code HTTP Description
IMPORT_FILE_DUPLICATE 409 Same checksum
IMPORT_FILE_TOO_LARGE 413 Exceeds limit
IMPORT_ENCODING_INVALID 422 Not UTF-8
IMPORT_SCHEMA_MISMATCH 422 Headers don't match
IMPORT_PARTNER_MISMATCH 422 Wrong partner

18. Integrations / supplier

Code HTTP Description
SUPPLIER_UNAVAILABLE 503 Outage
SUPPLIER_SCHEDULE_CHANGED 409 Underlying flight changed
SUPPLIER_RATE_LIMITED 503 Supplier-side throttle
SUPPLIER_RESPONSE_MALFORMED 502 Couldn't parse
WEBHOOK_URL_INVALID 422 Non-HTTPS / unreachable
WEBHOOK_SIGNATURE_MISMATCH 401 Signature failed verification

19. Internal / platform

Code HTTP Description
INTERNAL_ERROR 500 Unexpected; logged
DB_DEADLOCK_RETRY 503 Caller can retry
CACHE_MISS_HARD 503 Required cache entry missing
WORKER_TIMEOUT 504 Background job timed out
FEATURE_NOT_ENABLED 403 Feature flag off for partner

20. Consumer guidance

For API consumers: - Always switch on the code, not the message. Messages may localise. - Tolerate unknown codes. New codes may be introduced; treat as INTERNAL_ERROR defensively. - Respect retry_advice. Don't hammer. - Surface the request_id in support tickets.