# Understory API

This is the reference documentation for the Understory API.
Here you can find detailed information about the API endpoints, request and response formats, and authentication methods.

For more general information, go to [Documentation](/docs).

{% admonition type="success" name="Preview and Alpha" %}
Some parts of the Understory API is still under active development.

Refer to [API Versioning](docs/about/api-versioning) for details on what you can expect from endpoints and webhooks marked with `Preview` and `Alpha`.

Want to help us test and improve it? Share your feedback by clicking the chat icon in the bottom right. We’d love to hear your thoughts!
{% /admonition %}


License: Apache 2.0

## Servers

```
https://api.understory.io
```

## Security

### OAuth2

OAuth2 authentication using the client credentials flow

Type: oauth2

## Download OpenAPI description

[Understory API](https://developer.understory.io/_bundle/apis/index.yaml)

## Accounting

Accounting exposes financial transactions recorded against bookings and gift cards as journal entries.

Each journal entry carries the postings, references, and supporting documents needed to sync financial activity
into external accounting and bookkeeping systems.

> **Note:** Access to the Accounting API requires an active accounting subscription.


### Get journal entry

 - [GET /v1/accounting-journal-entries/{journalEntryId}](https://developer.understory.io/apis/accounting/getjournalentrybyid.md): Get a single journal entry by its ID. Returns the postings, references,
and supporting documents required to sync the entry to an external
accounting integration.

### Record a journal entry activity

 - [POST /v1/accounting-journal-entries/{journalEntryId}/activities](https://developer.understory.io/apis/accounting/recordjournalentryactivity.md): Record an activity item against a journal entry. Integrations can use
this to relay how an entry was processed in an external accounting
system - for example that a sync started, succeeded, or failed. The
recorded activity surfaces on the entry's activity feed and drives its
sync status.

Supply a stable activity_id to make retries idempotent: recording the
same activity_id again has no further effect.

### Journal Entry created

 - [POST v1.journal_entry.created](https://developer.understory.io/apis/accounting/journalentrycreated.md): Sent when a new accounting journal entry has been recorded.

### Journal Entry document attached

 - [POST v1.journal_entry.document_attached](https://developer.understory.io/apis/accounting/journalentrydocumentattached.md): Sent when a supporting document - such as a customer receipt or credit
note - is attached to an existing journal entry. Documents can be
attached after the entry was first recorded, so re-fetch the entry to
pick up the newly attached document.

### Journal Entry created

 - [POST v1.journal_entry.created](https://developer.understory.io/apis/webhook/journalentrycreated.md): Sent when a new accounting journal entry has been recorded.

### Journal Entry document attached

 - [POST v1.journal_entry.document_attached](https://developer.understory.io/apis/webhook/journalentrydocumentattached.md): Sent when a supporting document - such as a customer receipt or credit
note - is attached to an existing journal entry. Documents can be
attached after the entry was first recorded, so re-fetch the entry to
pick up the newly attached document.

## Webhook

Webhook subscription management and event delivery.

Webhooks are sent to subscriber endpoints when events occur related to
experiences, events, and bookings.


### Journal Entry created

 - [POST v1.journal_entry.created](https://developer.understory.io/apis/accounting/journalentrycreated.md): Sent when a new accounting journal entry has been recorded.

### Journal Entry document attached

 - [POST v1.journal_entry.document_attached](https://developer.understory.io/apis/accounting/journalentrydocumentattached.md): Sent when a supporting document - such as a customer receipt or credit
note - is attached to an existing journal entry. Documents can be
attached after the entry was first recorded, so re-fetch the entry to
pick up the newly attached document.

### Booking created

 - [POST v1.booking.created](https://developer.understory.io/apis/booking/bookingcreated.md): Sent when a new booking is created.

### Booking updated

 - [POST v1.booking.updated](https://developer.understory.io/apis/booking/bookingupdated.md): Sent when a booking is updated.

### Booking cancelled

 - [POST v1.booking.cancelled](https://developer.understory.io/apis/booking/bookingcancelled.md): Sent when a booking is cancelled.

### Event created

 - [POST v1.event.created](https://developer.understory.io/apis/event/eventcreated.md): Sent when a new event is created for an experience.

### Event updated

 - [POST v1.event.updated](https://developer.understory.io/apis/event/eventupdated.md): Sent when an event is updated.

### Event cancelled

 - [POST v1.event.cancelled](https://developer.understory.io/apis/event/eventcancelled.md): Sent when an event is cancelled.

### Event completed

 - [POST v1.event.completed](https://developer.understory.io/apis/event/eventcompleted.md): Sent when an event has completed.

For single-session events, this is triggered when the session's end time is reached.
For multi-session events, this is triggered when the last session's end time is reached.

### Event deleted

 - [POST v1.event.deleted](https://developer.understory.io/apis/event/eventdeleted.md): Sent when an event is deleted.

### Experience created

 - [POST v1.experience.created](https://developer.understory.io/apis/experience/experiencecreated.md): Sent when a new experience is created.

### Experience updated

 - [POST v1.experience.updated](https://developer.understory.io/apis/experience/experienceupdated.md): Sent when an experience is updated.

### Experience deleted

 - [POST v1.experience.deleted](https://developer.understory.io/apis/experience/experiencedeleted.md): Sent when an experience is deleted.

### Marketing consent created

 - [POST v1.marketing_consent.created](https://developer.understory.io/apis/marketing/marketingconsentcreated.md): Sent when a new marketing consent is submitted.

This webhook is triggered every time a consent is submitted, even if the
email already exists. This allows external marketing systems to resubscribe
users who may have been unsubscribed externally.

### List Webhook Subscriptions

 - [GET /v1/webhook-subscriptions](https://developer.understory.io/apis/webhook/listwebhooksubscriptions.md): Retrieve all webhook subscriptions for the current organization.

### Create Webhook Subscription

 - [POST /v1/webhook-subscriptions](https://developer.understory.io/apis/webhook/createwebhooksubscription.md): Create a new webhook subscription to receive event notifications at the specified URL.

### Get Webhook Subscription

 - [GET /v1/webhook-subscriptions/{subscriptionId}](https://developer.understory.io/apis/webhook/getwebhooksubscription.md): Retrieve details of a specific webhook subscription.

### Update Webhook Subscription

 - [PUT /v1/webhook-subscriptions/{subscriptionId}](https://developer.understory.io/apis/webhook/updatewebhooksubscription.md): Update the configuration of an existing webhook subscription.

### Delete Webhook Subscription

 - [DELETE /v1/webhook-subscriptions/{subscriptionId}](https://developer.understory.io/apis/webhook/deletewebhooksubscription.md): Permanently delete a webhook subscription. This will stop all webhook deliveries for this subscription.

### Event created

 - [POST v1.event.created](https://developer.understory.io/apis/webhook/eventcreated.md): Sent when a new event is created for an experience.

### Event updated

 - [POST v1.event.updated](https://developer.understory.io/apis/webhook/eventupdated.md): Sent when an event is updated.

### Event cancelled

 - [POST v1.event.cancelled](https://developer.understory.io/apis/webhook/eventcancelled.md): Sent when an event is cancelled.

### Event completed

 - [POST v1.event.completed](https://developer.understory.io/apis/webhook/eventcompleted.md): Sent when an event has completed.

For single-session events, this is triggered when the session's end time is reached.
For multi-session events, this is triggered when the last session's end time is reached.

### Event deleted

 - [POST v1.event.deleted](https://developer.understory.io/apis/webhook/eventdeleted.md): Sent when an event is deleted.

### Experience created

 - [POST v1.experience.created](https://developer.understory.io/apis/webhook/experiencecreated.md): Sent when a new experience is created.

### Experience updated

 - [POST v1.experience.updated](https://developer.understory.io/apis/webhook/experienceupdated.md): Sent when an experience is updated.

### Experience deleted

 - [POST v1.experience.deleted](https://developer.understory.io/apis/webhook/experiencedeleted.md): Sent when an experience is deleted.

### Booking created

 - [POST v1.booking.created](https://developer.understory.io/apis/webhook/bookingcreated.md): Sent when a new booking is created.

### Booking updated

 - [POST v1.booking.updated](https://developer.understory.io/apis/webhook/bookingupdated.md): Sent when a booking is updated.

### Booking cancelled

 - [POST v1.booking.cancelled](https://developer.understory.io/apis/webhook/bookingcancelled.md): Sent when a booking is cancelled.

### Journal Entry created

 - [POST v1.journal_entry.created](https://developer.understory.io/apis/webhook/journalentrycreated.md): Sent when a new accounting journal entry has been recorded.

### Journal Entry document attached

 - [POST v1.journal_entry.document_attached](https://developer.understory.io/apis/webhook/journalentrydocumentattached.md): Sent when a supporting document - such as a customer receipt or credit
note - is attached to an existing journal entry. Documents can be
attached after the entry was first recorded, so re-fetch the entry to
pick up the newly attached document.

### Marketing consent created

 - [POST v1.marketing_consent.created](https://developer.understory.io/apis/webhook/marketingconsentcreated.md): Sent when a new marketing consent is submitted.

This webhook is triggered every time a consent is submitted, even if the
email already exists. This allows external marketing systems to resubscribe
users who may have been unsubscribed externally.

## Booking

A Booking is a customer's reservation against an Event.

Each Booking carries the customer details, the items the customer chose (ticket variants and add-ons),
and the lifecycle status of the reservation. Tickets are issued per booking and can be checked in when the customer arrives.


### Get Bookings

 - [GET /v1/bookings](https://developer.understory.io/apis/booking/getbookings.md): Get all bookings.

### Create Booking

 - [POST /v1/bookings](https://developer.understory.io/apis/booking/createbooking.md): Create a new booking for an event.

### Get Booking

 - [GET /v1/bookings/{bookingId}](https://developer.understory.io/apis/booking/getbooking.md): Get a booking by its ID.

### Get Information Request Answers

 - [GET /v1/bookings/{bookingId}/information-request-answers](https://developer.understory.io/apis/booking/getinformationrequestanswers.md): Get answers to information requests for a booking.

Each answer corresponds to a question defined as an information request in the Experience API.

### Get Tickets

 - [GET /v1/bookings/{bookingId}/tickets](https://developer.understory.io/apis/booking/gettickets.md): Get all tickets for a booking.

### Booking created

 - [POST v1.booking.created](https://developer.understory.io/apis/booking/bookingcreated.md): Sent when a new booking is created.

### Booking updated

 - [POST v1.booking.updated](https://developer.understory.io/apis/booking/bookingupdated.md): Sent when a booking is updated.

### Booking cancelled

 - [POST v1.booking.cancelled](https://developer.understory.io/apis/booking/bookingcancelled.md): Sent when a booking is cancelled.

### Booking created

 - [POST v1.booking.created](https://developer.understory.io/apis/webhook/bookingcreated.md): Sent when a new booking is created.

### Booking updated

 - [POST v1.booking.updated](https://developer.understory.io/apis/webhook/bookingupdated.md): Sent when a booking is updated.

### Booking cancelled

 - [POST v1.booking.cancelled](https://developer.understory.io/apis/webhook/bookingcancelled.md): Sent when a booking is cancelled.

## Event Availability

Query availability for events.

Availability is computed from multiple inputs — the event's lifecycle state, its remaining seat capacity,
configured booking limits, the booking cutoff, and the per-ticket-variant resource limits.
The response always returns every applicable constraint (both passing and failing), so callers can tell
exactly *why* an event is or is not bookable.


### Get Event Availability

 - [GET /v1/event-availabilities/{eventId}](https://developer.understory.io/apis/event-availability/geteventavailability.md): Get the availability for a single event.

Returns availability information including remaining seats and constraints.

### List Event Availability

 - [GET /v1/event-availabilities](https://developer.understory.io/apis/event-availability/listeventavailability.md): Get availability for events of an experience.

Use this when you need availability for many events at once — for example, when rendering a
calendar. For a single event, prefer GET /v1/event-availabilities/{eventId}. The response is paginated;
pass the returned next cursor on subsequent calls to continue.

## Event

An Event is a scheduled, bookable instance of an Experience.

Each Event has a lifecycle state, a visibility, a capacity that is shared across all of its sessions,
and one or more Sessions describing when and where it takes place. Bookings are made against an Event.


### Get events

 - [GET /v1/events](https://developer.understory.io/apis/event/getevents.md): Get all events.

The response includes events in every non-deleted lifecycle state (ACTIVE, INACTIVE, CANCELLED, COMPLETED);
apply state filtering client-side if you only want bookable events.

Results are ordered by session start time. Each event is returned once,
positioned by its earliest session that matches the from/to window.

### Get event

 - [GET /v1/events/{eventId}](https://developer.understory.io/apis/event/getevent.md): Get an event by its ID.

### Event created

 - [POST v1.event.created](https://developer.understory.io/apis/event/eventcreated.md): Sent when a new event is created for an experience.

### Event updated

 - [POST v1.event.updated](https://developer.understory.io/apis/event/eventupdated.md): Sent when an event is updated.

### Event cancelled

 - [POST v1.event.cancelled](https://developer.understory.io/apis/event/eventcancelled.md): Sent when an event is cancelled.

### Event completed

 - [POST v1.event.completed](https://developer.understory.io/apis/event/eventcompleted.md): Sent when an event has completed.

For single-session events, this is triggered when the session's end time is reached.
For multi-session events, this is triggered when the last session's end time is reached.

### Event deleted

 - [POST v1.event.deleted](https://developer.understory.io/apis/event/eventdeleted.md): Sent when an event is deleted.

### Event created

 - [POST v1.event.created](https://developer.understory.io/apis/webhook/eventcreated.md): Sent when a new event is created for an experience.

### Event updated

 - [POST v1.event.updated](https://developer.understory.io/apis/webhook/eventupdated.md): Sent when an event is updated.

### Event cancelled

 - [POST v1.event.cancelled](https://developer.understory.io/apis/webhook/eventcancelled.md): Sent when an event is cancelled.

### Event completed

 - [POST v1.event.completed](https://developer.understory.io/apis/webhook/eventcompleted.md): Sent when an event has completed.

For single-session events, this is triggered when the session's end time is reached.
For multi-session events, this is triggered when the last session's end time is reached.

### Event deleted

 - [POST v1.event.deleted](https://developer.understory.io/apis/webhook/eventdeleted.md): Sent when an event is deleted.

## Experience

An Experience is the product a company offers — for example, a guided tour, a workshop, or a tasting.

Experiences are templates: each Experience produces one or more Events (scheduled instances) that customers actually book.
This API exposes experiences along with their information requests and ticket variants.


### Get experiences

 - [GET /v1/experiences](https://developer.understory.io/apis/experience/getexperiences.md): Get all experiences for the company.

Returns experiences in any non-deleted lifecycle state, including INACTIVE and ARCHIVED.
Filter by state client-side if you only want bookable experiences. The response is paginated;
pass the returned next cursor on subsequent calls to continue.

### Get experience

 - [GET /v1/experiences/{experienceId}](https://developer.understory.io/apis/experience/getexperiencebyid.md): Get an experience by its ID.

### Get information requests

 - [GET /v1/experiences/{experienceId}/information-requests](https://developer.understory.io/apis/experience/getinformationrequestsforexperience.md): Get the information requests configured for an experience.

Information requests describe the additional questions a guest answers during the booking flow.
Use them to render the booking form. The answers a guest actually provides are returned by
Get information request answers on a booking.

### Get ticket variants

 - [GET /v1/experiences/{experienceId}/ticket-variants](https://developer.understory.io/apis/experience/getticketvariantsforexperience.md): Get the ticket variants configured for an experience.

Ticket variants are the ticket options a guest can choose between when booking — the experience's
price catalog. Add-ons offered alongside a ticket are nested inside each variant. Pricing returned
here is the catalog price; the actual price for a specific event is finalized when the booking is created.

### Experience created

 - [POST v1.experience.created](https://developer.understory.io/apis/experience/experiencecreated.md): Sent when a new experience is created.

### Experience updated

 - [POST v1.experience.updated](https://developer.understory.io/apis/experience/experienceupdated.md): Sent when an experience is updated.

### Experience deleted

 - [POST v1.experience.deleted](https://developer.understory.io/apis/experience/experiencedeleted.md): Sent when an experience is deleted.

### Experience created

 - [POST v1.experience.created](https://developer.understory.io/apis/webhook/experiencecreated.md): Sent when a new experience is created.

### Experience updated

 - [POST v1.experience.updated](https://developer.understory.io/apis/webhook/experienceupdated.md): Sent when an experience is updated.

### Experience deleted

 - [POST v1.experience.deleted](https://developer.understory.io/apis/webhook/experiencedeleted.md): Sent when an experience is deleted.

## Gift Card

A Gift Card is a prepaid balance that a customer can redeem against future purchases.

Each Gift Card carries an initial value, a remaining balance, an expiry date, and a status describing where it is in its lifecycle.

An active Gift Card's expiry date can be pushed further out with the extend-expiry action. Its balance cannot be
changed through this API. Gift Cards that have already expired, been fully spent, or been voided are final.


### Get Gift Cards

 - [GET /v1/gift-cards](https://developer.understory.io/apis/gift-card/getgiftcards.md): Get all gift cards for the company.

### Get Gift Card

 - [GET /v1/gift-cards/{giftCardId}](https://developer.understory.io/apis/gift-card/getgiftcardbyid.md): Get a gift card by its ID.

### Extend Gift Card Expiry

 - [POST /v1/gift-cards/{giftCardId}/extend-expiry](https://developer.understory.io/apis/gift-card/extendgiftcardexpiry.md): Push an active gift card's expiry date further out.

The new expiry must be later than the gift card's current expiry — this action only extends
validity, it never shortens it. Only gift cards with status ACTIVE can be extended; a gift card
that has already expired, been fully spent, or been voided is final.

Re-sending the gift card's current expiry date has no effect and returns the gift card unchanged,
so a retried request is safe.

The change is recorded on the gift card's history and is visible to the company in Understory.

## Location

A Location is a place a company runs its experiences from, referenced by the `location_id` on every
session of an [Event](/apis/event/getevents).

Each Location carries a postal address, optional geographic coordinates, and the IANA time zone that
interprets its sessions' offset-free `start_time` and `end_time`. The time zone falls back to
`Europe/Copenhagen` when the company has not set one.


### Get Locations

 - [GET /v1/locations](https://developer.understory.io/apis/location/getlocations.md): Get all locations for the company.

### Get Location

 - [GET /v1/locations/{locationId}](https://developer.understory.io/apis/location/getlocationbyid.md): Get a location by its ID.

A removed location is no longer resolvable and returns 404.

## Marketing

Marketing endpoints expose data captured for marketing automation flows.

Today the API surfaces marketing consents collected through Understory checkouts —
use them to feed external mailing platforms, build segmented audiences, and reconcile opt-ins.


### Get marketing consents

 - [GET /v1/marketing-consents](https://developer.understory.io/apis/marketing/getmarketingconsents.md): Get all marketing consents collected through Understory checkouts.

### Get marketing consent by ID

 - [GET /v1/marketing-consents/{consentId}](https://developer.understory.io/apis/marketing/getmarketingconsentbyid.md): Get a single marketing consent by its unique identifier.

### Marketing consent created

 - [POST v1.marketing_consent.created](https://developer.understory.io/apis/marketing/marketingconsentcreated.md): Sent when a new marketing consent is submitted.

This webhook is triggered every time a consent is submitted, even if the
email already exists. This allows external marketing systems to resubscribe
users who may have been unsubscribed externally.

### Marketing consent created

 - [POST v1.marketing_consent.created](https://developer.understory.io/apis/webhook/marketingconsentcreated.md): Sent when a new marketing consent is submitted.

This webhook is triggered every time a consent is submitted, even if the
email already exists. This allows external marketing systems to resubscribe
users who may have been unsubscribed externally.

## Order

An Order represents the financial side of a purchase made through Understory.

Each Order is linked to its origin (a booking or a gift card purchase) and carries its line items,
transactions, and refunds. Use this API to reconcile payments, build invoices, and audit the financial trail.


### Get Orders

 - [GET /v1/orders](https://developer.understory.io/apis/order/getorders.md): Get all orders.

### Get Order

 - [GET /v1/orders/{orderId}](https://developer.understory.io/apis/order/getorder.md): Get an order by its ID.

### Get Line Items

 - [GET /v1/orders/{orderId}/line-items](https://developer.understory.io/apis/order/getlineitems.md): Get all line items for an order.

Resolving product names

Line items contain product references but not human-readable names. To resolve the name, use the product_type and details fields to determine which endpoint to call.

• TICKET and TICKET_ADDON: Extract experience_id from details, call Get ticket variants, and match product_id to a ticket variant or add-on.

• GIFTCARD: Use gift_card_id from details to call Get gift card by ID.

### Get Transactions

 - [GET /v1/orders/{orderId}/transactions](https://developer.understory.io/apis/order/gettransactions.md): Get all transactions for an order.

### Get Refunds

 - [GET /v1/orders/{orderId}/refunds](https://developer.understory.io/apis/order/getrefunds.md): Get all refunds for an order.

## Test

These endpoints are for testing purposes only.

You can use them to verify that your integration authentication works as intended.


### Who am I

 - [GET /v1/me](https://developer.understory.io/apis/test/getme.md): Get information about the current user.

