Error Handling

All API responses use a consistent envelope format. See Core Concepts for the full structure. This page focuses on error categories, retry strategies, and how to handle common error scenarios.

Error Categories

4xx Client Errors

Errors caused by invalid requests. Fix the request before retrying.

HTTP StatusError CodeMeaningSolution
400INVALID_REQUESTValidation failedCheck error.details for field-specific errors
400INVALID_LOCATIONInvalid location providedCheck location format or use valid locationId
400INVALID_DATE_RANGEDate range is invalidEnsure pickup is before return, dates in future
400INVALID_OFFER_TOKENToken format invalid/corruptedGet fresh offer token from search/prebook
400MISSING_REQUIRED_FIELDRequired field not providedCheck error.details for missing fields
401UNAUTHORIZEDInvalid/expired tokenRefresh API token
401AUTHENTICATION_REQUIREDMissing Authorization headerAdd Bearer token
403FORBIDDENInsufficient permissionsContact support for access
404NOT_FOUNDResource doesn't existVerify resource ID
404NO_OFFERS_AVAILABLENo offers match criteriaBroaden search dates/locations
409OFFER_EXPIREDOffer token expiredStart new search
409OFFER_EXPIREDOffer sold outShow alternative offers
409OFFER_TOKEN_ALREADY_USEDToken was already usedGet fresh offer token from search/prebook
409MISSING_REQUIRED_FIELDProvider needs additional fieldsCollect information, retry with same token
409BOOKING_FAILEDBooking could not be createdCheck error details, may need new search
422INVALID_REQUESTInvalid field valuesFix validation errors in details
429RATE_LIMIT_EXCEEDEDToo many requestsWait and retry with backoff

5xx Server Errors

Temporary server issues. Safe to retry with exponential backoff.

HTTP StatusError CodeMeaningSolution
500INTERNAL_ERRORServer errorRetry with backoff
500PROVIDER_ERRORProvider returned errorRetry with backoff
501OPERATION_NOT_SUPPORTEDFeature not supportedUse alternative endpoint/provider
503SERVICE_UNAVAILABLETemporary outageRetry after delay
504TIMEOUTOperation timed outRetry with backoff

Field Validation Errors

When you receive an INVALID_REQUEST, the error.details object contains field-specific issues that you can map directly to your form fields:

{
  "success": false,
  "error": {
    "code": "INVALID_REQUEST",
    "message": "Request validation failed",
    "details": {
      "origin.dateTime": "Must be in the future",
      "destination.dateTime": "Must be after origin time"
    }
  }
}

Parse the keys in error.details to identify which fields need correction and display inline validation messages to the user. Do not retry until the user has fixed the input.

Retry Strategy

Network errors, 5xx server errors, and 429 rate limit responses are safe to retry. Use exponential backoff starting at 1 second and doubling with each attempt (1s, 2s, 4s, 8s), with a maximum of 3-5 retries. Add a small random jitter (0-1 second) to each wait to prevent thundering herd effects when multiple clients retry simultaneously. The MISSING_REQUIRED_FIELD error is also retryable after you have collected the required fields from the user.

Do not retry authentication errors (401, 403), validation errors (400, 422), not found errors (404), or business logic errors like OFFER_EXPIRED and OFFER_TOKEN_ALREADY_USED. These require either fixing the request, obtaining fresh data, or informing the user.

Common Scenarios

Expired Offer Token

When you receive OFFER_EXPIRED, the user took too long to complete the booking flow and the token's validity window has passed. Do not retry with the same token. Instead, guide the user back to search with a message like "This offer has expired. Please search again for current availability and pricing." Displaying the usableUntil timestamp as a countdown in your UI can help users complete the flow before expiration.

Offer Token Already Used (Idempotency)

The OFFER_TOKEN_ALREADY_USED error means a booking was already successfully created with this token. This is the API's built-in idempotency mechanism — each prebooked offer token can only produce one booking.

Important

This error only occurs if a booking was already created. If previous requests failed with network or server errors, the token is still valid and you can safely retry.

This commonly happens when a network timeout occurs during booking creation but the booking actually succeeded on the server, or when the user accidentally submits the form twice. When you receive this error, query the bookings endpoint to retrieve the booking details and show the user their confirmation. Display a message like "A booking has already been created. Please check your bookings or contact support with request ID: {requestId}."

For handling booking failures in general: retry with the same token on network/server errors (5xx, timeout), check the bookings endpoint on OFFER_TOKEN_ALREADY_USED, and obtain a fresh token from search/prebook on OFFER_EXPIRED or other errors.

Offer No Longer Available

The OFFER_EXPIRED error indicates another user booked the last available option. Show alternative offers from the existing search results if available, or suggest the user search again with nearby locations or adjusted dates. A message like "This option is no longer available. Here are similar alternatives..." provides a good experience.

Rate Limiting

When RATE_LIMIT_EXCEEDED is returned, check the X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset response headers to determine when you can retry. If these headers are absent, fall back to exponential backoff. Caching search results locally helps reduce API call volume and avoid hitting rate limits. Show users a message like "Please wait a moment before searching again."

Additional Information Required

The MISSING_REQUIRED_FIELD error means a provider needs data that was not part of the initial request. The error.details.requiredFields array describes what is needed, with each entry specifying a field name, type (boolean or string), label, and message.

{
  "success": false,
  "error": {
    "code": "MISSING_REQUIRED_FIELD",
    "message": "Additional information needed",
    "details": {
      "requiredFields": [
        {
          "field": "MULTIPLE_BOOKINGS_CONFIRMATION",
          "type": "boolean",
          "label": "Confirm multiple bookings",
          "message": "More than one booking on one card. Accept?"
        },
        {
          "field": "FLIGHT_NUMBER",
          "type": "string",
          "label": "Flight number",
          "message": "Please provide your arrival flight number"
        }
      ],
      "retryable": true
    }
  }
}

For boolean fields, display a checkbox or confirmation prompt with the message. For string fields, display a text input with the label. Once you have collected the information, retry the request with the same prebookedOfferToken plus the additional data. The prebook reservation remains valid during this process. Common examples include confirming multiple bookings on a single customer card (Stadtmobil), providing a flight number for airport pickups, or supplying a driver license number for certain vehicle classes.

Timeout Handling

Different operations have different latency characteristics due to the multi-provider architecture:

OperationExpected DurationRecommended Timeout
Search1-20 seconds25 seconds
Offer Details2-5 seconds10 seconds
Prebook3-8 seconds15 seconds
Create Booking5-15 seconds30 seconds

Show loading indicators with a spinner during long operations, especially searches and booking creation.

Logging

Log every error response together with the meta.requestId, the error code and message, what the user was trying to do, and any relevant booking or offer IDs. When contacting support, include the requestId along with the error code, the user's action, and a timestamp — this allows us to trace the request through our systems quickly.