Authentication
Register an application at My apps to get a client_id and a client_secret. Send the secret as a bearer token on every request. The secret is shown once; store only that — Revel keeps a hash and cannot show it again. Rotate from the app page if it leaks: the old secret keeps working for 24 hours so you can cut over.
curl "https://api.revel.show/v1/me" \
-H "Authorization: Bearer rvl_sk_live_…"Rate limits
Limits are per account, not per IP — serverless egress with rotating addresses is fine — and every account gets 100 requests per minute and 15,000 per UTC day from its first request, shared across its applications. Keep your registration honest: if we can’t tell who is behind an account we reduce it to 1,000 a day until you tell us, and GET /v1/me reports the current tier as access. Every response carries the governing window; a 429 also carries Retry-After.
Response headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1757203260 # unix seconds
X-RateLimit-Limit-Day: 15000
X-RateLimit-Remaining-Day: 14871
X-RateLimit-Reset-Day: 1757203200Need more? Say so in your application’s intended use, or get in touch — limits are raised per application.
Code samples
Any HTTP client works. Keep the secret on a server — never ship it in a browser or a mobile app.
JavaScript
const res = await fetch(
"https://api.revel.show/v1/events?city=austin&limit=50",
{ headers: { Authorization: `Bearer ${process.env.REVEL_SECRET}` } }
);
const { data, next_cursor } = await res.json();
console.log(data[0].name, data[0].start_time, data[0].venue.name);Python
import os, requests
r = requests.get(
"https://api.revel.show/v1/events",
params={"city": "austin", "limit": 50},
headers={"Authorization": f"Bearer {os.environ['REVEL_SECRET']}"},
)
r.raise_for_status()
for event in r.json()["data"]:
print(event["start_time"], event["name"], "@", event["venue"]["name"])Search, then resolve
curl "https://api.revel.show/v1/search?type=comedians&q=nikki%20glaser" \
-H "Authorization: Bearer $REVEL_SECRET"Pagination and incremental sync
List endpoints return up to limit rows (default 50, max 100) and a next_cursor. Pass it back as cursor until it comes back null. The cursor is opaque; don’t build one.
To stay in sync, remember the time of your last run and pass it as updated_since: you get every row created or changed since, including cancellations and sold-out flips of past shows. This is the intended way to stay current.
GET /v1/events?city=austin&limit=100
GET /v1/events?city=austin&limit=100&cursor=eyJ0IjoiMjAyNi0wOS0…
GET /v1/events?updated_since=2026-09-05T00:00:00ZEndpoints
| Endpoint | Returns |
|---|---|
| GET/v1/me | The application behind your key, its limits, usage today. |
| GET/v1/search | Name search for comedians or venues. `q` and `type` (comedians | venues) are required; up to 20 lightweight hits with ids to resolve. |
| GET/v1/cities | Every city Revel covers; the `slug` is the `city` filter value. |
| GET/v1/events | Upcoming shows, soonest first. Filters: city, from, to, venue_id, comedian_id, updated_since. |
| GET/v1/events/{id} | One show with its full lineup. |
| GET/v1/venues | Venues and promoters, alphabetical. Filters: city, updated_since. |
| GET/v1/venues/{id} | One venue. |
| GET/v1/venues/{id}/events | A venue’s shows. Filters: from, to, updated_since. |
| GET/v1/comedians | Comedians with a resolved identity, alphabetical, all cities. Filter: updated_since. |
| GET/v1/comedians/{id} | One comedian. |
| GET/v1/comedians/{id}/events | Every show a comedian is on the bill for, in any city. Filters: from, to, updated_since. |
Ids are stable 24-character strings. Times are UTC instants in ISO 8601; every event also carries its venue-local timezone. from defaults to now unless updated_since is set. Comedian endpoints are city-agnostic by design.
Event
GET /v1/events/{id}
{
"id": "aBYkXvMPjpdeZYc6fFKhRraw",
"name": "Maria Bamford",
"slug": "maria-bamford",
"url": "https://revel.show/austin/events/maria-bamford-aBYkXvMPjpdeZYc6fFKhRraw",
"description": "…",
"start_time": "2026-09-12T02:30:00.000Z",
"end_time": null,
"doors_time": "2026-09-12T01:30:00.000Z",
"timezone": "America/Chicago",
"primary_tag": "standup_comedy",
"tags": ["standup_comedy"],
"is_sold_out": false,
"is_cancelled": false,
"is_open_mic": false,
"is_free": false,
"min_price": 25,
"max_price": 45,
"currency": "USD",
"image_url": "https://cdn.revel.show/…",
"venue": { "id": "…", "name": "Cap City Comedy Club", "slug": "cap-city-comedy-club", "url": "https://revel.show/venues/cap-city-comedy-club" },
"city": { "slug": "austin", "name": "Austin", "timezone": "America/Chicago" },
"lineup": [
{ "id": "…", "name": "Maria Bamford", "slug": "maria-bamford", "url": "https://revel.show/comedians/maria-bamford", "image_url": "…", "is_headliner": true }
],
"created_at": "2026-08-01T10:00:00.000Z",
"updated_at": "2026-09-01T10:00:00.000Z"
}url is the Revel event page and carries the ticket link. Link there rather than deep-linking a ticketing site — it is the attribution the free tier asks for.
Errors
| Status | error | When |
|---|---|---|
| 400 | invalid_request | A query parameter failed validation; the message names it. |
| 400 | invalid_cursor | The cursor is malformed or came from a different endpoint. |
| 401 | unauthorized | No bearer token, or the secret is unknown. |
| 403 | forbidden | The credential was revoked or expired, or the application is suspended. |
| 404 | not_found | Unknown id or city slug. |
| 429 | rate_limited | Over the per-minute or per-day limit; wait `retry_after` seconds. |
429 body
{ "error": "rate_limited", "message": "Rate limit exceeded", "retry_after": 12 }Terms of use
- Open to everyone, for commercial and non-commercial use.
- Link to the Revel event page for tickets — the
urlon every event. Ticketing links themselves are not exposed. - One key per application; don’t share keys or resell access to the API.
- Revel may suspend a key for abuse, and may change limits or fields with notice on this page.
- Listings are provided as-is; confirm details with the venue before relying on them. The Terms of Service apply.