Quick start
No sign-up is needed to try it. Open this address in your browser and you will see JSON:
GET https://soundsandstage.com/api/v1/productions?status=running&sort=name&limit=5&fields=name,venue,url
That asks for five running productions, sorted by name, showing only the name, venue and link. Free use is 60 requests a minute. See the packages for 600 or more requests a minute and 100 results per page.
Code examples
curl
# The five running productions curl "https://soundsandstage.com/api/v1/productions?status=running&sort=name&limit=5&fields=name,venue,url" # With your key curl -H "X-API-Key: YOUR_KEY" "https://soundsandstage.com/api/v1/productions?q=wicked" # One production, with cast, creative team, tour dates and reviews curl "https://soundsandstage.com/api/v1/productions/wicked" # Venues within 3 km of Leicester Square curl "https://soundsandstage.com/api/v1/venues?near=51.5101,-0.1281&radius=3"
JavaScript (browser or Node 18+)
const res = await fetch("https://soundsandstage.com/api/v1/productions?status=running&limit=20", {
headers: { "X-API-Key": "YOUR_KEY" } // optional
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { meta, data, links } = await res.json();
console.log(meta.total + " productions");
for (const show of data) console.log(show.name, "at", show.venue?.name);
// Follow the links to page through everything
let url = "https://soundsandstage.com/api/v1/productions?limit=100";
while (url) {
const r = await (await fetch(url)).json();
r.data.forEach(s => console.log(s.name));
url = r.links.next; // undefined on the last page
}
Python
import requests
BASE = "https://soundsandstage.com/api/v1"
s = requests.Session()
s.headers["X-API-Key"] = "YOUR_KEY" # optional
def pages(path, **params):
url = BASE + path
while url:
r = s.get(url, params=params if "?" not in url else None, timeout=15)
if r.status_code == 429:
raise SystemExit("Slow down, retry in %s seconds" % r.headers.get("Retry-After"))
r.raise_for_status()
body = r.json()
yield from body["data"]
url = body["links"].get("next")
for show in pages("/productions", status="running", sort="name"):
print(show["name"], "-", (show["venue"] or {}).get("name"))
PHP
<?php
$ctx = stream_context_create(['http' => [
'header' => "X-API-Key: YOUR_KEY\r\n", // optional
'timeout' => 15,
]]);
$json = file_get_contents('https://soundsandstage.com/api/v1/productions?status=running&limit=20', false, $ctx);
$data = json_decode($json, true);
foreach ($data['data'] as $show) {
echo $show['name'], ' at ', $show['venue']['name'] ?? 'tour', "\n";
}
Resources
| Resource | Address | Contains |
|---|---|---|
| Productions | https://soundsandstage.com/api/v1/productions | Dates, previews, press night, running time, age guidance, price from, venue, area, company, cast. Add /slug for creative team, tour dates, ways to buy, offers, reviews, news, songs and characters. |
| Venues | https://soundsandstage.com/api/v1/venues | Address, city, kind, capacity, coordinates, area. Add /slug for current shows and seat notes (labelled fact or opinion). |
| Areas | https://soundsandstage.com/api/v1/areas | Towns and districts, with the venues in each. |
| People | https://soundsandstage.com/api/v1/people | Stage names, with biography, credits and awards on the /slug page. |
| Articles | https://soundsandstage.com/api/v1/articles | News, features and reviews: headline, summary, date and link. Full text stays on the site. |
| Reviews | https://soundsandstage.com/api/v1/reviews | Reviews only; filter by production, venue or person. |
| Performances | https://soundsandstage.com/api/v1/performances | Upcoming tour dates by venue and city. |
| Awards | https://soundsandstage.com/api/v1/awards | Winners and nominees by awards body, year and category. |
| Glossary | https://soundsandstage.com/api/v1/glossary | Theatre terms and roles with short definitions. |
| Offers | https://soundsandstage.com/api/v1/offers | Live ticket offers and discount codes we have checked. |
| Jobs | https://soundsandstage.com/api/v1/jobs | Live theatre job adverts. |
| Events | https://soundsandstage.com/api/v1/events | A date-ordered calendar: openings, closings, press nights, previews and awards dates. |
| Tickets | https://soundsandstage.com/api/v1/tickets | Shows on sale now with booking links, price from and closing dates. |
| Search | https://soundsandstage.com/api/v1/search | One search across productions, venues, areas, people and articles. Use ?q=. |
| Status | https://soundsandstage.com/api/v1/status | Health check and record counts. |
| OpenAPI | https://soundsandstage.com/api/v1/openapi.json | Machine-readable description for Postman, Swagger and code generators. |
Searching, filtering and sorting
Every list takes q (search words), page, limit, sort (a field name, with a - in front to reverse) and fields (a comma-separated list, to keep responses small). updated_since=YYYY-MM-DD returns only what changed on or after that day.
| Resource | Extra filters | Sort by |
|---|---|---|
| productions | venue, area (slugs), status (running, previews, upcoming, closed), type, company | name, opens, closes, press_night, updated |
| venues | city, area, kind, near=lat,lng with radius in km (default 5, up to 200) | name, city, capacity, distance_km, updated |
| people | kind, letter (A to Z), has_bio=1 | name, kind, updated |
| articles | category, show, venue, person, tag (slugs) | published, title, updated |
| performances | city, production, from, to (dates) | starts, ends, production, city |
| awards | body, year, result=winners | year, awards, category, nominee |
| performances (near a town) | town, radius (miles, default 25) | distance_miles |
| events | from, to, kind (opens, closes, press_night, previews, awards), type | date, kind, production |
| tickets | closing_within (days) | production, closes, price_from |
| productions (extra) | closes_before, opens_after, price_max | |
| offers, jobs, glossary | kind; jobs also category and location | title, valid_to, price_from, posted, term |
What comes back
{
"meta": { "source": "Sounds & Stage", "version": "1", "authenticated": false,
"total": 87, "page": 1, "pages": 18, "per_page": 5, "returned": 5 },
"links": { "self": "https://soundsandstage.com/api/v1/productions?limit=5", "first": "...", "next": "https://soundsandstage.com/api/v1/productions?limit=5&page=2", "last": "..." },
"data": [ { "id": 12, "slug": "wicked", "name": "Wicked", "type": "Musical", "status": "running",
"opens": "2006-09-27", "running_time": "2h 45m", "price_from": "£25",
"venue": { "name": "Apollo Victoria Theatre", "slug": "apollo-victoria-theatre", "url": "..." },
"area": { "name": "Victoria", "slug": "victoria", "url": "..." },
"url": "...", "updated": "2026-10-01T09:30:00+01:00" } ]
}
Lists are paged. Use links.next until it is missing. The same links are sent in a Link header.
Keys, limits and errors
- Send your key in an
X-API-Keyheader. Without a key: 60 requests a minute and 20 results per page. With a key: 600 a minute and 100 per page. - Every response carries
X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Reset. When you go over, you get429with aRetry-Afterheader. - Responses have an
ETag. Send it back inIf-None-Matchand an unchanged answer is a tiny304, which still counts as a request but saves your bandwidth. - Errors are JSON:
{"error":{"status":404,"code":"not_found","message":"..."}}. Codes:400bad request,401invalid key,404not found,405read only,429rate limited. - Browsers can call the API directly: CORS is open for GET.
Rules
- Show a visible link back to the Sounds & Stage page for anything you display. The data may not be resold as a dataset.
- Cache on your side for a few minutes. Productions and venues change daily at most.
- We do not provide live seat availability or prices from ticket sellers. "Price from" is what our editor last checked.
Need a key or a feed?
Ticketing services, apps and other theatre sites can see the API packages or contact us. Tell us what you are building. The machine-readable description is at https://soundsandstage.com/api/v1/openapi.json.