Get available timeslots

PUBLIC

Returns available entry timeslots for the given products on the requested date.
Used during checkout to let the customer pick an entry window.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Part of the catalog — The product catalog explains how merchants, products, calendars and timeslots fit together.

Why this endpoint exists

Some venues admit visitors in timed entry windows — a zoo managing crowd flow, a museum with slot capacity. For those products a date alone is not a bookable request; the provider needs to know which window.

This endpoint asks the provider what is open on a given date and returns the windows with their remaining capacity. It exists as its own call because availability is live: it cannot be baked into the catalog cache, and it is the only capacity signal that reflects the provider's current state.

It is a POST because it takes a list of product ids in the body, not because it changes anything. Nothing is reserved or held.

When to call it

Whenever a product in the basket reports requires_timeslot: true, after the customer picks a date and before you create a checkout. The slot they choose becomes the time component of date in Create.

Skip it entirely when every product reports requires_timeslot: false.

Request

curl -X POST https://api.acc.funtrips.io/v2/fulfillment/timeslots \
  -H "x-campaign-id: $CAMPAIGN_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "product_ids": ["d4b8f2a1-6c3e-4957-b18d-2f5a9c7e3b04"],
    "date": "2026-09-12"
  }'
FieldTypeRequiredNotes
product_idsUUID[]YesThe products the customer intends to buy
datedate YYYY-MM-DDYesCalendar day — no time component

Send all timeslotted products from the basket in one call. The returned slots are the ones workable for the set, which is what you need when the customer is buying an adult and a child ticket that must be admitted together.

Response

{
  "data": {
    "date": "2026-09-12",
    "slots": [
      {
        "entry_from":  "2026-09-12T09:00:00Z",
        "entry_until": "2026-09-12T10:00:00Z",
        "available_capacity": 48
      },
      {
        "entry_from":  "2026-09-12T10:00:00Z",
        "entry_until": "2026-09-12T11:00:00Z",
        "available_capacity": 12
      }
    ]
  },
  "meta": { "correlation_id": "…" }
}
FieldMeaning
entry_fromStart of the window. This is the value you send as date at checkout
entry_untilEnd of the window — for display: "09:00 – 10:00"
available_capacityUnits left in the window

Pass entry_from through verbatim as the checkout date. Do not reformat, re-zone or truncate it — it is the provider's slot key, and a rewritten timestamp may not match a slot.

Filter out slots where available_capacity is below the customer's requested quantity: showing a window with 2 places left to someone buying 4 tickets produces a failure at checkout that you could have prevented here.

An empty slots array is a real answer

Empty slots on a requires_timeslot: true product means that date is not bookable.

Block the date and prompt the customer to choose another. Do not fall back to midnight or to "no timeslot": timeslotted providers reject a midnight visit time, and because midnight UTC is 02:00 Amsterdam in summer, the request that does get through books the wrong day.

The same empty response means the opposite for a product with requires_timeslot: false — that product is all-day and the date alone is sufficient. The product flag, not the slot list, tells you which case you are in, so branch on the flag explicitly rather than inferring intent from an empty array.

if (product.requires_timeslot) {
  const { data } = await fetchTimeslots([product.id], date);
  const usable = data.slots.filter(s => s.available_capacity >= quantity);
  if (usable.length === 0) return blockDate(date);   // not bookable
  return usable;                                     // let the customer pick
}
return null;                                         // all-day: date is enough

Timezones

Slot timestamps are absolute instants with a zone. Convert to the venue's local time for display; send entry_from back unmodified. A slot rendered in the customer's browser timezone will confuse anyone booking from abroad — the venue opens at 09:00 local, not 09:00 wherever the customer is sitting.

Errors

StatustypeCause
400product_ids empty, a malformed UUID, or date not YYYY-MM-DD
500Unexpected fault, or the provider could not be reached. Retryable

Fulfillment errors carry no type field — branch on status. See Error handling.

A date with no availability is 200 with slots: [], not an error.

Body Params
product_ids
array of uuids
required
product_ids*
date
required
Headers
uuid
required

Campaign scope for this request. Filters content to the specified campaign.

string

RFC 7231 language preference. The best match against supported locales (nl-NL, en-GB, de-DE) is selected. Defaults to nl-NL when omitted.

string
enum
Defaults to application/json

Generated from available response content types

Allowed:
Responses

Language
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json
application/problem+json