Getting started
This guide takes you from no key to live market data in a few minutes. Every code sample on this site is a file in the repository’s
site/samples/ directory, and each one runs against a real API on every change, so what you copy works.
Before you start
Section titled “Before you start”- An organization on the Pro plan or higher. Core and Free organizations can’t create keys. See entitlements by plan.
- The owner or admin role in that organization, to create keys.
- For the shell samples:
curlandjq.
1. Create an API key
Section titled “1. Create an API key”- In the app, open Settings → Developers and choose Create key.
- Name the key after the integration that will use it (for example
pricing-bot), and pick its scopes. Read only covers the catalog, market data, sales and maps. Addstreamfor the realtime stream (each topic also needs its read scope, and thealertstopicalerts:write); the write scopes are for lists, alert rules and webhooks. See scopes. - Optionally restrict the key to your servers’ IP addresses and give it an expiry.
- Copy the key. It is shown once: Status302 only keeps a hash of it.
Keep the key out of your code. The samples read it from the environment:
export STATUS302_API_KEY="tx_live_…"export STATUS302_API_URL="https://api.status302.com" # the default; point it at another environment if you have one2. Make your first request
Section titled “2. Make your first request”List the next five upcoming events. The key goes in the Authorization header as a Bearer token.
#!/usr/bin/env bash# The next five upcoming events in the catalog.set -euo pipefailAPI="${STATUS302_API_URL:-https://api.status302.com}"
curl --fail-with-body -sS "$API/v1/events?limit=5" \ -H "Authorization: Bearer $STATUS302_API_KEY"// The next five upcoming events in the catalog.import { Status302 } from "@status302/sdk";
const status302 = new Status302({ apiKey: process.env.STATUS302_API_KEY, baseUrl: process.env.STATUS302_API_URL });
const page = await status302.get("/v1/events", { query: { limit: 5 } });for (const event of page.items) { console.log(event.id, event.name, event.startsAt ?? "date TBA", event.venue?.city ?? "");}# The next five upcoming events in the catalog.import os
from status302 import Status302
with Status302(os.environ["STATUS302_API_KEY"], base_url=os.environ.get("STATUS302_API_URL", "https://api.status302.com")) as status302: page = status302.list_events(limit=5) for event in page["items"]: city = (event.get("venue") or {}).get("city") or "" print(event["id"], event["name"], event["startsAt"] or "date TBA", city)// The next five upcoming events in the catalog, with the standard library only.package main
import ( "encoding/json" "fmt" "log" "net/http" "os")
type eventPage struct { Items []struct { ID int64 `json:"id"` Name string `json:"name"` StartsAt *string `json:"startsAt"` } `json:"items"` NextCursor *string `json:"nextCursor"`}
func main() { api := os.Getenv("STATUS302_API_URL") if api == "" { api = "https://api.status302.com" } req, err := http.NewRequest(http.MethodGet, api+"/v1/events?limit=5", nil) if err != nil { log.Fatal(err) } req.Header.Set("Authorization", "Bearer "+os.Getenv("STATUS302_API_KEY"))
res, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer res.Body.Close() if res.StatusCode != http.StatusOK { var problem struct{ Title, Detail string } _ = json.NewDecoder(res.Body).Decode(&problem) log.Fatalf("%s: %s %s", res.Status, problem.Title, problem.Detail) }
var page eventPage if err := json.NewDecoder(res.Body).Decode(&page); err != nil { log.Fatal(err) } for _, e := range page.Items { starts := "date TBA" if e.StartsAt != nil { starts = *e.StartsAt } fmt.Println(e.ID, e.Name, starts) }}The answer is a page of events, soonest first (abridged):
{ "items": [ { "id": 4102, "name": "J. Cole: The Fall-Off Tour", "startsAt": "2026-10-28T18:30:00Z", "status": "onsale", "venue": { "id": 77, "name": "Co-op Live", "city": "Manchester", "stateCode": null, "countryCode": "GB" }, "metrics": { "scope": "primary", "currency": "GBP", "floor": 4420, "median": 7275, "inventory": 1372, "sales24h": 123 } } ], "nextCursor": "eyJzIjoic3RhcnRzQXQiLCJ2IjoiMjAyNi0xMC0yOFQxODozMDowMFoiLCJpIjo0MTAyfQ"}Prices are integers in the currency’s minor unit: 4420 GBP is £44.20. See money and currency.
3. Read an event’s market metrics
Section titled “3. Read an event’s market metrics”GET /v1/events/{id}/metrics returns one row per market (primary for Ticketmaster face value, tm_resale for verified resale) with the
floor, median, inventory, sales and their changes over 24 hours, 72 hours and 7 days.
#!/usr/bin/env bash# Market metrics (floor, median, inventory, sales, changes) of the next upcoming event.set -euo pipefailAPI="${STATUS302_API_URL:-https://api.status302.com}"AUTH="Authorization: Bearer $STATUS302_API_KEY"
event_id=$(curl --fail-with-body -sS "$API/v1/events?limit=1" -H "$AUTH" | jq -r '.items[0].id')
curl --fail-with-body -sS "$API/v1/events/$event_id/metrics" -H "$AUTH" \ | jq '.items[] | {scope, currency, floor, median, inventory, sales24h, chg24h, asOf}'// Market metrics (floor, median, inventory, sales, changes) of the next upcoming event.import { Status302 } from "@status302/sdk";
const status302 = new Status302({ apiKey: process.env.STATUS302_API_KEY, baseUrl: process.env.STATUS302_API_URL });
const { items } = await status302.get("/v1/events", { query: { limit: 1 } });const event = items[0];if (!event) throw new Error("the catalog has no upcoming events");
const metrics = await status302.get("/v1/events/{id}/metrics", { path: { id: event.id } });console.log(event.name);for (const m of metrics.items) { // Money is integer minor units of `currency`; changes are fractions (0.12 = +12%). console.log(m.scope, { currency: m.currency, floor: m.floor, median: m.median, inventory: m.inventory, sales24h: m.sales24h, chg24h: m.chg24h, asOf: m.asOf });}# Market metrics (floor, median, inventory, sales, changes) of the next upcoming event.import os
from status302 import Status302
with Status302(os.environ["STATUS302_API_KEY"], base_url=os.environ.get("STATUS302_API_URL", "https://api.status302.com")) as status302: items = status302.list_events(limit=1)["items"] if not items: raise SystemExit("the catalog has no upcoming events") event = items[0]
metrics = status302.get_event_metrics(event["id"]) print(event["name"]) for m in metrics["items"]: # Money is integer minor units of `currency`; changes are fractions (0.12 = +12%). print(m["scope"], m["currency"], m["floor"], m["median"], m["inventory"], m["sales24h"], m["chg24h"], m["asOf"])4. Install an SDK
Section titled “4. Install an SDK”The SDKs are typed from the same OpenAPI spec as the API reference. They follow cursors for you, retry rate-limited requests
after Retry-After, raise typed errors, verify webhooks and include a stream client that reconnects and resumes on its own.
npm install @status302/sdk # TypeScript / JavaScript, Node.js 22+pip install status302 # Python 3.11+See the TypeScript and Python guides.
Next steps
Section titled “Next steps”- Authentication: scopes, IP allowlists, rotation without downtime.
- Rate limits: read the
RateLimitheaders and handle429. - Realtime stream: live sales, inventory changes and alert firings over one WebSocket.
- Webhooks: get alert firings and on-sale announcements pushed to your server.

