Skip to content

Errors

An error is a JSON problem (RFC 9457, application/problem+json) with a code that names it:

A trip that isn't on this site
Terminal window
curl "https://api.stg.vacationpackagesoman.com/v1/public/products/no-such-trip" \
-H "Tp-Publishable-Key: $TP_KEY"
Answer: 404 Not Found
{
"type": "about:blank",
"title": "Not Found",
"status": 404,
"code": "NotFound",
"detail": "No product no-such-trip.",
"entity": "product"
}
Field What it is
status The HTTP status, again.
title The status’s name, e.g. Not Found.
code What went wrong, e.g. NotFound. Switch on this.
detail A sentence for developers. Don’t show it to travellers.
type Always about:blank.

Some codes carry more fields, listed below. Switch on code, never on detail’s words, and treat a code you don’t know by its status: new codes may be added.

CodeStatusWhenWhat to do
Unauthenticated401The key is missing, wrong or revoked, or the endpoint needs a session the request doesn't carry.Send the website's key as Tp-Publishable-Key, or a secret key as Authorization: Bearer. Don't retry until it's fixed.
NotPermitted403The secret key or the staff member is known, but their role lacks the permission this needs. Carries permission, and reason: missing_permission or no_operator.Give the key's role the permission named in permission, in the portal.
OriginNotAllowed403A browser on a page whose origin the website key's site doesn't list called with that key. A call from a server, with no Origin, never gets this. Carries origin: the page's origin that was refused.Add the page's origin to the site's allowed origins in the portal (API keys, Website keys), or call from your server.
NotFound404There is no such record on this site: a trip, page, option or booking it doesn't sell or can't see. A booking with the wrong token or email is not found too, so a guess learns nothing. Carries entity: the kind of record, such as product or booking.Check the slug, id or reference. For a booking, check the token or the lead traveller's email.
Conflict409The record's state doesn't allow it now: cancelling a booking that is already cancelled, or checking out a hold that was checked out for someone else.Read the record again and act on its current state.
InvalidInput422A field is missing, has the wrong type or a value the API doesn't take.Fix the request; detail names the field.
PriceTableNotMonotonic422Seller endpoints only: a price table where one more traveller would lower the total. Carries cells: each with unit_id, tier and min_net_usd.Raise the cells listed in cells.
RateLimited429Too many tries in a short time at a sign-in link, a passkey sign-in or a contact change. Carries retry_after_seconds.Wait retry_after_seconds, then try again.
SearchUnavailable503Search is down, or not set up on this server.Fall back to the trip list (GET /v1/public/products with q), and try search again later.

A request that doesn’t fit the contract (a field missing, a wrong type, a value the API doesn’t take) is InvalidInput, and detail names the field:

A filter value the API doesn't know
Terminal window
curl "https://api.stg.vacationpackagesoman.com/v1/public/products?duration=weekend" \
-H "Tp-Publishable-Key: $TP_KEY"
Answer: 422 Unprocessable Content
{
"type": "about:blank",
"title": "Unprocessable Content",
"status": 422,
"code": "InvalidInput",
"detail": "duration takes up_to_3h, 3h_to_6h, full_day, multi_day, not weekend"
}

A quote, a hold or a checkout that can’t go ahead is a 422 with one of these codes and the facts in details (named as the API sends them):

Too many travellers for the places left
Terminal window
curl -X POST "https://api.stg.vacationpackagesoman.com/v1/public/quotes" \
-H "Tp-Publishable-Key: $TP_KEY" \
-H "Content-Type: application/json" \
-d '{
"option_id": "9e4c2a71-3b5d-4e8f-a1c6-7d20f5b93e48",
"start": "2026-11-14T15:00",
"units": [
{
"unit_id": "1c7e9b42-6a3f-4d85-b0e2-58f4a1c9d736",
"qty": 4
}
],
"currency": "USD"
}'
Answer: 422 Unprocessable Content
{
"type": "about:blank",
"title": "Unprocessable Content",
"status": 422,
"code": "NotEnoughCapacity",
"detail": "Not enough places are left then.",
"details": {
"remaining": 2
}
}
CodeStatusWhenWhat to do
SlotClosed422The option doesn't run at that start.Show the calendar again and let the traveller pick another start.
SoldOut422No places are left at that start.Offer another start from the calendar.
NotEnoughCapacity422Fewer places are left than travellers. Carries remaining.Say how many places are left, from remaining.
PastCutoff422It is too late to book that start. Carries cutoffAt.Offer a later start.
PriceNotAvailable422The seller has no price for this selection: out of season, a group size or a weekday they don't price. Carries unitId, and reason: outside_season, group_size or weekday.Offer an enquiry instead.
UnitQuantityInvalid422Too few or too many of one kind of traveller or item. Carries unitId, min, max.Keep the number between min and max.
AgeRestriction422A traveller's age is outside the unit's ages. Carries unitId, minAge, maxAge.Book them under the right unit, or not on this option.
AccompanimentRequired422A traveller, usually a child, needs someone with them. Carries unitId, by.Add one of the units in by.
UnknownUnit422A unit_id isn't one of this option's units. Carries unitId.Take the units from the trip's option.
VehicleCapacityExceeded422The vehicles chosen don't have enough seats. Carries pax, seats.Choose more or bigger vehicles.
VehicleLimitReached422Not enough vehicles are left that day. Carries remainingVehicles, limitName.Offer another day.
RoomingInvalid422The rooms don't fit the travellers. Carries reason.Change the rooms.
CurrencyNotEnabled422The site doesn't offer that currency. Carries currency.Use one of the storefront's currencies.
ExtraQuantityInvalid422More of an extra than it allows. Carries extraId, max.Keep it at max or fewer.
ExtraSoldOut422An extra is sold out that day. Carries extraId.Remove the extra.
PickupNotOffered422Pickup isn't offered from there, or the option has no pickup. Carries reason, sometimes.Ask for another pickup place, or none.
OnRequest422A hold was asked for an option the seller confirms by hand.Skip the hold: check out directly, and the booking waits as pending.
HoldRequired422Checkout without a hold, for an option that confirms at once.Hold first, then check out with the hold's ref.
HoldExpired422The hold ran out and its places went back on sale.Hold again; quote first if time has passed.
AdjustmentTooLarge422Seller endpoints only: a booking staff make for a traveller, whose adjustment lines take the total below zero. Carries total.Make the discount smaller; total is what the lines would leave.
PaymentMethodRequired422Checkout without payment_method, on a site that has ways to pay set up. Carries offered.Send one of offered as payment_method.
PaymentMethodNotOffered422That way to pay isn't offered for this start. Carries method.Ask GET /v1/public/payment-methods again and use one of them.
TravellerDetailsRequired422The trip needs every traveller's details before booking, and some are missing. Carries missing: each with traveller and, when only some are missing, fields.Collect what missing lists and check out again.
TravellerDetailsInvalid422Some traveller details aren't right, such as a passport that expires before the trip ends. Carries problems, or the counts that don't match.Show each of problems next to its field.
PickupDetailsRequired422The pickup asks for a flight, a ship or a room, and it is missing. Carries missing.Collect what missing lists.
PriceChanged422Seller endpoints only: the price moved between the quote staff saw and applying a booking's change, or making a booking for a traveller. Carries difference, refund, expected_difference and expected_refund for a change; total and expected_total for a booking.Quote again and check the new price, then send it as expected_difference for a change or expected_total for a booking.
SellerUnavailable422A hold or checkout on the own site of a seller the platform has suspended. Bookings already made keep working.Say the seller can't take new bookings for now, and keep the trip pages up.
Cancelling a booking twice
Terminal window
curl -X POST "https://api.stg.vacationpackagesoman.com/v1/public/bookings/TP-4HZQ-8MNE/cancel?token=TOKEN_FROM_THE_LINK" \
-H "Tp-Publishable-Key: $TP_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Answer: 409 Conflict
{
"type": "about:blank",
"title": "Conflict",
"status": 409,
"code": "Conflict",
"detail": "booking TP-4HZQ-8MNE is cancelled, not confirmed"
}
Search while its index is down
Terminal window
curl "https://api.stg.vacationpackagesoman.com/v1/public/search?q=Desert%20safari%20with%20BBQ%20dinner" \
-H "Tp-Publishable-Key: $TP_KEY"
Answer: 503 Service Unavailable
{
"type": "about:blank",
"title": "Service Unavailable",
"status": 503,
"code": "SearchUnavailable",
"detail": "Search is down for now: try again shortly."
}