Skip to content

Authentication

Every request to the API is authenticated with an API key of your organization, sent as a Bearer token:

GET /v1/events?limit=5 HTTP/1.1
Host: api.status302.com
Authorization: Bearer <your API key>

Keys look like tx_live_<keyId>_<secret>: the prefix tx_live_, a 12-character key id and a 43-character secret, all base62 (63 characters in total). The tx_live_ prefix lets secret scanners, GitHub’s included, recognize a leaked key.

  • Keys belong to the organization, not to the person who created them, so an integration keeps working when people leave. Each key records who created it and when it was last used, and from which IP address.
  • Status302 stores only a hash of the secret. The full key is shown once, when you create or rotate it. If you lose it, rotate the key.
  • Owners and admins create, edit, rotate and revoke keys in Settings → Developers. Members can see the key list. Every change is written to the organization’s audit log.
  • Keys need a plan with API access (Pro or higher). If the organization’s plan lapses, its keys answer 402 plan-required until a plan is active again.

Treat a key like a password: keep it in your secret store or environment, never in source control or in a browser. For browser code, use a stream ticket or call the API from your backend.

A key can only call the operations its scopes allow. Pick the fewest that your integration needs; you can change them later without issuing a new key (open streams of the key then reconnect, see close codes).

ScopeGrantsOperations
catalog:readEvents, search, calendar, attractions, venues, saved lists (read) and exports
17 operations
  • GET /v1/events
  • GET /v1/events/{id}
  • GET /v1/search
  • GET /v1/attractions/{id}
  • GET /v1/attractions/{id}/events
  • GET /v1/venues/{id}
  • GET /v1/venues/{id}/events
  • GET /v1/calendar/days
  • GET /v1/calendar/items
  • GET /v1/lists
  • GET /v1/lists/{listId}
  • GET /v1/lists/{listId}/items
  • GET /v1/lists/{listId}/export.csv
  • GET /v1/events/{id}/lists
  • GET /v1/exports
  • POST /v1/exports
  • GET /v1/exports/{exportId}
market:readMetrics, series, inventory changes, movers and compare
5 operations
  • GET /v1/events/{id}/inventory/changes
  • GET /v1/events/{id}/metrics
  • GET /v1/events/{id}/series
  • GET /v1/movers
  • GET /v1/compare/series
sales:readEvent sales, the sales feed and its summary
3 operations
  • GET /v1/events/{id}/sales
  • GET /v1/sales/feed
  • GET /v1/sales/summary
maps:readSeat maps and their live overlays
2 operations
  • GET /v1/events/{id}/map
  • GET /v1/events/{id}/map/overlay
streamConnecting to the realtime stream and its tickets; each topic also needs its REST scope (see the stream guide)
1 operations
  • POST /v1/stream/ticket
lists:writeCreate and change saved lists
6 operations
  • POST /v1/lists
  • DELETE /v1/lists/{listId}
  • PATCH /v1/lists/{listId}
  • POST /v1/lists/{listId}/items
  • DELETE /v1/lists/{listId}/items
  • PATCH /v1/lists/{listId}/items
alerts:writeAlert rules and their firing history (read and write)
6 operations
  • GET /v1/alerts/rules
  • POST /v1/alerts/rules
  • GET /v1/alerts/rules/{ruleId}
  • DELETE /v1/alerts/rules/{ruleId}
  • PATCH /v1/alerts/rules/{ruleId}
  • GET /v1/alerts/events
webhooks:writeWebhook endpoints and their deliveries (read and write)
9 operations
  • GET /v1/webhooks
  • POST /v1/webhooks
  • GET /v1/webhooks/{webhookId}
  • DELETE /v1/webhooks/{webhookId}
  • PATCH /v1/webhooks/{webhookId}
  • POST /v1/webhooks/{webhookId}/rotate-secret
  • POST /v1/webhooks/{webhookId}/test
  • GET /v1/webhooks/{webhookId}/deliveries
  • POST /v1/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver

GET /v1/usage is open to every key. Account, billing, team and key management are only available in the app, never to keys: a key calling them gets 403.

The create dialog offers three presets: Read only (catalog:read, market:read, sales:read, maps:read), Read + stream (the read scopes and stream) and Full (all scopes).

A request outside the key’s scopes answers 403 with the scope it needs:

{
"type": "https://status302.com/problems/insufficient-scope",
"title": "Forbidden",
"status": 403,
"detail": "this API key lacks the \"sales:read\" scope",
"requiredScope": "sales:read"
}

Restrict a key to the addresses your integration runs from. An allowlist holds up to 50 entries; each is an IPv4 or IPv6 address (203.0.113.7) or a CIDR prefix (203.0.113.0/24, 2001:db8::/48). An empty list allows any address.

A request from any other address answers 403 ip-not-allowed. Status302 checks the address that connects to it; behind your own NAT or proxy, that is your egress address.

Keys can expire (30, 90 or 365 days, or a date you choose) or live until you revoke them. From the expiry on, requests answer 401 invalid-api-key with the detail invalid API key: expired. Removing the expiry later is allowed.

Rotating a key issues a new secret with the same name, scopes, allowlist and expiry, and keeps the old secret valid for a grace period of your choice, from none up to 48 hours:

  1. In Settings → Developers, choose Rotate on the key and a grace period (for example 24 hours).
  2. Copy the new key and deploy it to every place that uses the old one.
  3. Once traffic moved over, nothing else is needed: the old secret stops working when the grace period ends, and its open streams close with code 4401.

The key list shows the old key as rotating until then, with its last use, so you can see whether anything still sends it. A grace of none revokes the old secret at once, for a key you believe leaked.

Revoking a key takes effect across the platform within about a second: REST requests answer 401 and open streams close with code 4401. Revocation can’t be undone; create a new key instead.

Problem types below are under https://status302.com/problems/ (see problem types).

Status Problem type When
401 invalid-api-key The key is malformed, unknown, revoked, expired or past its rotation grace. The response also carries WWW-Authenticate: Bearer error="invalid_token".
403 insufficient-scope The key lacks the operation’s scope; requiredScope names it.
403 ip-not-allowed The request came from an address outside the key’s allowlist.
403 about:blank The operation isn’t available to API keys (account and key management).
402 plan-required The organization’s plan has no API access (feature: "api") or doesn’t include what was asked for.

The detail of an invalid-api-key problem says whether the key was revoked or expired. See errors for the full catalogue.

Never ship a key to a browser. For a browser page that needs the realtime stream, your backend asks for a ticket with its key and hands it to the page:

samples/curl/stream-ticket.sh
#!/usr/bin/env bash
# A single-use stream ticket (valid 60 s) for a browser: your backend calls this
# with its key and hands the ticket to the page, which connects to
# wss://api.status302.com/v1/stream?ticket=<ticket>. The key never reaches the browser.
set -euo pipefail
API="${STATUS302_API_URL:-https://api.status302.com}"
curl --fail-with-body -sS -X POST "$API/v1/stream/ticket" \
-H "Authorization: Bearer $STATUS302_API_KEY"

The page connects to wss://api.status302.com/v1/stream?ticket=<ticket>. A ticket is valid for one connection within 60 seconds and acts as the key that issued it (same scopes and plan). Request a new ticket for every reconnect; the SDK stream clients do this for you when you pass them a ticket function. See the stream guide.

The Status302 web app uses the same API with a session cookie instead of a key. The two differ in ways that matter if you are tempted to reuse a browser session in a script:

API key App session
Sent as Authorization: Bearer … status302_session cookie (HttpOnly)
Scopes The key’s scopes Everything the signed-in member’s role allows
CSRF protection Not needed X-CSRF-Token header on every write, and an allowed Origin
Quotas and RateLimit headers Per your plan, see rate limits Not metered
Lifetime Until revoked or expired; rotatable Sliding expiry; ends at sign-out
Operations The public API The public API plus account, billing, team and key management

Integrations must use keys: sessions are tied to a person, expire, and need CSRF handling. A request with an Authorization: Bearer header is always treated as a key request, even if a session cookie is also present.