Read the current broadcast
Read information about the broadcast the DJ is running right now: title, start and end times, listener count, greeting, categories, and chat-frozen state, all in one call.
| Method and path | GET /v1/live |
| Permission | live.read |
| Success | 200 |
| When not on air | 404 (OAPI_MNGR_0301) |
export SPOON_BASE_URL="https://kr-openapi.spooncast.net"
export SPOON_ACCESS_TOKEN="{your access token}"
For the Japan region use https://jp-openapi.spooncast.net — see regions.
Request
GET /v1/live
Headers
| Name | Required | Description |
|---|---|---|
Authorization | ✔ | Bearer {access_token}. |
There are no path parameters, query parameters, or body. The token decides which DJ's broadcast this is — one token is one DJ's consent, so a bot has nowhere to name someone else's broadcast.
Request example
curl -H "Authorization: Bearer $SPOON_ACCESS_TOKEN" "$SPOON_BASE_URL/v1/live"
Response
{
"liveId": 10001,
"title": "Tonight's late-night radio",
"startedAt": "2026-09-01T13:00:00Z",
"closeAirTime": "2026-09-01T15:00:00Z",
"listenerCount": 42,
"totalListenerCount": 137,
"welcomeMessage": "Welcome! Send your stories in chat",
"isChatFrozen": false,
"categories": ["talk"],
"tags": ["latenightradio", "stories"]
}
| Field | Type | Nullable | Description |
|---|---|---|---|
liveId | number | No | The id of this broadcast session. |
title | string | No | The broadcast title. |
startedAt | string | No | When it started. ISO-8601 UTC (Z). |
closeAirTime | string | No | The scheduled end time. ISO-8601 UTC (Z). |
listenerCount | number | No | Listeners connected right now. |
totalListenerCount | number | No | The cumulative number of people who have passed through. |
welcomeMessage | string | No | The greeting the DJ pinned to the room. An empty string if they wrote none. |
isChatFrozen | boolean | No | Whether chat is frozen. |
categories | string[] | No | Broadcast categories (sing, talk, …). |
tags | string[] | No | Hashtags the DJ added. |
Code
// live.ts — node --experimental-strip-types live.ts
interface Live {
liveId: number;
title: string;
startedAt: string;
closeAirTime: string;
listenerCount: number;
totalListenerCount: number;
welcomeMessage: string;
isChatFrozen: boolean;
categories: string[];
tags: string[];
}
const res = await fetch(`${process.env.SPOON_BASE_URL}/v1/live`, {
headers: { Authorization: `Bearer ${process.env.SPOON_ACCESS_TOKEN}` },
});
if (res.status === 404) {
console.log('Not on air. Check again shortly.');
} else if (!res.ok) {
throw new Error(`Lookup failed: ${res.status}`);
} else {
const live = (await res.json()) as Live;
console.log(`[${live.liveId}] ${live.title} — ${live.listenerCount} listening (${live.totalListenerCount} total)`);
if (live.isChatFrozen) console.log('Chat is frozen. Holding off on posting.');
}
node --experimental-strip-types live.ts
Watch out
You cannot send chat while isChatFrozen is true. Send chat fails,
because bots follow the same rules as listeners. Checking this value before you post avoids
the failure up front.
liveId is how a bot tells broadcast sessions apart. Use it as the idempotency key for
rules like "once per broadcast", and to decide on reconnect whether this is the same
broadcast or a new one. Using startedAt instead splits one broadcast in two as soon as
the value shifts even slightly.
Do not confuse listenerCount with totalListenerCount. The first is connected right
now, the second is the cumulative count of everyone who passed through. The
cumulative one never goes down.
You do not need to poll this endpoint to find out whether a broadcast started. The event stream
returns 404 before connecting when the DJ is not on air, so retrying the connection is enough —
see the connection loop.
Errors
| HTTP | detailCode | What happened | What to do |
|---|---|---|---|
401 | none | The token is missing or invalid. | Ask the DJ to authorize again. |
403 | none | The live.read permission is missing. | Add the permission and get consent again. |
404 | OAPI_MNGR_0301 | The DJ is not on air. | A state, not an error. Call again shortly. |
502 | OAPI_MNGR_2302 | Broadcast server error. | Retry after a backoff. |
States outside this table can arrive too. A wrong method or Content-Type
(400, 405, 415 — OAPI_MNGR_0103), the call quota (429, no body), and server errors
(500 — OAPI_MNGR_1002) are common to every endpoint — see
Error codes.
Related documents
- Endpoint list — the full endpoint list.
- List listeners — who is in the room right now.
- Event stream — what happens during the broadcast, in real time.
- Choosing permissions — what
live.readgrants. - Error codes — the full list of error codes.