본문으로 건너뛰기

팬 랭킹 조회

지금 방에 있는 청취자들의, 이 방송 후원 랭킹 상위 30명이에요. 방송이 끝나면 초기화돼요.

메서드 · 경로GET /v1/live/fans
필요한 권한fans.read
성공 응답200
방송 중이 아닐 때404 (OAPI_MNGR_0301)
export SPOON_BASE_URL="https://kr-openapi.spooncast.net"
export SPOON_ACCESS_TOKEN="{발급받은 access token}"

일본 지역이면 https://jp-openapi.spooncast.net 이에요 — 지역별 주소.

요청​

GET /v1/live/fans

헤더​

이름필수설명
Authorization✔Bearer {access_token} 형식이에요.

경로 파라미터 · 쿼리 파라미터 · 요청 바디가 없어요. 페이징도 없어요 — 상위 30명이 한 번에 와요.

요청 예시​

curl -H "Authorization: Bearer $SPOON_ACCESS_TOKEN" "$SPOON_BASE_URL/v1/live/fans"

응답​

{
"totalCount": 2,
"fans": [
{ "id": "Ab1Cd2Ef3Gh4Ij5Kl6Mn7O", "nickname": "스푼청취자", "rank": 1, "spoonCount": 1200 },
{ "id": "Pq8Rs9Tu0Vw1Xy2Za3Bc4D", "nickname": "라디오팬", "rank": 2, "spoonCount": 300 }
]
}
필드타입null설명
totalCountnumber아니오돌려준 목록의 크기예요. 최대 30이고, 전체 팬 수가 아니에요.
fansobject[]아니오누적 후원이 많은 순이에요.
fans[].idstring아니오청취자를 가리키는 값이에요. 암호화한 값이에요.
fans[].nicknamestring아니오닉네임이에요.
fans[].ranknumber아니오순위예요. 1부터 시작해요.
fans[].spoonCountnumber예이 방송에서 그 청취자가 쓴 누적 스푼이에요. 값이 없을 수 있으니 null 을 처리해요.
id 로 사람을 식별해요

id 는 이 사람의 고유 식별자예요. 같은 사람이면 항상 같은 값이라 출석 · 누적 · 랭킹의 키로 쓰면 돼요. nickname 은 바뀌고 중복될 수 있으니 식별에 쓰지 마세요.

값의 범위는 내 봇과 그 DJ 조합이에요. DJ 가 연동을 끊었다 다시 동의해도 유지돼요.

코드​

// fans.ts — node --experimental-strip-types fans.ts

interface Fan {
id: string;
nickname: string;
rank: number;
spoonCount: number | null;
}

interface Fans {
totalCount: number;
fans: Fan[];
}

const res = await fetch(`${process.env.SPOON_BASE_URL}/v1/live/fans`, {
headers: { Authorization: `Bearer ${process.env.SPOON_ACCESS_TOKEN}` },
});
if (!res.ok) throw new Error(`팬 랭킹 조회 실패: ${res.status}`);

const { totalCount, fans } = (await res.json()) as Fans;
console.log(`랭킹에 오른 ${totalCount}명 (최대 30)`);

for (const fan of fans.slice(0, 3)) {
const spoons = fan.spoonCount ?? 0; // null 이 올 수 있어요
console.log(`${fan.rank}위 ${fan.nickname} — ${spoons} 스푼`);
}

const top = fans.find((f) => f.rank === 1);
if (top) console.log(`오늘의 1등은 ${top.nickname} 님, ${top.spoonCount ?? 0} 스푼이에요!`);
node --experimental-strip-types fans.ts

주의​

봇 계정도 이 방송에 후원 이력이 있으면 랭킹에 올라요. 봇의 id 를 걸러내야 할 수 있어요.

상위 30명까지만 와요. 페이징이 없어요 — 31등부터는 랭킹의 의미가 없어서 애초에 주지 않아요. totalCount 도 전체 팬 수가 아니라 돌려준 목록의 크기(최대 30) 예요. 전체 청취자가 필요하면 청취자 목록 조회 를 쓰세요. 그쪽은 지금 방에 있는 사람 전부라 커서로 나눠 받아요.

지금 방에 있는 사람만 보여요. 후원하고 나간 사람은 랭킹에서 빠지고, 사람이 드나들 때마다 순위가 바뀌어요. 방송 내내의 누적이 필요하면 이벤트 스트림의 후원 이벤트로 직접 쌓아요.

랭킹은 이 방송 안에서의 누적이에요. DJ 의 전체 팬 순위가 아니에요.

입장 시점의 순위는 이벤트 스트림의 fanRank 로도 와요. "1위 팬 입장!" 같은 인사를 만들 때는 이 API 를 따로 부르지 않아도 돼요.

에러​

HTTPdetailCode무슨 일인가요어떻게 하나요
401없음토큰이 없거나 무효해요.DJ 에게 재연동을 안내해요.
403없음fans.read 권한이 없어요.권한을 추가해 재동의를 받아요.
404OAPI_MNGR_0301방송 중이 아니에요.오류가 아니라 상태예요. 잠시 뒤 다시 불러요.
502OAPI_MNGR_2302방송 서버 오류예요.백오프 후 재시도해요.

이 표에 없는 상태도 올 수 있어요. 잘못된 메서드·Content-Type(400 · 405 · 415, OAPI_MNGR_0103) · 호출 한도(429, 본문 없음) · 서버 오류(500, OAPI_MNGR_1002)는 모든 엔드포인트에 공통이에요 — 에러 코드에 있어요.

관련 문서​