openapi: 3.1.0
x-provenance:
generated: '2026-07-19'
method: generated
source: https://github.com/headout/api-docs
note: >-
Headout publishes no OpenAPI. This spec was faithfully generated from the
public Partner API documentation at github.com/headout/api-docs (conventions,
apis/v1, apis/v2, error-handling). Only documented operations, parameters,
and the documented error envelope are included; nothing was invented.
info:
title: Headout Partner API
version: '2.0'
description: >-
Headout's public Partner API for accessing the experiences marketplace:
products, categories, collections and subcategories (v2), plus inventory &
pricing and the two-step booking flow (v1). Partners authenticate with a
Headout-Auth API key. Production keys are prefixed pk_ and testing keys tk_.
contact:
name: Headout Partnerships
email: partnerships@headout.com
url: https://github.com/headout/api-docs
termsOfService: https://www.headout.com/terms-of-use/
servers:
- url: https://www.headout.com
description: Production
- url: https://sandbox.api.test-headout.com
description: Sandbox / testing (use tk_ keys)
security:
- HeadoutAuth: []
tags:
- name: Products
- name: Categories
- name: Collections
- name: Subcategories
- name: Inventory
- name: Booking
paths:
/api/public/v2/products:
get:
operationId: listProducts
tags: [Products]
summary: List products for a city
description: Fetch products for a given city, optionally filtered by collection, category or subcategory.
parameters:
- { name: cityCode, in: query, required: true, schema: { type: string }, description: The city code to fetch products for. }
- { name: collectionId, in: query, required: false, schema: { type: string } }
- { name: categoryId, in: query, required: false, schema: { type: string } }
- { name: subCategoryId, in: query, required: false, schema: { type: string } }
- { name: languageCode, in: query, required: false, schema: { type: string, default: EN } }
- { name: currencyCode, in: query, required: false, schema: { type: string } }
- { name: campaignName, in: query, required: false, schema: { type: string } }
- { $ref: '#/components/parameters/Offset' }
- { $ref: '#/components/parameters/Limit' }
responses:
'200':
description: Paginated list of products
content:
application/json:
schema: { $ref: '#/components/schemas/ProductPage' }
'400': { $ref: '#/components/responses/BadRequest' }
'401': { $ref: '#/components/responses/Unauthorized' }
/api/public/v2/categories:
get:
operationId: listCategories
tags: [Categories]
summary: List categories for a city
parameters:
- { name: cityCode, in: query, required: true, schema: { type: string } }
- { name: languageCode, in: query, required: false, schema: { type: string, default: EN } }
- { $ref: '#/components/parameters/Offset' }
- { $ref: '#/components/parameters/Limit' }
responses:
'200':
description: Paginated list of categories
content: { application/json: { schema: { $ref: '#/components/schemas/CategoryPage' } } }
'400': { $ref: '#/components/responses/BadRequest' }
/api/public/v2/collections:
get:
operationId: listCollections
tags: [Collections]
summary: List collections for a city
parameters:
- { name: cityCode, in: query, required: true, schema: { type: string } }
- { name: languageCode, in: query, required: false, schema: { type: string, default: EN } }
- { $ref: '#/components/parameters/Offset' }
- { $ref: '#/components/parameters/Limit' }
responses:
'200':
description: Paginated list of collections
content: { application/json: { schema: { $ref: '#/components/schemas/CollectionPage' } } }
'400': { $ref: '#/components/responses/BadRequest' }
/api/public/v2/subcategories:
get:
operationId: listSubcategories
tags: [Subcategories]
summary: List subcategories for a city
parameters:
- { name: cityCode, in: query, required: true, schema: { type: string } }
- { name: languageCode, in: query, required: false, schema: { type: string, default: EN } }
- { $ref: '#/components/parameters/Offset' }
- { $ref: '#/components/parameters/Limit' }
responses:
'200':
description: Paginated list of subcategories
content: { application/json: { schema: { $ref: '#/components/schemas/SubcategoryPage' } } }
'400': { $ref: '#/components/responses/BadRequest' }
/api/public/v1/inventory/list-by/variant:
get:
operationId: listInventoryByVariant
tags: [Inventory]
summary: List inventory and pricing by variant
description: Fetch availability and pricing for a variant across a date-time window.
security: []
parameters:
- { name: variantId, in: query, required: true, schema: { type: string }, description: The ID of the variant for which the inventory needs to be fetched. }
- { name: startDateTime, in: query, required: false, schema: { type: string }, description: fm-date-time; defaults to current timestamp. }
- { name: endDateTime, in: query, required: false, schema: { type: string }, description: fm-date-time; defaults to infinity if unspecified. }
- { name: currencyCode, in: query, required: false, schema: { type: string }, description: ISO 4217 currency code (e.g. USD, AED). }
- { $ref: '#/components/parameters/Offset' }
- { $ref: '#/components/parameters/Limit' }
responses:
'200':
description: Paginated list of inventory records
content: { application/json: { schema: { $ref: '#/components/schemas/InventoryPage' } } }
'400': { $ref: '#/components/responses/BadRequest' }
/api/public/v1/booking:
get:
operationId: listBookings
tags: [Booking]
summary: List bookings
parameters:
- { $ref: '#/components/parameters/Offset' }
- { $ref: '#/components/parameters/Limit' }
responses:
'200':
description: Paginated list of bookings
content: { application/json: { schema: { $ref: '#/components/schemas/BookingPage' } } }
'401': { $ref: '#/components/responses/Unauthorized' }
post:
operationId: createBooking
tags: [Booking]
summary: Create a booking (step 1)
description: >-
Creates a booking in UNCAPTURED state. Capture it within 60 minutes via
updateBooking or it transitions to CAPTURE_TIMEOUT.
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/BookingCreateRequest' }
responses:
'200':
description: Booking created in UNCAPTURED state
content: { application/json: { schema: { $ref: '#/components/schemas/Booking' } } }
'400': { $ref: '#/components/responses/BadRequest' }
'401': { $ref: '#/components/responses/Unauthorized' }
/api/public/v1/booking/{id}:
get:
operationId: getBooking
tags: [Booking]
summary: Retrieve a booking
parameters:
- { name: id, in: path, required: true, schema: { type: string }, description: The booking identifier. }
responses:
'200':
description: A single booking
content: { application/json: { schema: { $ref: '#/components/schemas/Booking' } } }
'401': { $ref: '#/components/responses/Unauthorized' }
'404': { $ref: '#/components/responses/NotFound' }
put:
operationId: updateBooking
tags: [Booking]
summary: Capture / update a booking (step 2)
description: >-
Capture a booking by setting status to PENDING, optionally attaching a
partnerReferenceId. Idempotent — step 2 may be retried until it succeeds.
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/BookingUpdateRequest' }
responses:
'200':
description: Booking transitioned to PENDING
content: { application/json: { schema: { $ref: '#/components/schemas/Booking' } } }
'400': { $ref: '#/components/responses/BadRequest' }
'401': { $ref: '#/components/responses/Unauthorized' }
'404': { $ref: '#/components/responses/NotFound' }
components:
securitySchemes:
HeadoutAuth:
type: apiKey
in: header
name: Headout-Auth
description: API token. Production keys are prefixed pk_, testing keys tk_.
parameters:
Offset:
name: offset
in: query
required: false
schema: { type: integer, default: 0 }
description: Pagination offset.
Limit:
name: limit
in: query
required: false
schema: { type: integer, default: 20 }
description: Pagination limit.
responses:
BadRequest:
description: Bad request
content:
application/json:
schema: { $ref: '#/components/schemas/Error' }
Unauthorized:
description: Missing or invalid Headout-Auth token
content:
application/json:
schema: { $ref: '#/components/schemas/Error' }
NotFound:
description: Resource not found
content:
application/json:
schema: { $ref: '#/components/schemas/Error' }
schemas:
Error:
type: object
description: Headout error envelope.
properties:
status: { type: integer }
error:
type: object
properties:
code: { type: string }
message: { type: string }
Pagination:
type: object
properties:
nextUrl: { type: string }
prevUrl: { type: string }
total: { type: integer }
nextOffset: { type: integer }
Product:
type: object
properties:
id: { type: string }
name: { type: string }
cityCode: { type: string }
categoryId: { type: string }
subCategoryId: { type: string }
collectionId: { type: string }
ProductPage:
allOf:
- $ref: '#/components/schemas/Pagination'
- type: object
properties:
products: { type: array, items: { $ref: '#/components/schemas/Product' } }
Category:
type: object
properties:
id: { type: string }
name: { type: string }
cityCode: { type: string }
CategoryPage:
allOf:
- $ref: '#/components/schemas/Pagination'
- type: object
properties:
items: { type: array, items: { $ref: '#/components/schemas/Category' } }
Collection:
type: object
properties:
id: { type: string }
name: { type: string }
cityCode: { type: string }
CollectionPage:
allOf:
- $ref: '#/components/schemas/Pagination'
- type: object
properties:
items: { type: array, items: { $ref: '#/components/schemas/Collection' } }
Subcategory:
type: object
properties:
id: { type: string }
name: { type: string }
categoryId: { type: string }
cityCode: { type: string }
SubcategoryPage:
allOf:
- $ref: '#/components/schemas/Pagination'
- type: object
properties:
items: { type: array, items: { $ref: '#/components/schemas/Subcategory' } }
Inventory:
type: object
properties:
id: { type: string }
startDateTime: { type: string }
endDateTime: { type: string }
availability: { type: string, enum: [LIMITED, UNLIMITED, CLOSED] }
remaining: { type: integer }
pricing:
type: object
properties:
persons: { type: object }
groups: { type: object }
InventoryPage:
allOf:
- $ref: '#/components/schemas/Pagination'
- type: object
properties:
items: { type: array, items: { $ref: '#/components/schemas/Inventory' } }
Booking:
type: object
properties:
id: { type: string }
status: { type: string, enum: [UNCAPTURED, PENDING, COMPLETED, CAPTURE_TIMEOUT] }
variantId: { type: string }
inventoryId: { type: string }
partnerReferenceId: { type: string }
BookingPage:
allOf:
- $ref: '#/components/schemas/Pagination'
- type: object
properties:
items: { type: array, items: { $ref: '#/components/schemas/Booking' } }
BookingCreateRequest:
type: object
required: [variantId, inventoryId, price]
properties:
variantId: { type: string }
inventoryId: { type: string }
customersDetails: { type: object }
variantInputFields: { type: object }
price: { type: object }
BookingUpdateRequest:
type: object
required: [status]
properties:
status: { type: string, enum: [PENDING] }
partnerReferenceId: { type: string }