# OCTO for resellers Resellers, OTAs and hubs book an outfitter's offerings over OCTO, the open standard for tours and activities, at `https://daybag.io/api/octo`. The outfitter makes one reseller key per reseller in Developers; the reseller reads products and availability, holds a place, then confirms it with the guest's name and email. daybag serves OCTO Core with pricing and content. URL: https://daybag.io/docs/octo ## Connect a reseller One key per reseller, made in the dashboard. A reseller's key works here only, and sees only the bookings it made: a new key for the same reseller doesn't see the old one's, so keep the key while its bookings are ahead. 1. In the dashboard, open Developers and choose New under API keys. 2. Pick Reseller, name the key after the reseller, and create it. 3. Send the reseller the key, shown once, and the OCTO address under it. ```http https://daybag.io/api/octo Authorization: Bearer daybag_live_… Octo-Capabilities: octo/pricing, octo/content ``` ## Endpoints OCTO Core, plus `octo/pricing` and `octo/content` when `Octo-Capabilities` asks for them. JSON in and out. - GET /supplier: The outfitter, with its booking page - GET /products: Every active offering - GET /products/{id}: One product - POST /availability: Start times with what's left: by `localDate`, `localDateStart` and `localDateEnd`, or `availabilityIds` - POST /availability/calendar: Each day, up to a year at a time - POST /bookings: Hold a place: `uuid`, `productId`, `optionId`, `availabilityId`, `unitItems`, `expirationMinutes` - POST /bookings/{uuid}/confirm: Confirm with the guest's `contact` - PATCH /bookings/{uuid}: Move to another start; a hold may also change its units and guest - POST /bookings/{uuid}/extend: Keep a hold `expirationMinutes` from now, up to a day after it was made - POST /bookings/{uuid}/cancel: Cancel, with a `reason` - DELETE /bookings/{uuid}: The same cancel, for clients of older OCTO versions - GET /bookings/{uuid}: One booking - GET /bookings: By `resellerReference` or `supplierReference` - GET /capabilities: What can be asked for ## How daybag maps Every active offering is a product, sold by start time in the outfitter's time zone. - class: One option, `DEFAULT`, of `guest` units (type `ADULT`): one per seat. Two sessions at one start read as one availability; a booking takes the first with room. - appointment: One option, `DEFAULT`, of `guest` units for the party; one a booking when additional guests cost something else. Each booking takes one guide's time, whatever its party: `vacancies` is one booking's worth while a guide is free. - rental: One option per number of periods, `1` up to its most, of `item` units (type `OTHER`), priced for that many periods. - availabilityId: The local start with its offset, such as `2026-12-05T09:00:00-07:00`; `allDay` for a time that runs midnight to midnight. - voucher: Once confirmed: the booking's reference as a QR code; the outfitter checks guests off its roster. ## Holds and bookings Hold, then confirm with the guest's contact. Statuses: `ON_HOLD`, `EXPIRED` once a hold lapses, `CONFIRMED`, `CANCELLED`. - The `uuid` is the idempotency key: a retry with it returns the same booking. - A hold lasts `expirationMinutes`: 30 by default, at most 1440. Extending never keeps it past a day from when it was made. A key keeps at most 20 open holds. - Confirm with `contact`: `emailAddress`, and `fullName` or `firstName` and `lastName`, before the start. `unitItems` may change a hold's party on the way. - A booking shows the contact you sent, and only that. - A confirmed booking is the guest's and reads as paid: the reseller collected the money and owns the refund. - Cancel a hold any time, and a booking until 24 hours before the start, or the outfitter's guest cancellation window. Its guest can't cancel it with the outfitter. - daybag sends the reseller's guest no booking emails or reminders; the outfitter hears of each booking you confirm, move or cancel. Messages the outfitter writes, one by one or to everyone on a trip, still reach the guest. - When a trip asks guests to sign a waiver, the outfitter passes its signing link on: it isn't part of the OCTO booking. Errors are OCTO's: `{ error, errorMessage }` plus the id that was wrong, with HTTP 400. No key is 401; a key that isn't a live reseller key, 403; past 120 requests a minute, 429 with `Retry-After`. ## Not supported - Notifications and webhooks: read `GET /bookings/{uuid}` again. When the outfitter cancels or moves a booking of yours, daybag asks it to tell you. - Pickups, dropoffs, offers, promotions, questions and gift cards. - `OPENING_HOURS` products, freesale and open-dated bookings. - A contact, reference or ticket per unit item, `emailReceipt`, and `force` on cancel. - A currency other than the outfitter's, and net rates.