The partner feed
The partner feed gives you the published upcoming shows of every Confirmed production that has chosen to share its listings with you, in one request. A signed notice tells you when a production's listing changes, so you only need to pull what changed.
Your token and webhook settings are on your partner page. Members of your team can log in there with their email address.
GET https://confirmed.show/api/partners/v1/shows.json
GET https://confirmed.show/api/partners/v1/shows.json?production=<handle>
You can send your token as Authorization: Bearer <token> or as an
X-API-Token header. The feed doesn't accept it in the address, as
addresses end up in server and browser logs. It's safest to call the feed from your
own server, since the token works for every production sharing with you.
What it covers
- Shows the production has published, from now to 180 days ahead. Drafts and private shows never appear.
-
Shows that were published and then cancelled, with
status: "cancelled"and an empty lineup, until they would have taken place. You can use them to tell ticket holders the show is off. - Confirmed bookings only. An act the production is still waiting to hear from stays private.
- No fees, call times, contact details, crew, notes or custom fields, and no ticket price.
-
A production can list only the hosts of a show type, or no lineup at all, for nights
like open mics. Those shows come with a shorter or empty
lineup, which doesn't mean nobody is booked.
Each token can make 60 requests an hour. Beyond that, the feed answers
429 until the hour is up.
Response
{
"shows": [
{
"id": "ps_2b8e0d4f6a1c3e5b7d9f",
"production": "brightside",
"show_type_id": "pt_5a7c9e1b3d5f7a9c1e3b",
"name": "Friday Showcase",
"status": "scheduled",
"ts": "2026-11-13 20:00:00",
"ts_utc": "2026-11-13T20:00:00Z",
"doors_ts": "2026-11-13 19:30:00",
"doors_ts_utc": "2026-11-13T19:30:00Z",
"updated_at": "2026-11-05 14:02:00",
"room_id": "pr_4e1a9c0b7d2f8e6a3c51",
"tickets_available": 42,
"total_act_spots": 4,
"meta": { "tickets_url": "https://tickets.example.com/brightside-friday", "promo_image": "https://st.confirmed.show/…" },
"lineup": [
{ "production_id": "pa_9f2c4a1e7b3d5f60a1b2", "category": "host" },
{ "production_id": "pa_1b7d0c9e8f7a6b5c4d3e", "category": "act", "spot_length": 20 }
]
}
],
"acts": {
"pa_9f2c4a1e7b3d5f60a1b2": {
"global_id": "ga_c81e728d9d4c2f636f06",
"name": "Nina Halloran",
"bio": "The Brightside's resident host.",
"credits": "…",
"images": ["https://st.confirmed.show/…"],
"instagram": "ninahalloran",
"act_profile": { "bio": "Touring comic and podcaster." }
}
},
"productions": {
"brightside": { "name": "Brightside Comedy" }
},
"show_types": {
"pt_5a7c9e1b3d5f7a9c1e3b": {
"name": "Friday Showcase",
"description": "Four acts and a host, every Friday in the Main Room.",
"duration": 120
}
},
"rooms": {
"pr_4e1a9c0b7d2f8e6a3c51": {
"name": "Main Room",
"venue": {
"id": "pv_7c3d1e9a0f2b4c6d8e1a",
"name": "The Brightside",
"address": "62 Cowgate",
"city": "Edinburgh",
"postcode": "EH1 1JX",
"country": "United Kingdom",
"tz": "Europe/London"
}
}
},
"ended": [{ "handle": "brightside-outpost", "ended_at": "2026-11-01 09:12:00" }]
}
ended lists productions that stopped sharing with you in the last 30 days.
It's only in the full feed.
Show fields
| Field | Description |
|---|---|
id |
The show's id, starting ps_. It's made for you alone
and stays the same for the life of the show.
|
production |
The production's handle, as a key in productions |
show_type_id |
The show's type, as a key in show_types |
name |
The show's public name |
status |
scheduled or cancelled |
cancelled_ts |
When a cancelled show was cancelled, in UTC. Only there on cancelled shows. |
ts |
Start time in the venue's time zone, as YYYY-MM-DD HH:MM:SS
|
ts_utc |
The same start time in UTC, as ISO 8601 |
doors_ts |
When doors open, in the venue's time zone. Only there when the show has a doors time. |
doors_ts_utc |
The same doors time in UTC, as ISO 8601 |
updated_at |
When the production's listing last changed, in UTC |
room_id |
The room the show is in, as a key in rooms.
null when the show has no venue yet.
|
meta |
The show's promotion: ticket link, pictures, video and blurb. The fields are the ones listed under Promotion on the public Shows endpoint, and each one only appears once the show has a value for it. |
tickets_available |
How many seats are left, when the room has a capacity on record. Not on cancelled shows. |
total_act_spots |
How many act spots the show has, including any still open |
lineup |
Hosts and acts in running order, each with
production_id pointing at an entry in acts,
category (host or act) and, for acts,
spot_length in minutes
|
Productions
Each production in the response is in productions once, keyed by its
handle. The handle is the one notices name and ?production= takes.
| Field | Description |
|---|---|
name |
The production's name |
Show types
A production's shows of the same kind, such as a weekly showcase, share a show type.
Each one is in show_types once.
| Field | Description |
|---|---|
name |
The show type's public name. A show's own name can
differ from it.
|
description |
Its public description, or null |
duration |
How long its shows run, in minutes, or null |
Rooms and venues
Most productions run many shows in the same room, so each room is in
rooms once and shows point at it with room_id. Each room has
its venue's details with it, so a venue with two rooms appears twice.
| Field | Description |
|---|---|
name |
The room's name. null when the show is at the venue without
a particular room.
|
venue.id |
The venue's id, starting pv_. Rooms at the same venue share
it, so you can map it to your own venue once.
|
venue.name, venue.address,
venue.city, venue.postcode,
venue.country
|
Where the venue is |
venue.tz |
The venue's time zone, which the show times are in |
Show, show type, room and venue ids are made for you alone, like act ids, and stay the same while the thing they point at exists.
Acts
Names aren't unique, and one comedian can have a record at several productions, so each act has two ids:
| Field | Description |
|---|---|
production_id |
The act's record at this production, starting pa_. Every
act has one, and it stays the same while the record exists. It's the key
in acts.
|
global_id |
The act's own Confirmed account, starting ga_. It's
null until the production's record is linked to an account.
Two acts with the same global_id are the same person.
|
Both ids are made for you alone, so they won't match ids another service has from us.
-
When an act claims their profile, the same
production_idturns up with aglobal_id. -
When we find two accounts are the same person and merge them, the
production_idstays and theglobal_idchanges to the account that remains. -
When a production folds two of its own records into one, one
production_iddisappears and its shows come back under the other on your next pull.
The profile fields are the ones the production publishes: name,
bio, bio_extended, credits, images,
website, twitter, instagram,
facebook, tiktok and plug. The first image is the
headshot.
A production can use its own wording for an act. When it does,
act_profile has the act's own version of each of those fields. On a
show listing, use the top-level fields. On a page about the act, use
act_profile where it has a value and the top-level fields otherwise, which
gives you the same profile at every production with that global_id.
Notices
Each notice is a POST to your webhook address with a JSON body:
{ "event": "shows.changed", "production": "brightside", "ts": "2026-11-05T14:02:00Z" }
| Event | What to do |
|---|---|
shows.changed |
Pull ?production=<handle> and replace everything you hold
for that production with the result.
|
sharing.ended |
Delete everything you hold for that production. A pull of it now answers
410.
|
shows.test |
Sent when someone on your team tests the webhook from the partner page. |
Notices go out a few minutes after a production finishes editing, so a run of changes leads to one notice. A notice only says which production changed, never what, so every pull gets the current state and a late or missed notice can't leave you with stale data. It's still worth pulling the full feed once a day.
Checking the signature
The X-Confirmed-Signature header is sha256= followed by the
HMAC-SHA256 of the raw body, made with your signing secret from the partner page.
import hashlib, hmac
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, request.headers["X-Confirmed-Signature"]):
abort(401)
Your endpoint has 10 seconds to answer with a 2xx status. If it keeps
failing for 24 hours, we pause notices and email your team. You can resume them from the
partner page.
Errors
| Status | What happened |
|---|---|
400 |
The request had no token in its headers. When the token was in the address
instead, error is token_in_query.
|
401 |
We don't recognise that token. |
404 |
No production with that handle is sharing with you. |
410 |
That production stopped sharing with you. The body has
ended_at.
|
429 |
The token has made 60 requests in the last hour. |
If anything here doesn't behave the way this page describes, write to support@confirmed.show and we'll sort it out.