{"openapi":"3.1.0","info":{"title":"Zameera Partner API","version":"1.1.0","summary":"The published Zameera catalog, plus booking requests on behalf of your guests.","description":"The Zameera Partner API: read the published catalog (experiences and destinations, in the same shape the website renders) and file booking requests on behalf of your guests.\n\n**Authentication.** Every endpoint except `/api/v1` and `/api/v1/openapi.json` requires a key, sent as `Authorization: Bearer <key>` (or the `X-API-Key` header). Keys look like `zk_live_…` and are issued by the Zameera team with one or more scopes: `catalog:read` (catalog endpoints), `bookings:write` (`POST /bookings`) and `bookings:read` (`GET /bookings…`).\n\n**Bookings.** `POST /bookings` files a booking *request* — Zameera does not sell instant inventory. The request lands with our team as `status: \"enquiry\"`; we confirm dates and the final price with the guest, then send a payment link. Read the status back with `GET /bookings/{reference}` (a key sees only the bookings it filed). Send an `Idempotency-Key` header so a retried POST can never create a duplicate. Booking responses are private (`Cache-Control: no-store`).\n\n**Rate limits.** Each key has a per-minute quota (600 by default). Over it you get `429` with a `Retry-After` header.\n\n**Caching.** Responses are shared-cacheable for 60 seconds and carry a weak `ETag`. Send it back as `If-None-Match` to get a `304` instead of a payload.\n\n**Incremental sync.** `GET /experiences?updated_since=<ISO 8601>` returns only rows changed since that instant. Page through large results with `meta.next_cursor`.\n\n**Availability.** Zameera bookings are request-based. Every experience reports `availability.mode = \"on_request\"`; there is no live inventory to query. Send guests to the returned `url` to enquire.\n\n**Attribution.** When a key is linked to an affiliate, every returned `url` carries that partner's `?ref=` code, so traffic and enquiries are attributed automatically.\n\n**Versioning.** This is v1. Additive changes (new fields, new endpoints) ship without notice; a breaking change ships as `/api/v2` and v1 keeps running for at least 6 months.","contact":{"name":"Zameera","email":"contact@zameera.com","url":"https://zameera.com/developers"},"termsOfService":"https://zameera.com/terms"},"servers":[{"url":"https://zameera.com/api/v1","description":"Production"}],"security":[{"bearerAuth":[]},{"apiKeyAuth":[]}],"tags":[{"name":"Service","description":"Discovery and machine-readable spec."},{"name":"Experiences","description":"The catalog itself."},{"name":"Destinations","description":"Places, and what is bookable there."},{"name":"Bookings","description":"File booking requests and read their status."}],"paths":{"/":{"get":{"tags":["Service"],"summary":"Service index","description":"Public. Names the API and points at the docs and this spec.","security":[],"operationId":"getServiceIndex","responses":{"200":{"description":"Service metadata.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"integer"},"docs":{"type":"string","format":"uri"},"openapi":{"type":"string","format":"uri"}}},"example":{"name":"Zameera Catalog API","version":1,"docs":"https://zameera.com/developers","openapi":"https://zameera.com/api/v1/openapi.json"}}}}}}},"/openapi.json":{"get":{"tags":["Service"],"summary":"This document","description":"Public. The OpenAPI 3.1 description of every endpoint.","security":[],"operationId":"getOpenApiDocument","responses":{"200":{"description":"The OpenAPI document.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/experiences":{"get":{"tags":["Experiences"],"summary":"List published experiences","operationId":"listExperiences","parameters":[{"name":"destination","in":"query","required":false,"description":"Filter by destination PAGE slug, e.g. `south-africa`, `maldives`.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size. Default 50, maximum 100.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"description":"Opaque keyset cursor from a previous response's `meta.next_cursor`.","schema":{"type":"string"}},{"name":"updated_since","in":"query","required":false,"description":"Return only experiences whose `updated_at` is strictly after this ISO 8601 instant.","schema":{"type":"string","format":"date-time"}},{"name":"If-None-Match","in":"header","required":false,"description":"Weak ETag from a previous response.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of experiences.","headers":{"ETag":{"description":"Weak validator.","schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ExperienceSummary"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"example":{"data":[{"id":"0f0d2f0e-6a4f-4a4c-9d2c-2f3c9a1b7e10","slug":"the-humble-silverback","url":"https://zameera.com/experience/the-humble-silverback?ref=sandhurst","title":"The Humble Silverback","subtitle":"Eight days beside the Virungas","summary":"A gorilla journey with room around it, anchored at Singita Kwitonda.","card_summary":"Two treks, one lodge, eight days.","destination":{"slug":"rwanda","name":"Rwanda","country":"Rwanda","url":"https://zameera.com/destination/rwanda?ref=sandhurst"},"images":{"hero":{"url":"https://zameera.com/images/the-humble-silverback/hs-subhero.jpg","alt":"The Humble Silverback"},"gallery":[]},"duration_days":8,"capacity":{"min":2,"max":8},"pricing":{"mode":"per_person","from":{"amount":67000,"currency":"USD"},"note":null,"display":"From USD 67,000 per person"},"availability":{"mode":"on_request","note":"Dates are confirmed privately by the Zameera team; enquire to check availability.","duration_days":8},"updated_at":"2026-08-01T09:12:44.128Z"}],"meta":{"count":1,"next_cursor":null,"generated_at":"2026-08-18T06:00:00.000Z"}}}}},"304":{"description":"The `If-None-Match` validator still matches; no body."},"400":{"description":"Invalid `limit`, `cursor` or `updated_since`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key does not carry the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No published destination matches the filter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the seconds in `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/experiences/{slug}":{"get":{"tags":["Experiences"],"summary":"Get one experience","operationId":"getExperience","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The experience.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/ExperienceDetail"},"meta":{"$ref":"#/components/schemas/ItemMeta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches; no body."},"401":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key does not carry the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No published experience with that slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the seconds in `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/destinations":{"get":{"tags":["Destinations"],"summary":"List published destinations","operationId":"listDestinations","parameters":[{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Every destination with a public page.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DestinationSummary"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches; no body."},"401":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key does not carry the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the seconds in `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/destinations/{slug}":{"get":{"tags":["Destinations"],"summary":"Get one destination and its experiences","operationId":"getDestination","parameters":[{"name":"slug","in":"path","required":true,"description":"Public page slug, e.g. `south-africa`.","schema":{"type":"string"}},{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The destination.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/DestinationDetail"},"meta":{"$ref":"#/components/schemas/ItemMeta"}}}}}},"304":{"description":"The `If-None-Match` validator still matches; no body."},"401":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key does not carry the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No published destination with that slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the seconds in `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings":{"post":{"tags":["Bookings"],"summary":"File a booking request","description":"Requires the `bookings:write` scope. Creates a booking request (`status: \"enquiry\"`) that the Zameera team confirms by hand — this is not an instant reservation and nothing is charged. Send an `Idempotency-Key` (any unique string per booking, e.g. your own reference) so a retried request returns the original booking instead of filing a second one. At most 30 bookings per minute per key.","operationId":"createBooking","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique per booking, 1–128 printable ASCII characters. Strongly recommended.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingRequest"},"example":{"experience":"the-humble-silverback","dates":{"start":"2026-11-12"},"guests":{"adults":2,"children":0},"customer":{"name":"Amelia Hart","email":"amelia.hart@example.com","phone":"+44 7700 900123","country":"GB","language":"en"},"special_requests":"Celebrating an anniversary; a quiet room please.","partner_reference":"SANDHURST-48213","notify_guest":true}}}},"responses":{"200":{"description":"Idempotent replay: a booking with this `Idempotency-Key` already exists and is returned unchanged (header `Idempotent-Replayed: true`).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Booking"},"meta":{"$ref":"#/components/schemas/ItemMeta"}}}}}},"201":{"description":"The booking request was filed.","headers":{"Location":{"description":"`/api/v1/bookings/{reference}`","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/Booking"},"meta":{"$ref":"#/components/schemas/ItemMeta"}}},"example":{"data":{"reference":"ZAM-7K2QMD","status":"enquiry","payment_status":"unpaid","experience":{"slug":"the-humble-silverback","title":"The Humble Silverback","url":"https://zameera.com/experience/the-humble-silverback"},"dates":{"start":"2026-11-12","end":"2026-11-20","nights":8},"guests":2,"estimate":{"amount":134000,"currency":"USD","display":"USD 134,000","note":"Approximate, computed from the published rate. Zameera confirms the final price with the guest before any payment is requested."},"customer":{"name":"Amelia Hart","email":"amelia.hart@example.com","phone":"+44 7700 900123","country":"GB","language":"en"},"special_requests":"Celebrating an anniversary; a quiet room please.","partner_reference":"SANDHURST-48213","source":"api","created_at":"2026-08-18T09:14:02.511Z","updated_at":"2026-08-18T09:14:02.511Z","confirmed_at":null,"cancelled_at":null,"confirmation_url":"https://zameera.com/book/confirmation/ZAM-7K2QMD"},"meta":{"generated_at":"2026-08-18T09:14:02.530Z"}}}}},"400":{"description":"Validation failed — `error.details` lists every offending field (including an unknown `experience` slug).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key does not carry the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this `Idempotency-Key` is still being processed; retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Body larger than 64 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the seconds in `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Bookings"],"summary":"List the bookings this key filed","description":"Requires the `bookings:read` scope. Newest first. A key only ever sees its own bookings.","operationId":"listBookings","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["enquiry","pending","confirmed","in_progress","completed","cancelled"]}},{"name":"updated_since","in":"query","required":false,"description":"Only bookings whose `updated_at` is after this instant — poll this to pick up status changes.","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"A page of bookings.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Booking"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}}},"400":{"description":"Invalid `status`, `limit`, `cursor` or `updated_since`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key does not carry the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the seconds in `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/bookings/{reference}":{"get":{"tags":["Bookings"],"summary":"Get one booking","description":"Requires the `bookings:read` scope. Poll this (or `GET /bookings?updated_since=`) to follow a request from `enquiry` through `confirmed`. A reference not filed by this key is a 404.","operationId":"getBooking","parameters":[{"name":"reference","in":"path","required":true,"description":"The Zameera reference returned on creation, e.g. `ZAM-7K2QMD`.","schema":{"type":"string"}}],"responses":{"200":{"description":"The booking.","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"$ref":"#/components/schemas/Booking"},"meta":{"$ref":"#/components/schemas/ItemMeta"}}}}}},"401":{"description":"Missing, unknown or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key does not carry the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No booking with that reference was filed by this key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded. Retry after the seconds in `Retry-After`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"`Authorization: Bearer zk_live_…`"},"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Alternative to the Authorization header."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["unauthorized","forbidden","rate_limited","not_found","bad_request","server_error"]},"message":{"type":"string"},"details":{"type":"array","description":"Only on validation failures (400): one entry per offending field.","items":{"type":"object","required":["field","message"],"properties":{"field":{"type":"string","description":"Dotted path into the request body, e.g. `customer.email`."},"message":{"type":"string"}}}}}}}},"Image":{"type":"object","required":["url","alt"],"properties":{"url":{"type":"string","format":"uri","description":"Absolute image URL."},"alt":{"type":["string","null"]}}},"ListMeta":{"type":"object","required":["count","next_cursor","generated_at"],"properties":{"count":{"type":"integer"},"next_cursor":{"type":["string","null"],"description":"Pass as `cursor` for the next page; null when done."},"generated_at":{"type":"string","format":"date-time"}}},"ItemMeta":{"type":"object","required":["generated_at"],"properties":{"generated_at":{"type":"string","format":"date-time"}}},"ExperienceSummary":{"type":"object","required":["id","slug","url","title","destination","images","capacity","pricing","availability","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"url":{"type":"string","format":"uri","description":"Canonical public URL, with ?ref=<affiliate code> when the key is linked to an affiliate."},"title":{"type":"string"},"subtitle":{"type":["string","null"]},"summary":{"type":["string","null"]},"card_summary":{"type":["string","null"],"description":"Short listing copy; falls back to `summary` when unset."},"destination":{"type":["object","null"],"required":["slug","name","country","url"],"properties":{"slug":{"type":"string","description":"Destination PAGE slug (Sabi Sand and Kruger both report `south-africa`)."},"name":{"type":"string"},"country":{"type":["string","null"]},"url":{"type":"string","format":"uri"}}},"images":{"type":"object","required":["hero","gallery"],"properties":{"hero":{"oneOf":[{"type":"object","required":["url","alt"],"properties":{"url":{"type":"string","format":"uri","description":"Absolute image URL."},"alt":{"type":["string","null"]}}},{"type":"null"}]},"gallery":{"type":"array","items":{"type":"object","required":["url","alt"],"properties":{"url":{"type":"string","format":"uri","description":"Absolute image URL."},"alt":{"type":["string","null"]}}}}}},"duration_days":{"type":["integer","null"],"description":"Fixed itinerary length; null when the stay is variable."},"capacity":{"type":"object","properties":{"min":{"type":["integer","null"]},"max":{"type":["integer","null"]}}},"pricing":{"type":"object","required":["mode","from","note","display"],"properties":{"mode":{"type":"string","enum":["flat","per_person","per_night","per_person_per_night"],"description":"How `from.amount` multiplies out: flat = whole party; per_person × guests; per_night × nights; per_person_per_night × guests × nights."},"from":{"type":"object","properties":{"amount":{"type":["number","null"],"description":"The RATE for `mode`, in major units. Null means price on request."},"currency":{"type":"string","examples":["USD","AED"]}}},"note":{"type":["string","null"],"description":"Merchandising note, e.g. \"+ VAT\"."},"display":{"type":"string","examples":["From USD 12,500 per person","Price on request"]}}},"availability":{"type":"object","required":["mode","note","duration_days"],"properties":{"mode":{"type":"string","enum":["on_request"]},"note":{"type":"string","examples":["Dates are confirmed privately by the Zameera team; enquire to check availability."]},"duration_days":{"type":["integer","null"]}}},"updated_at":{"type":"string","format":"date-time"}}},"ExperienceDetail":{"allOf":[{"$ref":"#/components/schemas/ExperienceSummary"},{"type":"object","properties":{"description":{"type":["string","null"]},"overview":{"type":["object","null"],"description":"The long-form editorial block, resolved exactly as the website resolves it.","properties":{"eyebrow":{"type":"string"},"heading":{"type":"string"},"body":{"type":"string"},"cards":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"body":{"type":"string"},"image":{"type":["string","null"],"format":"uri"}}}},"key_info":{"type":"array","items":{"type":"string"}},"price_line":{"type":["string","null"]},"itinerary":{"type":["object","null"],"properties":{"eyebrow":{"type":"string"},"heading":{"type":"string"},"body":{"type":"string"},"days":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"body":{"type":"string"},"image":{"type":["string","null"],"format":"uri"}}}}}},"before_you_go":{"type":"object","properties":{"place":{"type":"string"},"items":{"type":"array","items":{"type":"object","required":["label","value"],"properties":{"label":{"type":"string"},"value":{"type":"string"}}}}}}}},"tiles":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"body":{"type":"string"},"image":{"type":["string","null"],"format":"uri"}}}},"facts":{"type":"array","items":{"type":"object","required":["label","value"],"properties":{"label":{"type":"string"},"value":{"type":"string"}}}},"features":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"body":{"type":"string"},"image":{"type":["string","null"],"format":"uri"}}}},"day_phases":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"body":{"type":"string"}}}},"story":{"type":["object","null"],"properties":{"eyebrow":{"type":"string"},"title":{"type":"string"}}}}}]},"DestinationSummary":{"type":"object","required":["slug","name","country","url","experience_count"],"properties":{"slug":{"type":"string","description":"Public page slug."},"name":{"type":"string"},"country":{"type":["string","null"]},"url":{"type":"string","format":"uri"},"hero_image":{"type":["string","null"],"format":"uri"},"summary":{"type":["string","null"],"description":"The destination page's intro paragraph."},"coordinates":{"type":["object","null"],"properties":{"lat":{"type":"number"},"lng":{"type":"number"}}},"experience_count":{"type":"integer"}}},"DestinationDetail":{"allOf":[{"$ref":"#/components/schemas/DestinationSummary"},{"type":"object","properties":{"intro":{"type":["object","null"],"properties":{"heading":{"type":"string"},"body":{"type":"string"},"images":{"type":"array","items":{"type":"object","required":["url","alt"],"properties":{"url":{"type":"string","format":"uri","description":"Absolute image URL."},"alt":{"type":["string","null"]}}}}}},"destination":{"type":["object","null"],"description":"The long-form 'about the destination' section.","properties":{"heading":{"type":"string"},"paragraphs":{"type":"array","items":{"type":"string"}},"image":{"oneOf":[{"type":"object","required":["url","alt"],"properties":{"url":{"type":"string","format":"uri","description":"Absolute image URL."},"alt":{"type":["string","null"]}}},{"type":"null"}]}}},"facts":{"type":"array","items":{"type":"object","required":["label","value"],"properties":{"label":{"type":"string"},"value":{"type":"string"}}}},"experiences":{"type":"array","items":{"$ref":"#/components/schemas/ExperienceSummary"}}}}]},"BookingRequest":{"type":"object","required":["experience","dates","guests","customer"],"properties":{"experience":{"type":"string","description":"The experience slug, as returned by `GET /experiences`.","example":"the-humble-silverback"},"dates":{"type":"object","required":["start"],"properties":{"start":{"type":"string","format":"date","description":"Arrival date, YYYY-MM-DD. Today or later."},"end":{"type":"string","format":"date","description":"Departure date, YYYY-MM-DD, after `start`. Optional: a fixed-length experience derives it from its own duration when omitted."}}},"guests":{"description":"Party size — an integer, or `{ \"adults\": n, \"children\": n }`. 1 to 50.","oneOf":[{"type":"integer","minimum":1,"maximum":50},{"type":"object","required":["adults"],"properties":{"adults":{"type":"integer","minimum":1},"children":{"type":"integer","minimum":0,"default":0}}}]},"customer":{"type":"object","required":["name","email"],"properties":{"name":{"type":"string","maxLength":200},"email":{"type":"string","format":"email"},"phone":{"type":["string","null"],"maxLength":40,"description":"International format preferred, e.g. +44 7700 900123."},"country":{"type":["string","null"],"maxLength":100,"description":"Country of residence — ISO 3166-1 alpha-2 or a name."},"language":{"type":["string","null"],"maxLength":40,"description":"Preferred language for Zameera's correspondence, e.g. `en`, `fr`."},"nationality":{"type":["string","null"],"maxLength":100}}},"special_requests":{"type":["string","null"],"maxLength":2000,"description":"Free text passed verbatim to the Zameera team."},"partner_reference":{"type":["string","null"],"maxLength":100,"description":"Your own reference for this booking; echoed back on every read."},"notify_guest":{"type":"boolean","default":true,"description":"Send the guest Zameera's 'request received' email. Set false to keep all guest correspondence on your side until we confirm."},"marketing_opt_in":{"type":"boolean","default":false,"description":"The guest has agreed to hear from Zameera. Never assume this."}}},"Booking":{"type":"object","required":["reference","status","payment_status","experience","dates","guests","estimate","customer","source","created_at","updated_at","confirmation_url"],"properties":{"reference":{"type":"string","description":"Zameera's booking reference, e.g. `ZAM-7K2QMD`. Quote it in any correspondence."},"status":{"type":"string","enum":["enquiry","pending","confirmed","in_progress","completed","cancelled"],"description":"`enquiry`/`pending` — received, awaiting Zameera's confirmation. `confirmed` — dates and price agreed. `in_progress` — the guest is travelling. `completed`. `cancelled`."},"payment_status":{"type":"string","enum":["unpaid","processing","paid","refunded","failed"],"description":"Independent of `status`: a booking can be `paid` while still `pending` confirmation."},"experience":{"type":["object","null"],"required":["slug","title","url"],"properties":{"slug":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"}}},"dates":{"type":"object","required":["start","end","nights"],"properties":{"start":{"type":["string","null"],"format":"date"},"end":{"type":["string","null"],"format":"date"},"nights":{"type":["integer","null"]}}},"guests":{"type":"integer"},"estimate":{"type":["object","null"],"description":"Approximate cost from the published rate; null when the experience is price-on-request.","required":["amount","currency","display","note"],"properties":{"amount":{"type":"number","description":"Major units, e.g. 134000 = USD 134,000."},"currency":{"type":"string","description":"ISO 4217."},"display":{"type":"string","example":"USD 134,000"},"note":{"type":"string","example":"Approximate, computed from the published rate. Zameera confirms the final price with the guest before any payment is requested."}}},"customer":{"type":"object","required":["name","email","phone","country","language"],"properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"country":{"type":["string","null"]},"language":{"type":["string","null"]}}},"special_requests":{"type":["string","null"]},"partner_reference":{"type":["string","null"]},"source":{"type":"string","enum":["api"],"description":"Always `api` for bookings visible here."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":["string","null"],"format":"date-time"},"cancelled_at":{"type":["string","null"],"format":"date-time"},"confirmation_url":{"type":"string","format":"uri","description":"The guest-facing page for this request on zameera.com."}}}}}}