Troubleshooting the APIs
The errors the booking API, GraphQL and the MCP server answer with, what each one means and what to do about it.
Reference7 min read
Every error from the booking API has the same shape. The message is written so you can show it to a traveller as it is:
{ "error": { "code": "conflict", "message": "Only 2 places are left on this departure" } }GraphQL puts the same message in errors, with the code under extensions.code. See GraphQL for its own codes, such as query_too_deep.
Calls from the browser
403 'This website isn't allowed to book here. Add it to the allowed websites in Travel Orbit's settings.'https://northwilds.com. Only the scheme, host and port count, so https://www.northwilds.com is a different website. Up to 20 can be listed.Access-Control-Allow-Origin for your website.Content-Type, Authorization and X-Api-Key are allowed.403 'A key that reads drafts must stay on your server…'trv_sk_ key was sent from a browser on another website.trv_pk_ key in the browser.401 'Sign in with the code we email you' right after signing intravel.portal cookie to Travel Orbit from your website.| You see | Why | What to do |
|---|---|---|
403 'This website isn't allowed to book here. Add it to the allowed websites in Travel Orbit's settings.' | A quote, booking or portal call came from a website that isn't under Allowed websites. | An Admin adds the website under Booking settings, such as https://northwilds.com. Only the scheme, host and port count, so https://www.northwilds.com is a different website. Up to 20 can be listed. |
| A CORS error in the browser console, with no answer | The same as above: the answer has no Access-Control-Allow-Origin for your website. | As above. Reading trips works from any website. |
| A CORS error on a request with your own headers | Only Content-Type, Authorization and X-Api-Key are allowed. | Leave out other headers. |
403 'A key that reads drafts must stay on your server…' | A trv_sk_ key was sent from a browser on another website. | Call from your server, or use a trv_pk_ key in the browser. |
The portal answers 401 'Sign in with the code we email you' right after signing in | The browser doesn't send the travel.portal cookie to Travel Orbit from your website. | Call the portal endpoints from your own server and pass the cookie on. See the booking API. |
Keys and organisations
402 subscription_inactive404 'Organisation was not found'?organisation=, doesn't exist.northwilds.401 'This API key isn't valid for this organisation…'401 'This API key has been revoked…' or '…has expired…'401 'Send an API key, or name the organisation with ?organisation=…'?organisation=northwilds or a key.trv_sk_ key.404 'Trip was not found'.| You see | Why | What to do |
|---|---|---|
402 subscription_inactive | The organisation's Travel Orbit trial or plan has ended, so the booking pages and API are paused. | An owner chooses a plan under Billing in Orbit; everything answers again within a minute. Show your own "temporarily unavailable" message meanwhile. |
404 'Organisation was not found' | The booking name in the address, or in ?organisation=, doesn't exist. | Copy it from Booking settings, such as northwilds. |
401 'This API key isn't valid for this organisation…' | The key is wrong, or belongs to another organisation than the booking name. | Check the key under API keys, and that it matches the booking name. |
401 'This API key has been revoked…' or '…has expired…' | The key was revoked, or passed its expiry date. | Create a new key. A wrong key fails even on reads that need none. |
401 'Send an API key, or name the organisation with ?organisation=…' | A GraphQL request with neither. | Add ?organisation=northwilds or a key. |
| A draft trip is missing | Drafts need a trv_sk_ key. | Send a key with Read drafts, from your server. Quotes and bookings never accept draft trips: they answer 404 'Trip was not found'. |
Quotes and bookings
422 'Choose a departure', 'Add your first name', 'Add an email address we can reach you at', 'Accept the booking terms to continue'issues lists each one.400 'Add the passport number for traveller 2'travellerFields.400 'Answer "Boot size" for traveller 1'questions.400 'This trip isn't taking bookings at the moment'bookingMode is closed.400 'This departure isn't taking bookings', 'This departure is cancelled', 'This departure has already left', 'Bookings for this departure have closed'400 'This trip isn't sold in SEK'currency isn't one of the trip's currencies.400 'That code isn't valid', 'That code has expired', 'That code has been used up', 'That code is not valid for this trip'400 'Gear hire can't be added this close to departure'400 'Online payment isn't working right now. Try again in a moment, or contact us to book.'409 'This departure is full', 'Only 2 places are left on this departure'409 'Double room is sold out on this departure'409 'Those places were just taken. Choose another departure or fewer travellers.'| You see | Why |
|---|---|
422 'Choose a departure', 'Add your first name', 'Add an email address we can reach you at', 'Accept the booking terms to continue' | A field is missing or in the wrong format. issues lists each one. |
400 'Add the passport number for traveller 2' | The trip's Booking form asks for that detail. Read the trip's travellerFields. |
400 'Answer "Boot size" for traveller 1' | A required question of the trip has no answer. Read the trip's questions. |
400 'This trip isn't taking bookings at the moment' | The trip's bookingMode is closed. |
400 'This departure isn't taking bookings', 'This departure is cancelled', 'This departure has already left', 'Bookings for this departure have closed' | The departure is closed, cancelled, in the past or past its booking deadline. |
400 'This trip isn't sold in SEK' | currency isn't one of the trip's currencies. |
400 'That code isn't valid', 'That code has expired', 'That code has been used up', 'That code is not valid for this trip' | The discount code doesn't exist or doesn't apply. Other messages say it isn't active, isn't valid yet, or isn't valid for the date or currency. |
400 'Gear hire can't be added this close to departure' | The extra has a deadline before departure. |
400 'Online payment isn't working right now. Try again in a moment, or contact us to book.' | Stripe refused to start the payment. The places are released. Check the organisation's Stripe key under Stripe. |
409 'This departure is full', 'Only 2 places are left on this departure' | Fewer places than travellers. |
409 'Double room is sold out on this departure' | A package or extra has no places left. |
409 'Those places were just taken. Choose another departure or fewer travellers.' | Someone else booked the last places at the same moment. |
A booking comes back as requested
Nothing is charged and payment is null when the trip takes requests (bookingMode: "request"), or when the organisation has no working Stripe key (payments.online is false on the organisation). See Connect your Stripe account.
A booking stays held
A held booking waits for its first payment, for 15 minutes unless an Admin changed Hold places for in Booking settings (5 to 120 minutes). After stripe.confirmPayment, call POST/bookings/{reference}/check with the lead traveller's email: it asks Stripe and confirms the booking if the payment went through. If nobody pays in time, the booking becomes expired and the places go back on sale. Don't make a second booking: let the traveller try again with the same clientSecret.
The traveller account
{ "sent": true } but no email arrives400 'That code isn't right. Check the email and try again.'400 'That code has expired. Ask for a new one.'400 'Nothing is due on this booking'400 'This booking can't take payments'400 'Pay once by card first, and we will use that card for the next payments'400 'This trip has already started, so the details can't be changed here'| You see | Why |
|---|---|
{ "sent": true } but no email arrives | Codes are only sent to an email that made a confirmed, requested or cancelled booking, and at most once every 45 seconds. |
400 'That code isn't right. Check the email and try again.' | A wrong code. After 5 wrong tries the code stops working. |
400 'That code has expired. Ask for a new one.' | Codes last 10 minutes. |
400 'Nothing is due on this booking' | Every payment is made. |
400 'This booking can't take payments' | Only confirmed bookings take payments. |
400 'Pay once by card first, and we will use that card for the next payments' | Automatic payments need a saved card. |
400 'This trip has already started, so the details can't be changed here' | Travellers can change their details only before departure. |
Rate limits
429 with 'Too many tries. Wait a minute and try again.' (GraphQL: 'Too many requests…') means one address made too many requests in a short time. The limits per address and organisation are in the booking API. If your server calls on behalf of many visitors, all its calls share its address, so cache reads on your side.
The MCP server
401 'Connect the assistant to Travel Orbit again'403 'The person who connected this assistant no longer has Travel Orbit in the organisation'update_trip_text would have changed a price or terms.invalid_redirect_uri 'Give up to ten https addresses, or http on localhost'invalid_client_metadata 'Only public clients using PKCE are supported'invalid_grant 'The code has expired or was used', 'The code verifier does not match', 'Sign in again'| You see | Why |
|---|---|
401 'Connect the assistant to Travel Orbit again' | The token is missing, wrong or expired and couldn't be renewed. Connect again from the assistant. |
403 'The person who connected this assistant no longer has Travel Orbit in the organisation' | Their access was removed in Orbit. |
| 'Your Travel Orbit role doesn't allow that. Ask an admin of your organisation.' | A Viewer used a tool that writes. Editors and Admins can. |
| 'Assistants can't change prices, payment plans, discount codes or cancellation terms…' | update_trip_text would have changed a price or terms. |
invalid_redirect_uri 'Give up to ten https addresses, or http on localhost' | The client registered an address that isn't allowed. |
invalid_client_metadata 'Only public clients using PKCE are supported' | The client asked for a client secret. |
invalid_grant 'The code has expired or was used', 'The code verifier does not match', 'Sign in again' | The sign-in took longer than a minute, the PKCE verifier is wrong, or the refresh token expired. Start the sign-in again. |
| 'This app is not registered with Travel Orbit. Connect it again from the app.' on the sign-in page | The client registration was forgotten. The app should register again. |
Something failed on our side
500 with server_error means Travel Orbit couldn't answer. Try again in a moment. The status of every Orbit service is at docs.bifrostorbit.com/status.
Was this page helpful?