Download OpenAPI specification:
The OCTO 1.0 supplier API Travelity hosts for its resale partners.
Travelity hosts this API for resellers who speak OCTO - the Open Connectivity for Tours, Activities and Attractions standard. It is the supplier side of the protocol: you call us, we answer with our operators' inventory and take bookings against it.
Conformance target: OCTO 1.0. Where the published core specification is silent or where shipping implementations disagree with it, this document describes what Travelity actually sends and accepts. Those places are called out explicitly below. Everything here is generated from, and continuously tested against, the running service.
Credentials are issued per supplier connection by Travelity - one Bearer key
identifies exactly one operator's inventory on exactly one mount. To set up a
connection, or to replace a key that was lost or compromised, contact Travelity at
vahagns@bravecrew.io.
Send it on every request:
Authorization: Bearer <your api key>
The two failures are distinguished:
UNAUTHORIZED - nothing to authenticate with: no Authorization header, a
scheme other than Bearer, or an empty token.FORBIDDEN - a token was presented but matched no active connection on
this mount. A key issued for one mount answers 403 on another mount's prefix; it
is not a shared credential.401 is also what an unauthenticated request to an unknown path under the prefix gets - the credential is checked before the route.
OCTO capabilities are negotiated per request. Travelity supports exactly one:
octo/pricing. Ask for it with a header:
Octo-Capabilities: octo/pricing
or, if your client cannot set headers, with the _capabilities query parameter. The
header wins when both are present. Parsing is case-insensitive and comma-separated,
so OCTO/Pricing matches and unknown ids are ignored rather than rejected.
Every successful response carries an Octo-Capabilities response header naming
what actually activated - the empty string when nothing did. That header is how you
confirm pricing is on; it is set from the same resolution that gates the pricing
fields, so a capability can never activate without being acknowledged.
Without octo/pricing, every pricing field is absent - not null, not zero. No
other capability (octo/content, octo/pickups, octo/offers, octo/questions,
octo/notifications) is implemented.
One OCTO product is one Travelity option. productId is the option's identifier
in our system, and it is what you will see in every payload and send in every
request.
Each product carries exactly one option, with id: "DEFAULT". Travelity models
what OCTO calls options as separate products, so there is nothing to choose between.
Every request that takes an optionId requires it and it must equal DEFAULT;
anything else is INVALID_OPTION_ID and the response names the value you sent.
Products are START_TIME products: they publish departures, never opening hours.
allowFreesale is false on every product - a booking always requires an
availabilityId obtained from POST /availability first.
Every product listed here confirms instantly. An operator's on-request options, where a person decides whether to accept each request, are not offered on this channel at all. Neither is a private option without a maximum party size: this channel reports a private departure in participants, and that number is what states how many a vehicle holds.
Two fields carry a party ceiling, and they answer different questions:
Option.restrictions.maxUnits is the operator's per-booking party ceiling,
null when none is set. It is a static property of the option and says nothing
about any one departure.Availability.maxUnits is authoritative. It is the live per-departure number
and is a promise: every value it can name is one that POST /bookings will
accept. It is the smaller of the operator's ceiling and what the departure still
has free, and on a bracketed rule it never exceeds the highest priced bracket.On a private option the two are the same number while a vehicle is free, because
one booking takes the whole vehicle: Availability.maxUnits is the vehicle's party
size, and 0 once none is free.
Option.restrictions.minUnits is the option's minimum party size, null when the
operator set no floor, and it is enforced - see Participant bounds.
POST /availability takes exactly one of three request forms:
localDate - a single day.localDateStart + localDateEnd - an inclusive range.availabilityIds - specific departures you already hold ids for.Sending none, or more than one, is BAD_REQUEST. A range wider than one year
(366 days) is BAD_REQUEST. Dates are strict YYYY-MM-DD.
An availabilityId is an ISO 8601 local datetime, not an opaque row id:
2026-07-01T09:00:00+04:00
It is the departure's local date and start time with the operator's UTC offset.
Do not build one by string concatenation: the product's
availabilityLocalStartTimes are normalised to HH:MM ("09:00") while the id
carries seconds ("...T09:00:00+04:00"). Ids come from POST /availability, which is
the only place they are minted.
vacancies: 0 and status: "SOLD_OUT".vacancies: 0. The row still exists; you simply cannot sell it.capacity is the departure's own maximum; vacancies is what is genuinely sellable
right now. Both are counted in participants, on every option. status is
SOLD_OUT at zero vacancies, LIMITED at or below half of capacity, and AVAILABLE
otherwise. A departure that runs past midnight has a localDateTimeEnd on the
following local date - it never wraps back before its own start.
On a private option one booking takes a whole vehicle, so a sale of any size
drops vacancies by the vehicle's party size, and maxUnits is that party size
while a vehicle is free and 0 once none is.
POST /availability/calendar collapses the same departures into one entry per local
date, summing vacancies and capacity across the day. It is deliberately narrower
than POST /availability: no id, no allDay, no maxUnits, no utcCutoffAt. Use
it to paint a month; use POST /availability to quote and to obtain ids. Both range
dates are required.
A date this channel cannot put a price on is not returned, and is refused if you name one anyway. Three causes:
| Cause | Offered? | If you reserve against it |
|---|---|---|
| No pricing rule covers the date for your channel and currency | No | UNPROCESSABLE_ENTITY |
| The operator prices that date per group in brackets (a shape OCTO's unit-item contract cannot express) | No | UNPROCESSABLE_ENTITY |
| A tiered rule whose brackets do not reach your party size | Yes, but maxUnits is capped to the top bracket and unitPricing is absent for that party |
UNPROCESSABLE_ENTITY |
The practical consequence: you can sell exactly as far ahead as the operator has priced. An operator who has published prices for the next 90 days offers you 90 days here, however much further ahead their schedule runs. Extending the horizon is a pricing change on their side, not a scheduling one.
Everything in this section needs the octo/pricing capability negotiated.
Without it none of these fields appear at all.
All amounts are integers in the currency's minor unit, with currencyPrecision
telling you where the decimal point goes - 2 for most currencies, 0 for JPY, KRW,
VND and the other zero-decimal currencies. 10000 at precision 2 is 100.00.
The currency is the one configured on your connection, never the operator's own
default. Every product reports it as defaultCurrency, and availableCurrencies
always contains exactly that one value. You may send currency on a reservation as
an assertion; if it does not match the connection currency the reservation is
BAD_REQUEST rather than silently re-quoted.
Every pricing object carries the same three tiers. original and retail always
carry the same value: the booking's price in your connection's currency. Nothing you
call through this API changes it after reservation. net is null - no wholesale
rate is negotiated on this channel. includedTaxes is always []; taxes are not
itemised on this channel.
Where pricing appears:
defaultCurrency, availableCurrencies, pricingPer, and a
pricingFrom on each unit that has a price. A unit with no published price
carries no pricingFrom at all, rather than one reading zero.unitPricing[] when the departure resolves per-unit prices,
plus a total pricing object only when your request carried units, since a
total needs quantities. A per-group product sends unitPricing: [] with the group
total in pricing.unitPricingFrom[] and pricingFrom{}, taken from the day's first
departure. A calendar gives a "from" price for a date, not a quote for a departure.pricing on the booking, and a per-item pricing on each
unit item.pricingPer is BOOKING for a product the operator prices per group, and UNIT
for everything else. A BOOKING-priced product emits no unitItems[].pricing at
all - the group total on the booking is the whole price. It follows how the
operator's option is priced, per participant or per group, and does not change from
date to date: a product does not price per head on one day and per party on the
next.
Tiered prices are resolved before they reach you. OCTO has no bracket concept, so
a bracketed rule is flattened to per-unit prices: with units in your request the
bracket matching that party is used, so a quote and the reservation that follows it
agree; without units the first bracket stands in as a "from" price.
POST /bookings -> ON_HOLD (capacity is taken here)
POST /bookings/{uuid}/confirm -> CONFIRMED (tickets are issued here)
POST /bookings/{uuid}/cancel -> CANCELLED
A reservation holds capacity for expirationMinutes, clamped into [5, 60].
Out-of-range values are clamped, never rejected - a 0 becomes a 5-minute hold
rather than an error. POST /bookings/{uuid}/extend moves the expiry, always
measured from now and using the same clamp, so expirationMinutes means one
thing everywhere in this API. Only an unexpired hold can be extended.
Send a uuid on a reservation and it becomes the booking's identifier and its
idempotency key. Repeating a reservation with the same uuid replays the booking
that already exists instead of taking capacity twice - including for two requests
racing each other, one of which will replay the other's booking. The key is scoped to
the operator behind your key: two different operators may use the same uuid without
colliding.
Omit uuid and the booking's own identifier is returned as uuid. Either way, the
value you get back is the one to use in every later path.
unitItems[].uuid works the same way: supply one per head and it is echoed on every
later read; omit it and we mint one. Unit items keep their ids and their order from
the hold through confirmation and cancellation.
The operator's minimum and maximum party size are enforced when you reserve. The check is on the participant count, not on seats consumed - which matters for a private departure, where a party of any size takes the whole vehicle and the capacity check alone would never notice a party too large for it.
A party outside the bounds is UNPROCESSABLE_ENTITY carrying
restrictions: { minUnits, maxUnits } - the same shape the option advertised its
bounds in, so you can retry inside them. This is what makes Availability.maxUnits
and Option.restrictions.minUnits guarantees rather than hints.
contact is optional on our side, although OCTO 1.0 marks it required. A confirm
with no contact - or an empty one - is accepted; the booking then reads back with an
all-null contact. Only fullName / firstName / lastName, emailAddress and
phoneNumber are stored; country, postalCode, locales and notes are accepted
and discarded, and read back as null or []. Per-unit-item contacts are accepted
and discarded in the same way.
Confirming is idempotent: a repeat confirm issues no second set of tickets. A
repeat carrying a different resellerReference replaces the stored one - the
reference is yours and the latest one wins - while one that repeats it, or omits it,
changes nothing.
notes behaves the same way. The booking carries the notes sent at reservation; a
confirmation that sends notes replaces them, one that omits them leaves them
unchanged, and an empty string clears them.
PATCH /bookings/{uuid} always fails. A changed party, date or option is a different
sale: cancel and rebook. The booking is loaded first, so an unknown uuid still
answers INVALID_BOOKING_UUID rather than an unsupported-operation error, and a
known one answers UNPROCESSABLE_ENTITY. Any request body you send is discarded.
testMode is optional on a reservation and echoed on every later read. Test
bookings are real bookings - they consume capacity, issue tickets and are visible
to the operator like any other booking. There is no auto-cleanup; cancel them when you are done
certifying.
| Status | Meaning |
|---|---|
ON_HOLD |
A live reservation, within its expiry |
CONFIRMED |
A sale |
EXPIRED |
A hold that ran out of time |
CANCELLED |
Something somebody cancelled |
A hold reads EXPIRED as soon as its expiry passes, and it still reads EXPIRED
afterwards. A hold you cancel while it is still live
reads CANCELLED, as does any cancelled confirmed booking. An EXPIRED booking is
never cancellable.
The cancellation policy does not gate the call. The only guard is the departure
date: a booking whose departure day has already passed in the operator's timezone is
UNPROCESSABLE_ENTITY, unless you send force: true. Same-day cancellations are
allowed. A late cancellation is priced by its refund tier, not refused.
cancellable is true while the booking is ON_HOLD or CONFIRMED and its
departure day has not passed. EXPIRED and CANCELLED are always false.cancellation.refund is the tier that applied at the moment of cancellation,
not at read time - so a booking cancelled well inside a full-refund window keeps
reading FULL after its departure passes. A booking that never reached CONFIRMED
paid nothing and reads FULL.Option.cancellationCutoff, cancellationCutoffAmount and cancellationCutoffUnit
come from the operator's cancellation policy: the earliest hours-before-departure
at which the policy still refunds something, i.e. the boundary past which it pays
nothing. No policy, or no refundable tier, reports 0 / hour. A whole-day figure
is rendered in days (24 becomes 1 day). This is not the booking cutoff the
departure advertises for sales - that one is Availability.utcCutoffAt.
Unlike some supplier APIs, this one uses real HTTP status codes. Every business rejection is HTTP 400 with a body of exactly:
{ "error": "INVALID_PRODUCT_ID", "errorMessage": "...", "productId": "..." }
errorMessage is always a single string, never an array. The third property, when
present, names what was wrong.
The complete catalogue is the ten codes OCTO 1.0 defines, and nothing else:
| HTTP | error |
Extra |
|---|---|---|
| 400 | INVALID_PRODUCT_ID |
productId |
| 400 | INVALID_OPTION_ID |
optionId |
| 400 | INVALID_UNIT_ID |
unitId |
| 400 | INVALID_AVAILABILITY_ID |
availabilityId |
| 400 | INVALID_BOOKING_UUID |
uuid |
| 400 | UNPROCESSABLE_ENTITY |
restrictions, for a participant-bounds failure only |
| 400 | BAD_REQUEST |
- |
| 401 | UNAUTHORIZED |
- |
| 403 | FORBIDDEN |
- |
| 500 | INTERNAL_SERVER_ERROR |
- |
An authenticated request to an unknown path under the prefix answers 404 with
error: "BAD_REQUEST" - the OCTO body shape, with the HTTP status that tells you the
route does not exist.
A reservation is validated in a fixed order, so a request wrong in more than one way gets the most specific answer:
INVALID_PRODUCT_ID,
INVALID_OPTION_ID, INVALID_AVAILABILITY_ID;unitId must belong to the option - INVALID_UNIT_ID;UNPROCESSABLE_ENTITY with
restrictions;UNPROCESSABLE_ENTITY;UNPROCESSABLE_ENTITY.Nothing is written before all five pass. A refused reservation consumes no capacity.
A 500 carrying {"error": "INTERNAL_SERVER_ERROR", "errorMessage": "Unexpected error"} is a failure on our side; retry after a short delay. A 500 with any other
body shape is a transient platform error; retry, and contact Travelity if it
persists.
The operator behind this connection. contact is the operator's support
contact, not a booking contact; every field in it is nullable and only email
has a value today. endpoint is this mount's own base URL.
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
{- "id": "3f1a9e2c-7d45-4b8a-9c61-0e2d4f6a8b10",
- "name": "Yerevan Walking Tours",
- "contact": {
- "website": null,
- "email": "ops@yerevanwalks.example",
- "telephone": null,
- "address": null
}
}Every active product this connection may sell. Pricing fields appear only with
octo/pricing negotiated.
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
[- {
- "id": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "internalName": "Old Yerevan Walking Tour - Morning Departure",
- "reference": null,
- "locale": "en",
- "timeZone": "Asia/Yerevan",
- "allowFreesale": false,
- "instantConfirmation": true,
- "instantDelivery": true,
- "availabilityRequired": true,
- "availabilityType": "START_TIME",
- "deliveryFormats": [
- "QRCODE"
], - "deliveryMethods": [
- "TICKET"
], - "redemptionMethod": "DIGITAL",
- "defaultCurrency": "EUR",
- "availableCurrencies": [
- "EUR"
], - "pricingPer": "UNIT",
- "options": [
- {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}
]
}
]| productId required | string Example: 9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012 The product id, as returned by |
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
{- "id": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "internalName": "Old Yerevan Walking Tour - Morning Departure",
- "reference": null,
- "locale": "en",
- "timeZone": "Asia/Yerevan",
- "allowFreesale": false,
- "instantConfirmation": true,
- "instantDelivery": true,
- "availabilityRequired": true,
- "availabilityType": "START_TIME",
- "deliveryFormats": [
- "QRCODE"
], - "deliveryMethods": [
- "TICKET"
], - "redemptionMethod": "DIGITAL",
- "defaultCurrency": "EUR",
- "availableCurrencies": [
- "EUR"
], - "pricingPer": "UNIT",
- "options": [
- {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}
]
}Send exactly one of localDate, localDateStart + localDateEnd, or
availabilityIds. Include units to receive a total pricing object and, on a
bracketed rule, the prices for that specific party.
Closed departures and dates the operator has not priced are omitted. A departure
inside its booking cutoff is returned at vacancies: 0.
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
| productId required | string |
| optionId required | string Value: "DEFAULT" |
| localDate | string^\d{4}-\d{2}-\d{2}$ A single local date. |
| localDateStart | string^\d{4}-\d{2}-\d{2}$ First date of an inclusive range. Requires |
| localDateEnd | string^\d{4}-\d{2}-\d{2}$ Last date of an inclusive range. At most a year after |
| availabilityIds | Array of strings non-empty Specific departures, by the ids a previous call returned. |
Array of objects (AvailabilityUnit) The party you intend to book. Supplying it returns a total |
{- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "optionId": "DEFAULT",
- "localDate": "2026-07-01",
- "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "quantity": 2
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "quantity": 1
}
]
}[- {
- "id": "2026-07-01T09:00:00+04:00",
- "localDateTimeStart": "2026-07-01T09:00:00+04:00",
- "localDateTimeEnd": "2026-07-01T12:00:00+04:00",
- "utcCutoffAt": "2026-06-30T05:00:00.000Z",
- "allDay": false,
- "available": true,
- "status": "AVAILABLE",
- "vacancies": 18,
- "capacity": 20,
- "maxUnits": 10,
- "openingHours": [ ],
- "unitPricing": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
]For painting a calendar. vacancies and capacity are the day's sums across
every departure, and the prices are the day's first departure - a "from" figure,
not a quote. Both range dates are required, and the range may not exceed a year.
A date shown as open always has a real, priced departure behind it that
POST /availability will return an id for.
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
| productId required | string |
| optionId required | string Value: "DEFAULT" |
| localDateStart required | string^\d{4}-\d{2}-\d{2}$ |
| localDateEnd required | string^\d{4}-\d{2}-\d{2}$ At most a year after |
Array of objects (AvailabilityUnit) |
{- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "optionId": "DEFAULT",
- "localDateStart": "2026-07-01",
- "localDateEnd": "2026-07-31",
- "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "quantity": 2
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "quantity": 1
}
]
}[- {
- "localDate": "2026-07-01",
- "available": true,
- "status": "AVAILABLE",
- "vacancies": 18,
- "capacity": 20,
- "openingHours": [ ],
- "unitPricingFrom": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
], - "pricingFrom": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
]Takes capacity and returns an ON_HOLD booking. Send one unitItems entry per
head - the array's length is the party size.
Supply uuid to make the call idempotent: a repeat returns the same booking
without taking capacity twice.
Nothing is written unless the whole request is acceptable; a refusal consumes no capacity.
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
| productId required | string |
| optionId required | string Value: "DEFAULT" |
| availabilityId required | string A departure id from |
required | Array of objects (ReservationUnitItem) non-empty One entry per head. Two adults and a child is three entries. |
| uuid | string <uuid> Your identifier for this booking, and its idempotency key - repeating it replays the existing booking instead of taking capacity twice. Scoped to your connection's operator. |
| expirationMinutes | integer How long to hold. Clamped into |
| notes | string Free text kept with the booking and echoed on every read. A later confirmation may replace it. |
| currency | string Optional assertion. Must equal your connection's currency; a mismatch is
|
| testMode | boolean Marks the booking as a test. It still consumes capacity and issues tickets - cancel it when you are done. |
{- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "optionId": "DEFAULT",
- "availabilityId": "2026-07-01T09:00:00+04:00",
- "unitItems": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "uuid": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f"
}, - {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f"
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60"
}
], - "uuid": "b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
- "expirationMinutes": 60,
- "notes": "Please meet at the Cascade steps.",
- "currency": "EUR",
- "testMode": false
}{- "id": "7a6b5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
- "uuid": "b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
- "testMode": false,
- "resellerReference": null,
- "supplierReference": "YOUR-MOUNT-1782292532418",
- "status": "ON_HOLD",
- "utcCreatedAt": "2026-06-24T09:15:32.418Z",
- "utcUpdatedAt": "2026-06-24T09:15:32.418Z",
- "utcExpiresAt": "2026-06-24T10:15:32.418Z",
- "utcRedeemedAt": null,
- "utcConfirmedAt": null,
- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "product": {
- "id": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "internalName": "Old Yerevan Walking Tour - Morning Departure",
- "reference": null,
- "locale": "en",
- "timeZone": "Asia/Yerevan",
- "allowFreesale": false,
- "instantConfirmation": true,
- "instantDelivery": true,
- "availabilityRequired": true,
- "availabilityType": "START_TIME",
- "deliveryFormats": [
- "QRCODE"
], - "deliveryMethods": [
- "TICKET"
], - "redemptionMethod": "DIGITAL",
- "defaultCurrency": "EUR",
- "availableCurrencies": [
- "EUR"
], - "pricingPer": "UNIT",
- "options": [
- {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}
]
}, - "optionId": "DEFAULT",
- "option": {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}, - "cancellable": true,
- "cancellation": null,
- "freesale": false,
- "availabilityId": "2026-07-01T09:00:00+04:00",
- "availability": {
- "id": "2026-07-01T09:00:00+04:00",
- "localDateTimeStart": "2026-07-01T09:00:00+04:00",
- "localDateTimeEnd": "2026-07-01T12:00:00+04:00",
- "utcCutoffAt": "2026-06-30T05:00:00.000Z",
- "allDay": false,
- "available": true,
- "status": "AVAILABLE",
- "vacancies": 15,
- "capacity": 20,
- "maxUnits": 10,
- "openingHours": [ ],
- "unitPricing": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "notes": "Please meet at the Cascade steps.",
- "deliveryMethods": [
- "TICKET"
], - "voucher": null,
- "unitItems": [
- {
- "uuid": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
- "resellerReference": null,
- "supplierReference": null,
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "ON_HOLD",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": null,
- "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f70",
- "resellerReference": null,
- "supplierReference": null,
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "ON_HOLD",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": null,
- "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7081",
- "resellerReference": null,
- "supplierReference": null,
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "unit": {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "ON_HOLD",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": null,
- "pricing": {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}At least one filter is required - resellerReference, supplierReference,
localDate, localDateStart or productId. localDateEnd on its own does not
count: it bounds a range whose start is missing.
Results are always scoped to your connection. A product mapped to two resellers still lists each booking once.
OCTO 1.0 lists productId and optionId as narrowing parameters; here
productId on its own also satisfies the filter requirement.
| resellerReference | string Example: resellerReference=VOUCHER-88213 The reference you supplied at confirmation. |
| supplierReference | string Example: supplierReference=YOUR-MOUNT-1782292532418 Our order number, as returned in |
| localDate | string^\d{4}-\d{2}-\d{2}$ Example: localDate=2026-07-01 All bookings departing on this local date. |
| localDateStart | string^\d{4}-\d{2}-\d{2}$ Example: localDateStart=2026-07-01 First local date of a range. |
| localDateEnd | string^\d{4}-\d{2}-\d{2}$ Example: localDateEnd=2026-07-31 Last local date of a range. Not a filter on its own. |
| productId | string Example: productId=9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012 Restrict to one product. |
| optionId | string Example: optionId=DEFAULT Must be Value: "DEFAULT" |
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
[- {
- "id": "7a6b5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
- "uuid": "b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
- "testMode": false,
- "resellerReference": "VOUCHER-88213",
- "supplierReference": "YOUR-MOUNT-1782292532418",
- "status": "CONFIRMED",
- "utcCreatedAt": "2026-06-24T09:15:32.418Z",
- "utcUpdatedAt": "2026-06-24T09:22:07.903Z",
- "utcExpiresAt": null,
- "utcRedeemedAt": null,
- "utcConfirmedAt": "2026-06-24T09:22:07.903Z",
- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "product": {
- "id": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "internalName": "Old Yerevan Walking Tour - Morning Departure",
- "reference": null,
- "locale": "en",
- "timeZone": "Asia/Yerevan",
- "allowFreesale": false,
- "instantConfirmation": true,
- "instantDelivery": true,
- "availabilityRequired": true,
- "availabilityType": "START_TIME",
- "deliveryFormats": [
- "QRCODE"
], - "deliveryMethods": [
- "TICKET"
], - "redemptionMethod": "DIGITAL",
- "defaultCurrency": "EUR",
- "availableCurrencies": [
- "EUR"
], - "pricingPer": "UNIT",
- "options": [
- {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}
]
}, - "optionId": "DEFAULT",
- "option": {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}, - "cancellable": true,
- "cancellation": null,
- "freesale": false,
- "availabilityId": "2026-07-01T09:00:00+04:00",
- "availability": {
- "id": "2026-07-01T09:00:00+04:00",
- "localDateTimeStart": "2026-07-01T09:00:00+04:00",
- "localDateTimeEnd": "2026-07-01T12:00:00+04:00",
- "utcCutoffAt": "2026-06-30T05:00:00.000Z",
- "allDay": false,
- "available": true,
- "status": "AVAILABLE",
- "vacancies": 15,
- "capacity": 20,
- "maxUnits": 10,
- "openingHours": [ ],
- "unitPricing": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - "contact": {
- "fullName": "Ada Lovelace",
- "firstName": "Ada",
- "lastName": "Lovelace",
- "emailAddress": "ada@example.test",
- "phoneNumber": "+37410555000",
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "notes": "Please meet at the Cascade steps.",
- "deliveryMethods": [
- "TICKET"
], - "voucher": null,
- "unitItems": [
- {
- "uuid": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
- "resellerReference": null,
- "supplierReference": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f"
}
]
}, - "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f70",
- "resellerReference": null,
- "supplierReference": "d2e3f4a5-b6c7-4d8e-9f0a-1b2c3d4e5f60",
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "d2e3f4a5-b6c7-4d8e-9f0a-1b2c3d4e5f60"
}
]
}, - "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7081",
- "resellerReference": null,
- "supplierReference": "e3f4a5b6-c7d8-4e9f-8a0b-1c2d3e4f5a61",
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "unit": {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "e3f4a5b6-c7d8-4e9f-8a0b-1c2d3e4f5a61"
}
]
}, - "pricing": {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
]| uuid required | string <uuid> Example: b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d The booking's |
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
{- "id": "7a6b5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
- "uuid": "b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
- "testMode": false,
- "resellerReference": "VOUCHER-88213",
- "supplierReference": "YOUR-MOUNT-1782292532418",
- "status": "CONFIRMED",
- "utcCreatedAt": "2026-06-24T09:15:32.418Z",
- "utcUpdatedAt": "2026-06-24T09:22:07.903Z",
- "utcExpiresAt": null,
- "utcRedeemedAt": null,
- "utcConfirmedAt": "2026-06-24T09:22:07.903Z",
- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "product": {
- "id": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "internalName": "Old Yerevan Walking Tour - Morning Departure",
- "reference": null,
- "locale": "en",
- "timeZone": "Asia/Yerevan",
- "allowFreesale": false,
- "instantConfirmation": true,
- "instantDelivery": true,
- "availabilityRequired": true,
- "availabilityType": "START_TIME",
- "deliveryFormats": [
- "QRCODE"
], - "deliveryMethods": [
- "TICKET"
], - "redemptionMethod": "DIGITAL",
- "defaultCurrency": "EUR",
- "availableCurrencies": [
- "EUR"
], - "pricingPer": "UNIT",
- "options": [
- {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}
]
}, - "optionId": "DEFAULT",
- "option": {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}, - "cancellable": true,
- "cancellation": null,
- "freesale": false,
- "availabilityId": "2026-07-01T09:00:00+04:00",
- "availability": {
- "id": "2026-07-01T09:00:00+04:00",
- "localDateTimeStart": "2026-07-01T09:00:00+04:00",
- "localDateTimeEnd": "2026-07-01T12:00:00+04:00",
- "utcCutoffAt": "2026-06-30T05:00:00.000Z",
- "allDay": false,
- "available": true,
- "status": "AVAILABLE",
- "vacancies": 15,
- "capacity": 20,
- "maxUnits": 10,
- "openingHours": [ ],
- "unitPricing": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - "contact": {
- "fullName": "Ada Lovelace",
- "firstName": "Ada",
- "lastName": "Lovelace",
- "emailAddress": "ada@example.test",
- "phoneNumber": "+37410555000",
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "notes": "Please meet at the Cascade steps.",
- "deliveryMethods": [
- "TICKET"
], - "voucher": null,
- "unitItems": [
- {
- "uuid": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
- "resellerReference": null,
- "supplierReference": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f"
}
]
}, - "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f70",
- "resellerReference": null,
- "supplierReference": "d2e3f4a5-b6c7-4d8e-9f0a-1b2c3d4e5f60",
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "d2e3f4a5-b6c7-4d8e-9f0a-1b2c3d4e5f60"
}
]
}, - "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7081",
- "resellerReference": null,
- "supplierReference": "e3f4a5b6-c7d8-4e9f-8a0b-1c2d3e4f5a61",
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "unit": {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "e3f4a5b6-c7d8-4e9f-8a0b-1c2d3e4f5a61"
}
]
}, - "pricing": {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}This operation always fails. Travelity prices and seats a sale at creation, so a changed party, date or option is a different sale: cancel and rebook.
The booking is resolved first, so an unknown uuid answers INVALID_BOOKING_UUID
and a known one answers UNPROCESSABLE_ENTITY. Any body you send is discarded. It
is documented here because OCTO 1.0 defines it and a conformance suite will call
it.
| uuid required | string <uuid> Example: b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d The booking's |
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
Declared for OCTO conformance. Travelity does not support amendments, so any content is discarded and the call always fails.
{ }{- "error": "UNPROCESSABLE_ENTITY",
- "errorMessage": "Booking amendments are not supported - cancel and rebook"
}Turns an unexpired hold into a sale and issues one ticket per unit item. Only a
hold can be confirmed; anything else - confirmed, cancelled, expired, or a
cancellation that raced this call - answers INVALID_BOOKING_UUID.
Confirming twice is safe and issues no second set of tickets.
| uuid required | string <uuid> Example: b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d The booking's |
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
object (ConfirmationContact) Only | |
| resellerReference | string Your booking reference. Sending a different one on a repeat confirmation replaces the stored value; repeating or omitting it changes nothing. |
| notes | string Replaces the notes sent at reservation. Omitting the field leaves them unchanged; an empty string clears them. |
Array of objects (ConfirmationUnitItem) Accepted for OCTO conformance. Per-item contacts are not stored. |
{- "contact": {
- "firstName": "Ada",
- "lastName": "Lovelace",
- "emailAddress": "ada@example.test",
- "phoneNumber": "+37410555000"
}, - "resellerReference": "VOUCHER-88213"
}{- "id": "7a6b5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
- "uuid": "b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
- "testMode": false,
- "resellerReference": "VOUCHER-88213",
- "supplierReference": "YOUR-MOUNT-1782292532418",
- "status": "CONFIRMED",
- "utcCreatedAt": "2026-06-24T09:15:32.418Z",
- "utcUpdatedAt": "2026-06-24T09:22:07.903Z",
- "utcExpiresAt": null,
- "utcRedeemedAt": null,
- "utcConfirmedAt": "2026-06-24T09:22:07.903Z",
- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "product": {
- "id": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "internalName": "Old Yerevan Walking Tour - Morning Departure",
- "reference": null,
- "locale": "en",
- "timeZone": "Asia/Yerevan",
- "allowFreesale": false,
- "instantConfirmation": true,
- "instantDelivery": true,
- "availabilityRequired": true,
- "availabilityType": "START_TIME",
- "deliveryFormats": [
- "QRCODE"
], - "deliveryMethods": [
- "TICKET"
], - "redemptionMethod": "DIGITAL",
- "defaultCurrency": "EUR",
- "availableCurrencies": [
- "EUR"
], - "pricingPer": "UNIT",
- "options": [
- {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}
]
}, - "optionId": "DEFAULT",
- "option": {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}, - "cancellable": true,
- "cancellation": null,
- "freesale": false,
- "availabilityId": "2026-07-01T09:00:00+04:00",
- "availability": {
- "id": "2026-07-01T09:00:00+04:00",
- "localDateTimeStart": "2026-07-01T09:00:00+04:00",
- "localDateTimeEnd": "2026-07-01T12:00:00+04:00",
- "utcCutoffAt": "2026-06-30T05:00:00.000Z",
- "allDay": false,
- "available": true,
- "status": "AVAILABLE",
- "vacancies": 15,
- "capacity": 20,
- "maxUnits": 10,
- "openingHours": [ ],
- "unitPricing": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - "contact": {
- "fullName": "Ada Lovelace",
- "firstName": "Ada",
- "lastName": "Lovelace",
- "emailAddress": "ada@example.test",
- "phoneNumber": "+37410555000",
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "notes": "Please meet at the Cascade steps.",
- "deliveryMethods": [
- "TICKET"
], - "voucher": null,
- "unitItems": [
- {
- "uuid": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
- "resellerReference": null,
- "supplierReference": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f"
}
]
}, - "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f70",
- "resellerReference": null,
- "supplierReference": "d2e3f4a5-b6c7-4d8e-9f0a-1b2c3d4e5f60",
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "d2e3f4a5-b6c7-4d8e-9f0a-1b2c3d4e5f60"
}
]
}, - "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7081",
- "resellerReference": null,
- "supplierReference": "e3f4a5b6-c7d8-4e9f-8a0b-1c2d3e4f5a61",
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "unit": {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CONFIRMED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "e3f4a5b6-c7d8-4e9f-8a0b-1c2d3e4f5a61"
}
]
}, - "pricing": {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}Releases the capacity and, for a confirmed booking, retires its tickets. The cancellation policy does not gate this call - a late cancellation is priced by its refund tier, not refused, and same-day cancellations are allowed.
The one guard is a departure day that has already passed; send force: true to
cancel one anyway. Cancelling an already-cancelled booking succeeds and returns
it unchanged.
| uuid required | string <uuid> Example: b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d The booking's |
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
| reason | string Kept on the booking and echoed in |
| force | boolean Cancel even though the departure day has already passed. |
{- "reason": "Customer changed plans"
}{- "id": "7a6b5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
- "uuid": "b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
- "testMode": false,
- "resellerReference": "VOUCHER-88213",
- "supplierReference": "YOUR-MOUNT-1782292532418",
- "status": "CANCELLED",
- "utcCreatedAt": "2026-06-24T09:15:32.418Z",
- "utcUpdatedAt": "2026-06-25T11:04:18.210Z",
- "utcExpiresAt": null,
- "utcRedeemedAt": null,
- "utcConfirmedAt": "2026-06-24T09:22:07.903Z",
- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "product": {
- "id": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "internalName": "Old Yerevan Walking Tour - Morning Departure",
- "reference": null,
- "locale": "en",
- "timeZone": "Asia/Yerevan",
- "allowFreesale": false,
- "instantConfirmation": true,
- "instantDelivery": true,
- "availabilityRequired": true,
- "availabilityType": "START_TIME",
- "deliveryFormats": [
- "QRCODE"
], - "deliveryMethods": [
- "TICKET"
], - "redemptionMethod": "DIGITAL",
- "defaultCurrency": "EUR",
- "availableCurrencies": [
- "EUR"
], - "pricingPer": "UNIT",
- "options": [
- {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}
]
}, - "optionId": "DEFAULT",
- "option": {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}, - "cancellable": false,
- "cancellation": {
- "refund": "FULL",
- "reason": "Customer changed plans",
- "utcCancelledAt": "2026-06-25T11:04:18.210Z"
}, - "freesale": false,
- "availabilityId": "2026-07-01T09:00:00+04:00",
- "availability": {
- "id": "2026-07-01T09:00:00+04:00",
- "localDateTimeStart": "2026-07-01T09:00:00+04:00",
- "localDateTimeEnd": "2026-07-01T12:00:00+04:00",
- "utcCutoffAt": "2026-06-30T05:00:00.000Z",
- "allDay": false,
- "available": true,
- "status": "AVAILABLE",
- "vacancies": 18,
- "capacity": 20,
- "maxUnits": 10,
- "openingHours": [ ],
- "unitPricing": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - "contact": {
- "fullName": "Ada Lovelace",
- "firstName": "Ada",
- "lastName": "Lovelace",
- "emailAddress": "ada@example.test",
- "phoneNumber": "+37410555000",
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "notes": "Please meet at the Cascade steps.",
- "deliveryMethods": [
- "TICKET"
], - "voucher": null,
- "unitItems": [
- {
- "uuid": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
- "resellerReference": null,
- "supplierReference": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CANCELLED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f"
}
]
}, - "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f70",
- "resellerReference": null,
- "supplierReference": "d2e3f4a5-b6c7-4d8e-9f0a-1b2c3d4e5f60",
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CANCELLED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "d2e3f4a5-b6c7-4d8e-9f0a-1b2c3d4e5f60"
}
]
}, - "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7081",
- "resellerReference": null,
- "supplierReference": "e3f4a5b6-c7d8-4e9f-8a0b-1c2d3e4f5a61",
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "unit": {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "CANCELLED",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": {
- "redemptionMethod": "DIGITAL",
- "utcRedeemedAt": null,
- "deliveryOptions": [
- {
- "deliveryFormat": "QRCODE",
- "deliveryValue": "e3f4a5b6-c7d8-4e9f-8a0b-1c2d3e4f5a61"
}
]
}, - "pricing": {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}Moves the hold's expiry, measured from now and clamped into [5, 60] minutes
expirationMinutes: 0 extends by five minutes rather than expiring the hold
on the spot. Omitting it extends by the maximum.Only an unexpired hold can be extended: a confirmed, cancelled or already-expired
booking has nothing left to hold and answers INVALID_BOOKING_UUID.
| uuid required | string <uuid> Example: b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d The booking's |
| _capabilities | string Example: _capabilities=octo/pricing The same list as the |
| Octo-Capabilities | string Example: octo/pricing Capabilities to activate, comma-separated and case-insensitive. Only
|
| expirationMinutes | integer Minutes from now, clamped into |
{- "expirationMinutes": 30
}{- "id": "7a6b5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
- "uuid": "b0a1c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
- "testMode": false,
- "resellerReference": null,
- "supplierReference": "YOUR-MOUNT-1782292532418",
- "status": "ON_HOLD",
- "utcCreatedAt": "2026-06-24T09:15:32.418Z",
- "utcUpdatedAt": "2026-06-24T09:38:45.102Z",
- "utcExpiresAt": "2026-06-24T10:08:45.102Z",
- "utcRedeemedAt": null,
- "utcConfirmedAt": null,
- "productId": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "product": {
- "id": "9f8b1d24-5c3e-4a71-b0d2-6e5f7a8c9012",
- "internalName": "Old Yerevan Walking Tour - Morning Departure",
- "reference": null,
- "locale": "en",
- "timeZone": "Asia/Yerevan",
- "allowFreesale": false,
- "instantConfirmation": true,
- "instantDelivery": true,
- "availabilityRequired": true,
- "availabilityType": "START_TIME",
- "deliveryFormats": [
- "QRCODE"
], - "deliveryMethods": [
- "TICKET"
], - "redemptionMethod": "DIGITAL",
- "defaultCurrency": "EUR",
- "availableCurrencies": [
- "EUR"
], - "pricingPer": "UNIT",
- "options": [
- {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}
]
}, - "optionId": "DEFAULT",
- "option": {
- "id": "DEFAULT",
- "default": true,
- "internalName": "Morning Departure",
- "reference": null,
- "availabilityLocalStartTimes": [
- "09:00"
], - "cancellationCutoff": "1 day",
- "cancellationCutoffAmount": 1,
- "cancellationCutoffUnit": "day",
- "requiredContactFields": [
- "firstName",
- "lastName",
- "emailAddress"
], - "restrictions": {
- "minUnits": null,
- "maxUnits": 10
}, - "units": [
- {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}
]
}, - "cancellable": true,
- "cancellation": null,
- "freesale": false,
- "availabilityId": "2026-07-01T09:00:00+04:00",
- "availability": {
- "id": "2026-07-01T09:00:00+04:00",
- "localDateTimeStart": "2026-07-01T09:00:00+04:00",
- "localDateTimeEnd": "2026-07-01T12:00:00+04:00",
- "utcCutoffAt": "2026-06-30T05:00:00.000Z",
- "allDay": false,
- "available": true,
- "status": "AVAILABLE",
- "vacancies": 15,
- "capacity": 20,
- "maxUnits": 10,
- "openingHours": [ ],
- "unitPricing": [
- {
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}, - {
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "notes": "Please meet at the Cascade steps.",
- "deliveryMethods": [
- "TICKET"
], - "voucher": null,
- "unitItems": [
- {
- "uuid": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
- "resellerReference": null,
- "supplierReference": null,
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "ON_HOLD",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": null,
- "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f70",
- "resellerReference": null,
- "supplierReference": null,
- "unitId": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "unit": {
- "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
- "internalName": "Adult",
- "reference": null,
- "type": "ADULT",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "ON_HOLD",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": null,
- "pricing": {
- "original": 10000,
- "retail": 10000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}, - {
- "uuid": "e5f6a7b8-c9d0-4e1f-8a2b-3c4d5e6f7081",
- "resellerReference": null,
- "supplierReference": null,
- "unitId": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "unit": {
- "id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f60",
- "internalName": "Child",
- "reference": null,
- "type": "CHILD",
- "requiredContactFields": [ ],
- "restrictions": {
- "minAge": 0,
- "maxAge": 99,
- "idRequired": false,
- "minQuantity": null,
- "maxQuantity": null,
- "paxCount": 1,
- "accompaniedBy": [ ]
}, - "pricingFrom": [
- {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
]
}, - "status": "ON_HOLD",
- "utcRedeemedAt": null,
- "contact": {
- "fullName": null,
- "firstName": null,
- "lastName": null,
- "emailAddress": null,
- "phoneNumber": null,
- "locales": [ ],
- "postalCode": null,
- "country": null,
- "notes": null
}, - "ticket": null,
- "pricing": {
- "original": 6000,
- "retail": 6000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}
], - "pricing": {
- "original": 26000,
- "retail": 26000,
- "net": null,
- "currency": "EUR",
- "currencyPrecision": 2,
- "includedTaxes": [ ]
}
}