Overview
The Shows API lets you read, create and update the shows in a Confirmed production over HTTP. Every endpoint returns JSON.
The examples send the API token as a bearer token, one of the ways Authentication lists. Creating and updating shows needs a read-write key.
GET /shows
This endpoint returns the shows that start inside a date window, as an array.
| Parameter | Type | Description |
|---|---|---|
ts_from |
timestamp | Earliest start time. Defaults to ten days ago. |
ts_to |
timestamp | Latest start time. Defaults to thirty days ahead. |
show_type |
string | Only returns shows of this type. You can look up the ids on Show types. |
curl "https://confirmed.show/api/v1/spectrum/shows?ts_from=2026-07-01&ts_to=2026-07-31" \
-H "Authorization: Bearer <token>"
GET /shows/{show_id}
This endpoint returns one show. If no show has that id, you get a 404.
curl https://confirmed.show/api/v1/spectrum/shows/nan3 \
-H "Authorization: Bearer <token>"
The show object
The read endpoints and both update endpoints return shows in this shape. The spots are
split into hosts, lineup and production, each in
running order.
| Field | Type | Description |
|---|---|---|
id |
string | Show id |
type |
string | Show type id. See Show types. |
ts |
timestamp | Start date and time |
doors_ts |
timestamp | Doors time, worked out from the start time and the doors offset |
venue_id |
string | Venue id |
room_id |
string | Room id |
description |
string | Show description |
tags |
string[] | Tags |
public |
boolean | Whether the show is public |
production_contacts |
string[] | Act ids of the people responsible for the show |
meta |
object | The show's ticket link and promotional assets. See Show meta. |
created_by_api_key |
object |
Set when the show was created through the API: the first four characters of
the key as key, and what the key was called at the time as
description
|
hosts |
Slot[] | Host spots |
lineup |
Slot[] | Act and break spots |
production |
Slot[] | Production spots |
Each spot has the slot fields, with the id of the person booked in act_id.
A spot that's part of a settlement has settled: true.
POST /shows
This endpoint creates one show for each date in dates. The shows all share
the same type, venue, lineup and contacts, so you can add a whole run or residency in
one call.
| Field | Type | Required | Description |
|---|---|---|---|
dates |
string[] | Yes | Show dates as YYYY-MM-DD. A date that won't parse is skipped. |
time |
string | Yes | Start time as HH:MM, on a 24-hour clock |
type |
string | Yes | Show type. The production has to have it already. |
production_contacts |
string[] | Yes | Act ids of the people responsible. At least one, and each has to be on the team. |
venue_id |
string | No | Venue id, or venueID. The venue has to exist. |
room_id |
string | No |
Room id, or roomID. The room has to belong to
venue_id.
|
doors |
integer | No | Minutes between doors and the start time |
public |
boolean | No | Whether the show is public |
tags |
string[] | No | Tags of your own |
description |
string | No | Show description |
hosts |
Slot[] | No | Host spots |
lineup |
Slot[] | No | Act and break spots. A spot with no category becomes an act. |
production |
Slot[] | No | Production spots |
Without any of the three spot lists, the show gets a standard running order: one host, three acts and one production spot. Act spots run ten minutes unless you set a length.
curl -X POST https://confirmed.show/api/v1/spectrum/shows \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"dates": ["2026-07-21"],
"time": "21:00",
"type": "dmx-madness",
"production_contacts": ["ejcs"],
"hosts": [ { "role": "MC" } ],
"lineup": [ { "actID": "b9b4" }, {}, {} ],
"production": [ {}, {} ]
}'
{ "created": 1, "ids": ["nan3"] }
The slot object
A slot is one spot on a show. You use this shape both when you create shows and when you
patch spots through spot_updates. A field name we don't recognise comes
back as an error rather than being ignored.
| Field | Type | Description |
|---|---|---|
actID |
string |
The id of the person booked. act_id works too. The act has to
be in the production.
|
category |
enum |
act, host, production,
break, other
|
order |
integer | Where the spot is in the running order. We assign one if you leave it out. |
spot_length |
integer | Length in minutes. Acts run ten by default. |
role |
string | What they are doing, such as MC or headliner |
fee |
string | What the spot pays |
arrive_mins |
integer | How many minutes before the spot they're called in |
leave_mins |
integer | How many minutes after the spot they're free to go |
call_time |
timestamp | Call time, as YYYY-MM-DD HH:MM |
spot_start |
timestamp | Spot start, as YYYY-MM-DD HH:MM |
spot_end |
timestamp | Spot end, as YYYY-MM-DD HH:MM |
mc_opens |
integer[] | For a host: the spots they introduce |
status |
enum |
planning, offered, confirmed,
rejected, cancelled, no-show
|
settled |
string | Settlement marker |
PUT /shows
This endpoint updates several shows in one call. We check the whole request before writing anything, so if one show in the batch has a problem, none of them change.
{
"updates": [
{ "id": "<show id>", "changes": { ... } }
]
}
| Field | Type | Description |
|---|---|---|
type |
string | Show type. The production has to have it already. |
ts |
timestamp | Start date and time, as YYYY-MM-DD HH:MM |
venue_id |
string | Venue id, or venueID |
room_id |
string |
Room id, or roomID. When you send both, the room has to belong
to that venue.
|
doors |
integer | Minutes between doors and the start time |
public |
boolean | Whether the show is public |
tags |
string[] | Replaces the tags outright |
description |
string | Show description |
production_contacts |
string[] | Act ids. Each has to be on the team. |
status |
string | Show status |
currency |
string | Show currency |
comment |
string | A note about the change |
meta |
object | Ticket link and promotional assets. See Show meta. |
spot_updates |
object | Patches individual spots. See below. |
Editing spots
spot_updates is a map of { spot_id: { field: value } }. We
merge each spot you name in place, updating the fields you send and leaving the rest of
that spot, and every spot you didn't mention, as they were. It never replaces the
running order. A spot id that isn't on the show comes back as an error.
curl -X PUT https://confirmed.show/api/v1/spectrum/shows \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"updates": [
{
"id": "nan3",
"changes": {
"ts": "2026-07-21 20:00",
"venue_id": "5c9g",
"room_id": "bpjj",
"spot_updates": {
"a1b2": { "actID": "b9b4", "fee": "150", "status": "confirmed" },
"c3d4": { "order": 2 }
}
}
}
]
}'
You get the updated shows back as an array.
PUT /shows/{show_id}
This endpoint updates one show. The id comes from the path, so the body is just the
changes, without the updates wrapper. If no show has that id, you get a
404.
curl -X PUT https://confirmed.show/api/v1/spectrum/shows/nan3 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"ts": "2026-07-21 20:00",
"venue_id": "5c9g",
"spot_updates": {
"a1b2": { "fee": "150", "status": "confirmed" }
}
}'
You get the updated show back.
Show meta
Every show has a meta object with its ticket link and promotional assets.
You can read it from any show endpoint and set it through either update endpoint.
The built-in fields below mean the same thing in every production, so you can rely on their names. A production can add fields of its own under Data & API, which appear in the same object alongside the built-ins. Meta fields lists every field your production has, with its name and type.
| Field | Type | Description |
|---|---|---|
tickets_url |
url | Where the audience buys tickets |
event_url |
url | The show's own page, separate from the ticket seller |
promo_image |
image | The main promotional picture |
promo_thumb |
image | A thumbnail of it |
social_card |
image | The picture shown when someone shares a link to the show |
promo_video |
video | A promotional video |
poster |
image | Poster artwork |
promo_blurb |
long-text | A short description for listings and socials |
Image, video and file fields store a URL rather than the file itself. Uploading a file covers how to get one.
A production can switch off a built-in field to hide it from the show card. That only changes the show card, and the API still reads and writes the field.
Reading meta
Every show object has meta. On a show with nothing set, it's an empty
object.
{
"id": "nan3",
"type": "dmx-madness",
"ts": "2026-07-21 21:00",
"meta": {
"tickets_url": "https://tickets.example.com/nan3",
"promo_image": "https://st.confirmed.show/uploads/spectrum/shows/nan3/A1B2C3-promo.webp",
"promo_blurb": "One night only."
}
}
Setting a ticket link
We merge meta fields one at a time, so setting tickets_url leaves the promo
image and everything else on the show as it was. You can't replace the whole object
at once, so a ticketing integration can look after the link without ever touching the
artwork.
curl -X PUT https://confirmed.show/api/v1/spectrum/shows/nan3 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"meta": {
"tickets_url": "https://tickets.example.com/nan3"
}
}'
You can set links across a run of shows in one call:
curl -X PUT https://confirmed.show/api/v1/spectrum/shows \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"updates": [
{ "id": "nan3", "changes": { "meta": { "tickets_url": "https://tickets.example.com/nan3" } } },
{ "id": "p4rt", "changes": { "meta": { "tickets_url": "https://tickets.example.com/p4rt" } } }
]
}'
Send null to clear a field:
{ "meta": { "tickets_url": null } }
You can send meta alongside any other change in the same call, for example to publish a show and give it its ticket link at once:
{
"public": true,
"meta": { "tickets_url": "https://tickets.example.com/nan3" }
}
What the values have to be
- Every name has to be a built-in or a field the production has added. We reject anything else rather than creating a field for you, so a typo comes back as an error instead of quietly becoming a new field.
-
url,image,videoandfilefields need a string startinghttp://orhttps://. We trim any whitespace. -
numberfields need a number, andbooleanfields needtrueorfalse. - Everything else accepts text.
Uploading a file
Image, video and file fields store a URL. To put your own file behind one, you can ask for an upload slot, send the file to it, and then save the URL you get back. This needs a read-write key.
1. Ask for the slot.
curl -X POST "https://confirmed.show/api/v1/spectrum/upload-file?filename=promo.png" \
-H "Authorization: Bearer <token>"
{
"upload_url": "https://storage.googleapis.com/...<signed>",
"file_url": "https://st.confirmed.show/uploads/spectrum/api-uploads/A1B2C3-promo.png"
}
2. Send the file to upload_url. The link lasts fifteen
minutes.
curl -X PUT "<upload_url>" \
-H "Content-Type: image/png" \
--upload-file promo.png
3. Save file_url on the show.
curl -X PUT https://confirmed.show/api/v1/spectrum/shows/nan3 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "meta": { "promo_image": "https://st.confirmed.show/uploads/spectrum/api-uploads/A1B2C3-promo.png" } }'
Anyone with the URL can open the file, so these files are effectively public. Confirmed stores each picture exactly as it arrives and doesn't crop it for you, so it's best to send it at the size you want. The preferred dimensions you set under Data & API only shape the crop box inside Confirmed.
Errors
| Status | What happened |
|---|---|
400 |
The request carried no API token. |
401 |
We don't recognise that token. |
403 |
The token can read but not write. |
404 |
No show has that id. Only the single-show GET and PUT answer this way. |
422 |
Something in the request didn't check out. The body says what, and nothing was written. |
A 422 covers a field we don't recognise, a venue, act or spot id that
doesn't exist, a room that isn't in the venue you named, and a meta value of the
wrong sort. These are the ones you're most likely to meet while working with meta:
| Message | What happened |
|---|---|
Unknown meta field: x |
No built-in or custom field has that name. It may be a typo, or the field may need adding under Data & API first. |
Not a meta field name: x |
The name isn't the right shape. Names are lower case, start with a letter, and contain only letters, digits and underscores. |
x takes a url starting with http:// or https:// |
A link or file field got something that isn't a URL. |
x takes a number |
A number field got something else. |
x takes true or false |
A boolean field got something else. |
If something here doesn't behave the way this page describes, write to support@confirmed.show and we'll sort it out.