API reference
Events, orders and webhooks, for organisers, venues and professionals.
The Venued API is a small, deliberately narrow REST surface over data you
already own on Venued. Every key belongs to one principal — an
organiser account, a venue or a professional — and every response is
filtered to it.
GET /v1/me tells you which one a key is.
What this API deliberately cannot do
It cannot publish an event. POST and PATCH accept visibility of
draft or unlisted only; anything else is refused with 403 forbidden.
Publishing is a decision with a public consequence and a phone-verification
gate behind it, so it stays in the dashboard where the person making it can
see what they are about to make public.
⚠️ Note also that draft → unlisted is one-way. An event that has been
made unlisted cannot be returned to draft through this API or any other.
It cannot cancel an event. Cancelling notifies everyone interested in it and leaves paid ticket holders needing refunds, which this API cannot issue. It stays in Studio, where the person doing it sees who is affected.
It cannot touch money. Orders are read-only. There is no refund, no payout and no ticket issuance endpoint.
It cannot write server-owned fields. Anything not on the writable list
(see EventPatch) is silently dropped rather than rejected — including
ticketing, organizerId, priority and the embedding fields.
Getting a key
API keys are created from Studio (Business account → API), not through this
API. A key is shown once, at creation, and only its SHA-256 hash is
stored — Venued cannot recover or re-display it. Creating and revoking keys
requires the owner or org_manager role on an organiser account, and the
owner role on a venue or a professional.
A key looks like vnd_live_ followed by 48 hex characters.
Who can hold a key
A key belongs to a principal — an organiser, a venue or a
professional — and GET /v1/me tells you which. Authorisation is
scope ∧ principal type, not scope alone, and the second half is not
decoration:
-
Every business can hold an organiser key, whatever its kind. A venue or a professional is a business that organises too: its organiser key reads and writes the events it hosts, their orders and their attendees, exactly as any organiser's does. Its venue or professional keys come on top, for what it offers as a supplier.
-
events:readmeans my events to an organiser and the events at my address to a venue. Same scope string, different set. -
A venue key cannot be minted with
events:writeororders:readat all. A venue does not own the events booked into it, and the buyer names and emails on an order are the organiser's business, not the building's. -
A venue can subscribe to webhooks, for
event.published(an event at the venue's address became public, alongside the organiser's own delivery of the same event) and the supplier side of its deals:enquiry.received,enquiry.quoted,enquiry.countered,enquiry.accepted,enquiry.declined,enquiry.withdrawn,booking.confirmedandbooking.cancelled. Neverorder.confirmed. -
What a venue sees at its own address:
- every
publicevent; - an
unlistedevent only when no real account chose to unlist it — that is, when it belongs to an unclaimed placeholder business or to no organiser at all. Most unlisted events are catalogue rows collected from public sources that nobody has hidden from anyone; an unlisted event owned by an active organiser is that organiser's deliberate choice, and stays hidden; - never a draft, whoever owns it. A draft is an organiser's private working copy.
Paging stays exact across that filter:
has_moreis observed rather than inferred, so a hidden row is never mistaken for the end of the list. - every
-
A professional key reads its own
/v1/profileand/v1/offerings, the enquiries sent to it, and may subscribe to the same supplier-side deal events as a venue. It cannot holdevents:*,orders:readorattendees:read. -
attendees:readis organiser-only: ticket holders' contact details are the organiser's, never the venue's.
Conventions
- Success bodies are
{"data": …}— all of them. - List bodies add
has_moreandnext_cursorbesidedata, on every list endpoint, including ones that cannot currently have a second page. One shape means one mapping in whatever tool you are wiring this into, rather than one per endpoint. - Error bodies are
{"error": "<code>", "message": "<sentence>", "request_id": "<id>"}.messageis for a human and may be reworded without notice; branch onerror.request_idis on every response as theX-Request-Idheader too — quote it when reporting a problem. Send your own and it is echoed rather than replaced, provided it is a plausible token of at most 64 characters. - Paging is by cursor. Pass
?limit=(max 100) and follownext_cursorinto?cursor=. A cursor is opaque and belongs to the query that produced it: it is refused withinvalid_cursorif the ordering changed under it, or if the row it anchors on was deleted. ?updated_after=is the poller's filter, on every list endpoint. ISO 8601 or epoch milliseconds, and it reorders the result byupdatedAtascending rather than the endpoint's default order — so changes arrive in the order they happened and the lastupdatedAtyou saw is the only state you need to keep.- An unknown query parameter is a
400 unsupported_parameter, never silently ignored. A filter that looks applied but is not is how a poller quietly ships every row it meant to exclude. - Money is in minor units, as an integer, beside a non-null uppercase
ISO-4217
currency.totalAmountMinor: 1999is €19.99. - Concurrency:
GET /v1/events/{eventId}returns anETag. Send it back asIf-Matchon thePATCHand an edit that would overwrite somebody else's change fails with412 precondition_failedinstead. OmittingIf-Matchstill succeeds. HEADis served whereverGETis: same status, same headers, no body. A405always carries anAllowheader naming what the path does accept.- Timestamps are ISO 8601 strings in responses. Requests accept either ISO 8601 or epoch milliseconds.
titleanddescriptionon an event are localized maps, not strings:{"EN": "Sunrise Run"}. Locale keys are normalised to UPPERCASE. Thetitlein a response is already flattened to a single string.
Changes
The reference above describes the API as it is. What changed, and when, is kept here rather than threaded through it.
2026-09-21 — all breaking, all made while production held no API keys or webhook subscriptions, so nobody had anything to migrate:
- Venue keys. A key belongs to a principal — an organiser or a venue — rather than always an organiser. See Who can hold a key.
- Paging. Every list is ordered and pageable by
cursor, withhas_moreandnext_cursor.GET /v1/eventswas previously unordered, so an organiser with more than 100 events had no way to reach the rest. - Money.
Order.totalAmount, a float in major units, becametotalAmountMinor, an integer. The float is not kept alongside it. DELETE /v1/webhooks/{webhookId}returns the{"data": …}envelope (it returned{"ok": true}, the only endpoint with its own shape) and is metered as a write (it was metered as a read).- Rate limits belong to the account, not the key. Minting a second key no longer doubles the budget.
- Webhook envelopes name their
principalinstead oforganizerId. A venue receivingorganizerId: "<its venue id>"would have been wrong.
Discovery
What this key can do.
/v1any valid keyWhat this key can reach
Returns the scopes on the calling key, the endpoint paths, the available webhook event types, the paging and filtering conventions and the current rate limits. Useful as a connectivity and permission check — it requires a valid key but no particular scope.
The endpoints map is derived from the route table the server
dispatches from, not maintained beside it, so it cannot describe a
surface the server does not serve.
Request
curl https://api.venued.eu/v1/v1 \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200Discovery document
401unauthorized— missing, malformed, unknown or revoked key.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/meany valid keyWho this key is
The principal this key acts as, and the scopes it was minted with.
Why this is separate from GET /v1
GET /v1 answers what can I reach — the endpoint map, the paging
conventions, the rate limits — and is the same for everybody. This
answers who am I, which is per key and is the thing an integration
branches on: a no-code step that must decide whether to offer event
actions or venue actions needs the principal, not the endpoint table.
Requires a valid key but no particular scope. A key that cannot tell you what it is cannot be debugged by the person holding it, and "which account is this key for" is the first question anybody asks when an integration has written to the wrong place.
Used inAPI keys
Request
curl https://api.venued.eu/v1/v1/me \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200The calling principal
401unauthorized— missing, malformed, unknown or revoked key.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
Events
/v1/eventsevents:readList events
Newest first, by startTime descending, and pageable with cursor.
Which events depends on the key: an organiser key lists the organiser's own events; a venue key lists the events at its address (see What a venue sees above).
⚠️ An event with no stored startTime is not returned. Nothing
reachable is hidden by that — an event without a start is not on the
site, in the app or in search either, and this API will not create
one.
With updated_after the order changes to updatedAt ascending; see
the conventions above.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
limit | query | integer, 1–100, default 50 | Clamped to 100. A missing, non-numeric, zero or negative value becomes the default of 50 rather than an error. |
cursor | query | string | The It is anchored to a specific row of a specific ordering, and it is
rejected with |
updated_after | query | string | Only rows whose ⚠️ This changes the ordering to |
Request
curl https://api.venued.eu/v1/v1/events \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200Events owned by this organiser, newest first
400unsupported_parameter— a query parameter this endpoint does not accept.invalid_cursor— a malformed cursor, one belonging to a different ordering, or one anchored to a row that no longer exists.invalid_argument—updated_afterwas not ISO 8601 or epoch ms.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/eventsevents:writeCreate a draft or unlisted event
Creates an event owned by the calling organiser.
Idempotency-Key is required. A retried request carrying a key that
already succeeded replays the stored response verbatim rather than
creating a second event. A key whose first attempt FAILED is treated as
fresh and re-run — only successful results are recorded — so a failed
create is safe to retry with the same key. Keys are scoped per organiser
and retained 7 days.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
Idempotency-Keyrequired | header | string | Any opaque string you generate per logical operation — a UUID is the usual choice. Scoped to your organiser account and retained 7 days. |
Request
curl -X POST https://api.venued.eu/v1/v1/events \
-H "Authorization: Bearer vnd_live_your_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"title": {
"EN": "Sunrise Run & Rave"
},
"startTime": "2026-11-21T18:00:00Z"
}'Responses
201Created
400idempotency_key_required— noIdempotency-Keyheader.invalid_argument—startTimemissing or unparseable, orendTimeunparseable.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope, orforbiddenwhenvisibilityis anything other thandraftorunlisted.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/events/{eventId}events:readFetch one event
⚠️ An event belonging to a different organiser returns 404 not_found,
not 403. That is deliberate: a 403 would confirm the id exists.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
eventIdrequired | path | string |
Request
curl https://api.venued.eu/v1/v1/events/{eventId} \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200The event
401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/events/{eventId}events:writeUpdate an event
Merges the writable fields of the body into the event. Fields outside
the writable list are dropped silently, not rejected — so a body of
nothing but server-owned keys is a 400 invalid_argument ("No writable
fields in the request body"), which is usually the sign of a typo'd
field name.
No Idempotency-Key is required: a PATCH of the same body is naturally
idempotent.
If-Match makes the edit conditional. Send the ETag you got from
GET /v1/events/{eventId} and the write applies only if nothing has
changed since; otherwise it is refused with 412 precondition_failed
and nothing is written. Without the header the write applies
unconditionally, exactly as before — this is opt-in protection against
two editors overwriting each other, not a new requirement.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
eventIdrequired | path | string | |
If-Match | header | string | An |
Request
curl -X PATCH https://api.venued.eu/v1/v1/events/{eventId} \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200The updated event
400invalid_argument— no writable fields in the body, orstartTime/endTimeunparseable.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope, orforbiddenwhenvisibilityis anything other thandraftorunlisted.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.412precondition_failed— theIf-Matchyou sent does not match the resource's currentETag, so somebody else changed it after you read it. Nothing was written. Re-read the resource, reapply your change to the new version, and retry.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
Orders
/v1/events/{eventId}/ordersorders:readConfirmed orders for one event
Only orders with status: "confirmed" are returned — pending, failed and
abandoned checkouts are not visible through this API.
Newest first, by createdAt descending, and pageable with cursor.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
eventIdrequired | path | string | |
limit | query | integer, 1–100, default 50 | Clamped to 100. A missing, non-numeric, zero or negative value becomes the default of 50 rather than an error. |
cursor | query | string | The It is anchored to a specific row of a specific ordering, and it is
rejected with |
updated_after | query | string | Only rows whose ⚠️ This changes the ordering to |
Request
curl https://api.venued.eu/v1/v1/events/{eventId}/orders \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200Confirmed orders for this event, newest first
400unsupported_parameter— a query parameter this endpoint does not accept.invalid_cursor— a malformed cursor, one belonging to a different ordering, or one anchored to a row that no longer exists.invalid_argument—updated_afterwas not ISO 8601 or epoch ms.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/events/{eventId}/attendeesattendees:readEveryone holding a ticket to one event, with contact details
One row per ticket, the unit the door scans, joined to its order: the buyer's name and email, and every answer to the event's checkout questions. A phone number appears here when you asked for one as a question; Venued holds no other phone for a buyer.
Nothing is filtered out. Refunded, transferred-away and cancelled
tickets come back with voided: true, so a door list rebuilt from this
is complete and a count can say what it excluded. People who hid
themselves from the public guest list are included: that setting is
about other guests, not about you.
Newest first by issue date; updated_after flips it to ascending on
updatedAt, which a check-in or a refund also moves.
⚠️ This is personal data about your guests. It leaves Venued the moment a key reads it, so keep the key where your guest list already lives.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
eventIdrequired | path | string | |
limit | query | integer, 1–100, default 50 | Clamped to 100. A missing, non-numeric, zero or negative value becomes the default of 50 rather than an error. |
cursor | query | string | The It is anchored to a specific row of a specific ordering, and it is
rejected with |
updated_after | query | string | Only rows whose ⚠️ This changes the ordering to |
Request
curl https://api.venued.eu/v1/v1/events/{eventId}/attendees \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200A page of attendees.
400unsupported_parameter— a query parameter this endpoint does not accept.invalid_cursor— a malformed cursor, one belonging to a different ordering, or one anchored to a row that no longer exists.invalid_argument—updated_afterwas not ISO 8601 or epoch ms.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/ordersorders:readConfirmed orders across all of this organiser's events
Newest first (createdAt descending). Confirmed orders only — pending,
failed and abandoned checkouts are never visible here.
This is the poll source a "new order" trigger in Zapier or Make needs;
the order.confirmed webhook is the push counterpart. A robust
integration usually wants both: the webhook for latency, and
?updated_after= to backfill whatever the receiver was down for.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
limit | query | integer, 1–100, default 50 | Clamped to 100. A missing, non-numeric, zero or negative value becomes the default of 50 rather than an error. |
cursor | query | string | The It is anchored to a specific row of a specific ordering, and it is
rejected with |
updated_after | query | string | Only rows whose ⚠️ This changes the ordering to |
Request
curl https://api.venued.eu/v1/v1/orders \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200Confirmed orders, newest first
400unsupported_parameter— a query parameter this endpoint does not accept.invalid_cursor— a malformed cursor, one belonging to a different ordering, or one anchored to a row that no longer exists.invalid_argument—updated_afterwas not ISO 8601 or epoch ms.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
Venues
For a venue key — the place, and what happens at it.
/v1/venuesevents:readThe venue this key is, and the places it is
A venue key's own record, with its locations resolved.
⚠️ Always exactly one entry today. A venue key's principal IS a venue, so "list" is one row. It carries the page envelope anyway, for the same reason every other list does: one mapping in a no-code tool beats one per endpoint.
url is built from the venue id, not its slug. Venue slug
uniqueness is not enforced — the Studio editor writes the field
directly — so a slug URL can resolve to a different venue. The slug is
published as a field for display; it is not the link.
Request
curl https://api.venued.eu/v1/v1/venues \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200The venue, with its locations
401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
Enquiries
For a venue key — who is asking to hire it, and which days are already taken. Read-only: answering an enquiry is a negotiation with money at the end of it, and that stays in Studio where a person is looking at it.
/v1/enquiriesenquiries:readWho is asking to hire this venue
Every enquiry addressed to this venue, most recently active first.
An enquiry is the conversation BEFORE a booking: an organiser describes what they need, proposes dates, and the two sides quote and counter until somebody accepts. Accepting creates the booking, so money stays in one place; this endpoint never sees that part.
⚠️ A draft is never returned. An enquiry an organiser has written
and not sent is private to their side. The filter runs per page and the
page stays exact: has_more is observed, so a hidden row is never
mistaken for the end of the list.
⚠️ Addressed by the place as well as the venue. An enquiry raised against an address before that address was attached to this venue still belongs here, so both are matched. A venue operating more than 29 places sees the first 29 of them plus everything addressed to the venue itself, which is the same limit the dashboard's own inbox works under.
updated_after filters on the activity clock and flips the sort to
ascending, so a poller reads changes in the order they happened.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
limit | query | integer, 1–100, default 50 | Clamped to 100. A missing, non-numeric, zero or negative value becomes the default of 50 rather than an error. |
cursor | query | string | The It is anchored to a specific row of a specific ordering, and it is
rejected with |
updated_after | query | string | Only rows whose ⚠️ This changes the ordering to |
Request
curl https://api.venued.eu/v1/v1/enquiries \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200Enquiries for this venue, most recently active first
400401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/enquiriesenquiries:writePut an inquiry from your own channels into your Venued inbox
For the forms and tools a business already uses to collect inquiries: its website form, a Typeform, a Zapier or Make scenario reading a booking portal's mails. The inquiry lands in the business's Venued inbox exactly as a forwarded mail does: unread, with a notice, as a deal with an outside client the business then quotes from Studio.
It creates, it never answers. Quoting, accepting and declining stay in Studio, where a person looks at the money.
Whose inbox is the key's. A venue key may name one of its own places
with locationId (else its first place); a professional key is itself
and may name one of its services with serviceId.
Idempotency-Key is required, as for every create: a retried call
with a key that already succeeded replays the stored response.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
Idempotency-Keyrequired | header | string | Any opaque string you generate per logical operation — a UUID is the usual choice. Scoped to your organiser account and retained 7 days. |
Request
curl -X POST https://api.venued.eu/v1/v1/enquiries \
-H "Authorization: Bearer vnd_live_your_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"title": "Hochzeit Hofmann",
"client": {
"name": "Lena Hofmann",
"email": "lena@example.de",
"phone": "+49 151 2345678"
},
"need": {
"role": "Hochzeit, Abendessen und Party",
"headcount": 80,
"brief": "Samstag, gern mit DJ."
},
"dates": [
{
"start": "2027-06-12",
"allDay": true
}
],
"reference": "form-4711"
}'Responses
201Created, unread in the business's inbox
400idempotency_key_required— noIdempotency-Keyheader.invalid_argument— no contact (giveclient.emailorclient.phone), notitle, noneed.role, or a date that does not parse; or this venue has no place yet.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key lacksenquiries:write.forbidden— not a venue or professional key.404not_found—locationIdis not one of this venue's places, or the business no longer exists.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/enquiries/{enquiryId}enquiries:readOne enquiry
⚠️ 404, not 403, for an enquiry belonging to another venue. Whether a given id exists is not something this key should be able to confirm. A draft answers the same way, for the same reason the list omits it.
Used inWebhooks
Parameters
| Name | In | Type | Description |
|---|---|---|---|
enquiryIdrequired | path | string |
Request
curl https://api.venued.eu/v1/v1/enquiries/{enquiryId} \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200The enquiry
401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/availabilityavailability:readWhich days this venue is already taken
The days this venue is known to be busy, and the subset of them it blocked by hand.
⚠️ "Busy" is known; "free" is not a promise. The list is derived from bookings that hold a date, manual blocks and the venue's own events, and it is deliberately optimistic: a venue Venued knows nothing about reads as available, because search treats an unknown as bookable rather than hiding it. A day that is absent here therefore means we have no reason to think it is taken, which is not the same as free. Confirm before promising it.
⚠️ Whole days, not hours. A venue booked for one lunch is busy for that day as far as this index is concerned. Timed holds are coming; the day list stays, because a day list is what a subscribed calendar can consume.
⚠️ Per place. These fields live on each location, because a venue with three rooms has three calendars. An earlier version of this endpoint read them off the venue record, where nothing writes them, and so answered with empty lists for everybody.
manualBlockedDates is separated out because it is the only part the
venue authored — a booking-derived day is a fact, a manual block is a
decision, and a calendar sync needs to know which of its own entries it
is looking at.
Request
curl https://api.venued.eu/v1/v1/availability \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200The days known to be taken
401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
Professionals
A professional's own profile and offerings, for its key only. Read-only: the profile is edited in Studio.
/v1/profileprofile:readThis professional's own profile
The profile the key belongs to, including its own contact fields
(which the public page shows only as the professional chose). url
is built from the id and redirects to the current slug.
Request
curl https://api.venued.eu/v1/v1/profile \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200The profile.
401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/offeringsofferings:readThis professional's offerings, in every status
Drafts, paused and archived offerings included, since the key is the
owner's; status says which. The public page shows published only.
Ordered as in Studio (sortOrder, then title). A professional has a
handful, so this is one page: has_more is always false.
Request
curl https://api.venued.eu/v1/v1/offerings \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200Every offering.
401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
Webhooks
/v1/webhookswebhooks:readList webhook subscriptions
⚠️ The secret is returned here in plaintext. Treat this response as a
credential.
Used inWebhooks
Request
curl https://api.venued.eu/v1/v1/webhooks \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200Subscriptions
401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/webhookswebhooks:writeSubscribe to events
Creates a subscription and returns its signing secret. Store the
secret now — it is also readable from GET /v1/webhooks, but it is
what verifies every delivery and it should be treated as a credential
from the moment it exists.
A maximum of 10 subscriptions per account is enforced.
A venue key may subscribe to event.published and the supplier
side of its deals (enquiry.received, enquiry.quoted,
enquiry.countered, enquiry.accepted, enquiry.declined,
enquiry.withdrawn, booking.confirmed, booking.cancelled); a
professional key to the same deal events without event.published.
enquiry.sent and invoice.issued belong to the business account
and need an organiser key. order.confirmed is refused with
403 forbidden rather than silently dropped: it carries a buyer's name
and email, which is the organiser's record and not the building's, and
a subscription quietly narrower than the one you asked for would only
announce itself by never firing.
Used inWebhooks
Request
curl -X POST https://api.venued.eu/v1/v1/webhooks \
-H "Authorization: Bearer vnd_live_your_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"url": "https://example.com/hooks/venued",
"events": [
"order.confirmed"
],
"description": "Push confirmed orders into the CRM"
}'Responses
201Created. Carries the signing secret.
400invalid_argument—urlmissing, unparseable, not https, or not a public host; oreventscontains no known type.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope, orforbiddenwhen a venue or professional key asks for an event type it may not receive (see above).409limit_reached— already 10 subscriptions.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/webhooks/{webhookId}webhooks:writeChange a webhook subscription
Send any of url, events, enabled and description. Fields you
leave out are unchanged. The secret cannot be set here.
Strict on purpose, because a lenient reading of these fields fails silently:
enabledmust be a JSON boolean. The string"true"is a400, not a quiet "off".- Any other field,
secretincluded, is a400, never ignored. eventsfollows the same rules as on create. A type your key's account may not receive is a403naming it, not dropped.
Re-enabling an endpoint (enabled: true) resets
consecutiveFailures to 0. An endpoint that auto-disabled after 20
failures comes back this way once you have fixed it.
Used inWebhooks
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhookIdrequired | path | string |
Request
curl -X PATCH https://api.venued.eu/v1/v1/webhooks/{webhookId} \
-H "Authorization: Bearer vnd_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"enabled": true
}'Responses
200The subscription as it now is.
400invalid_argument: an empty body, an unknown field, a non-booleanenabled, a badurl, or no known event type.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope, orforbiddenfor an event type this account may not receive.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/webhooks/{webhookId}webhooks:writeDelete a webhook subscription
Removes the subscription and returns
{"data": {"id": "…", "deleted": true}}. Deliveries already in flight
are not recalled.
Metered as a write (120/min), like every other request that changes something.
Used inWebhooks
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhookIdrequired | path | string |
Request
curl -X DELETE https://api.venued.eu/v1/v1/webhooks/{webhookId} \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200Deleted
400invalid_argument— nowebhookIdin the path.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/webhooks/{webhookId}/deliverieswebhooks:readList an endpoint's recent deliveries
What was sent to this endpoint and what came back, newest first. One row per delivery: retries of it update the same row. Rows are kept for 30 days.
Use it to find the delivery your receiver missed, then resend it.
Used inWebhooks
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhookIdrequired | path | string | |
limit | query | integer, 1–100, default 50 | Clamped to 100. A missing, non-numeric, zero or negative value becomes the default of 50 rather than an error. |
cursor | query | string | The It is anchored to a specific row of a specific ordering, and it is
rejected with |
Request
curl https://api.venued.eu/v1/v1/webhooks/{webhookId}/deliveries \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
200A page of deliveries.
400unsupported_parameter— a query parameter this endpoint does not accept.invalid_cursor— a malformed cursor, one belonging to a different ordering, or one anchored to a row that no longer exists.invalid_argument—updated_afterwas not ISO 8601 or epoch ms.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
/v1/webhooks/{webhookId}/deliveries/{deliveryId}/resendwebhooks:writeResend one delivery
Queues the stored delivery again, byte for byte, with the same
id. A receiver that deduplicates on the delivery id, as it should,
treats a resend of a delivery it already processed as a duplicate.
That is also why this needs no Idempotency-Key: calling it twice
sends the same delivery twice, which your receiver already has to
handle.
Returns 202 once the delivery is queued, not once it has arrived.
Watch the delivery's row in the log for the outcome.
Used inWebhooks
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhookIdrequired | path | string | |
deliveryIdrequired | path | string |
Request
curl -X POST https://api.venued.eu/v1/v1/webhooks/{webhookId}/deliveries/{deliveryId}/resend \
-H "Authorization: Bearer vnd_live_your_key_here"Responses
202Queued.
401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found: no such webhook, or no such delivery (the log keeps 30 days).409webhook_disabled: the endpoint is switched off. Enable it first.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
503unavailable: the delivery could not be queued. Retry shortly.
/v1/webhooks/{webhookId}/rotate_secretwebhooks:writeRotate the signing secret, with an overlap
Issues a new signing secret and returns it. The old one keeps signing
for grace_seconds (default 3600, at most 604800, 0 to switch at
once), so for that window every delivery carries two v1 values and
verifies on either. Put the new secret in your receiver within the
window.
Idempotency-Key is required. Only one previous secret is kept, so
a rotation during an open overlap ends the older secret at once. A
retried rotate without a key would mint a second secret and silently
retire the one your receiver still uses. With a key, the retry returns
the first response, secret included.
Used inWebhooks
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhookIdrequired | path | string | |
Idempotency-Keyrequired | header | string | Any opaque string you generate per logical operation — a UUID is the usual choice. Scoped to your organiser account and retained 7 days. |
Request
curl -X POST https://api.venued.eu/v1/v1/webhooks/{webhookId}/rotate_secret \
-H "Authorization: Bearer vnd_live_your_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"grace_seconds": 3600
}'Responses
200The subscription with its new
secret.400idempotency_key_required: noIdempotency-Keyheader.invalid_argument:grace_secondsout of range or not a whole number, or any other field.401unauthorized— missing, malformed, unknown or revoked key.403insufficient_scope— the key is valid but lacks the scope.404not_found. Also returned for a resource that exists but belongs to a different organiser — see the note onGET /v1/events/{eventId}.429rate_limited. 600 reads/min and 120 writes/min in a fixed 60-second window.POST,PATCHandDELETEare writes;GETandHEADare reads.⚠️ The budget belongs to the organiser account, not to the key. It was metered per key, which meant minting a second key doubled the allowance — so there was no ceiling, only a formality. Two changes, both breaking, both made while the API has no keys in existence: this one, and
DELETEmoving from the read budget to the write budget.⚠️ The limit is a soft ceiling under burst. The counter is a single Firestore document per key per window, and contention means a hard burst can push somewhat past the nominal figure before 429s begin. It also fails open: if the counter cannot be read, the request is allowed rather than refused.
Webhook events
These are sent to you: Venued POSTs the envelope below to every endpoint subscribed to that event type.
Every delivery carries
| Field | Type | Description |
|---|---|---|
id | string, uuid | The delivery id. Use it to deduplicate. |
type | order.confirmed | event.published | enquiry.received | enquiry.sent | enquiry.quoted | enquiry.countered | enquiry.accepted | enquiry.declined | enquiry.withdrawn | booking.confirmed | booking.cancelled | invoice.issued | |
createdAt | string, date-time | |
principal | object | Who this delivery is for — an organiser, or the venue an event is happening at. ⚠️ A delivery resent from before 2026-09-21 reproduces its
original body, which carried |
principal.type | organiser | venue | professional | |
principal.id | string | |
data | object |
order.confirmedA ticket order or RSVP was confirmed
Sent once, on the pending → confirmed transition of an order. It does
not re-fire if the order is written again while already confirmed.
event.publishedAn event became public
Sent once, the first time an event transitions to public. Making an
already-public event public again does not re-fire it.
enquiry.receivedSomebody asked to hire this venue or professional
Sent once, when an enquiry reaches the business — the moment it stops being the organiser's unsent draft. A later edit does not re-fire it.
⚠️ Not for a deal you logged yourself. A business can log an enquiry it took by phone from an outside client; posting a webhook back for that would be telling you what you just did, so it is not delivered. An enquiry that arrived is delivered, whoever sent it: an organiser on Venued, the inquiry form on your own website, or a mail to your intake address.
⚠️ No contact details, deliberately. The payload says an enquiry
exists and what it is for. Names, emails and phone numbers are not in
it, because a webhook goes to a URL that is usually a third-party tool
and is retried and replayable. Read the enquiry with
GET /v1/enquiries/{enquiryId}, which is authenticated and scoped.
Deliverable to the venue or professional the enquiry is addressed to,
and to the business account that runs it. data.side is always
supplier; the organiser's side of the same moment is
enquiry.sent. Since 2026-10-04 the payload also carries side,
acceptedDate and quote (both null here); see
EnquiryWebhookData.
enquiry.sentYour business sent an enquiry to a venue or professional
Sent once, when an enquiry your business wrote stops being a draft and
reaches the business it is addressed to. The organiser's side of the
moment the venue or professional receives enquiry.received.
Organiser keys only (any kind of business can hold one).
enquiry.quotedThe business sent an offer
Sent when the venue or professional sends a new offer (a new price
revision). Delivered to both sides: the organiser that asked, and
the business that quoted, so an integration on either side holds the
current price. data.side says which side a delivery is for, and
data.quote carries the price.
enquiry.counteredThe organiser countered an offer
Sent when the organiser answers an offer with a counter-offer (a new
price revision). Delivered to both sides; data.quote is the counter.
enquiry.acceptedAn offer was accepted
Sent once, when the enquiry becomes accepted, whoever accepted.
Delivered to both sides. data.acceptedDate is the agreed date and
data.quote the agreed price. The booking that follows is
booking.confirmed.
enquiry.declinedThe business declined an enquiry
Sent once, when the venue or professional declines. Delivered to both sides.
enquiry.withdrawnThe organiser withdrew an enquiry
Sent once, when an enquiry that had been sent is withdrawn. Withdrawing an unsent draft sends nothing: it never existed for the business. Delivered to both sides.
booking.confirmedA booking was agreed
Sent once, the first time a booking reaches an agreed state
(confirmed, event_linked or completed; a booking can land past
confirmed in one step, and is announced once either way).
Delivered to the organiser that booked, and to the supplier: the
business account that is the merchant of record, and the venue or
professional booked. data.side says which. One business on both
sides (a venue booking its own room) receives one of each.
booking.cancelledA booking was cancelled
Sent once, when a booking becomes cancelled, to the same parties as
booking.confirmed.
invoice.issuedYour business issued an invoice
Sent once per number, when your business issues a document from its
invoice book: an invoice, an advance invoice, a final invoice, or a
cancellation (kind: invoice, advance, final, storno).
Organiser keys only: the invoice book belongs to the business account, not to a venue or professional record.
⚠️ No buyer in the payload. The buyer is often a private person; their name, email and address are not sent to a webhook URL.