API Reference · 룰렛·티켓
룰렛 추첨
사용자의 티켓 한 장으로 서버에서 당첨 칸을 결정하고 연결된 지급 경로를 처리합니다. 포인트 지급을 당첨 팝업의 '보상 받기' 시점으로 미룰 수도 있습니다.
/api/v1/contents/{content_id}/roulettes/{group_id}/spin요청
Authorization: Bearer sess_*— 콘텐츠 세션 토큰.content_id(path) — 토큰의 콘텐츠와 일치해야 합니다.group_id(path) — 룰렛 그룹 UUID.session_id(body, 필수) — 토큰의 세션 ID와 일치해야 합니다.ticket_type_id(body, 필수) — 허용된 티켓 유형 UUID. 개별 티켓은 서버가 만료 임박 순으로 고릅니다.idempotency_key(body 또는Idempotency-Key헤더, 필수) — 요청마다 고유한 문자열, 최대 128자. 둘 다 보내면 body가 우선합니다.claim(body, 선택) — 포인트 지급 시점."auto"는 추첨 응답 전에 지급합니다."deferred"는 추첨·티켓 차감·결과 반환까지만 하고, 지급은 당첨 보상 받기 호출 때 합니다. 생략하면"auto"(기존 즉시 지급)이며, 다른 값은400입니다.
curl -X POST \
-H "Authorization: Bearer <session_token>" \
-H "Content-Type: application/json" \
-d '{"session_id":"<session_uuid>","ticket_type_id":"<ticket_type_uuid>","idempotency_key":"<unique_spin_key>","claim":"deferred"}' \
"https://added-dev.blomics.net/api/v1/contents/<content_id>/roulettes/<group_id>/spin"성공 응답
200 — reward.slot_id가 서버가 뽑은 칸입니다. remaining_tickets는 사용한 티켓 유형의 남은 수량입니다. duplicate: true는 같은 키로 다시 조회한 결과로, 티켓을 다시 소비하거나 재추첨하지 않았다는 뜻입니다. 아래는 즉시 지급(claim 생략 또는 "auto")의 예입니다.
{
"draw_id": "<draw_uuid>",
"roulette_group_id": "<group_uuid>",
"roulette_id": "<roulette_uuid>",
"roulette_version": 1,
"ticket_id": "<consumed_ticket_uuid>",
"reward": { "slot_id": "<slot_uuid>", "label": "100P", "display_order": 0,
"reward_type": "point", "point": 100 },
"event_log_id": "<event_log_uuid>",
"postback_id": "<postback_uuid>",
"delivery": "delivered",
"delivery_code": null,
"remaining_tickets": 2,
"duplicate": false
}postback_id와 event_log_id는 상황에 따라 null일 수 있습니다. delivery·delivery_code는 포스트백이 있을 때만 포함되며 delivery는 delivered·pending·failed 중 하나입니다. 내부 적립에는 balance_after가, 지급 안내가 필요한 경우 user_message가 포함될 수 있습니다. 당첨 칸 결과와 지급 완료 여부를 구분해서 표시하세요.
지연 지급 응답 (claim: "deferred")
포인트 당첨이면 claim_status: "unclaimed"가 붙고 아직 지급하지 않았으므로 postback_id는 null, delivery·delivery_code·balance_after는 없습니다. 티켓은 이미 차감됐고 당첨 기록(event_log_id)과 예산·한도 집계는 추첨 시점에 끝납니다. 당첨 팝업에서 사용자가 '보상 받기'를 누르면 draw_id로 당첨 보상 받기를 호출하세요.
{
"draw_id": "<draw_uuid>",
"roulette_group_id": "<group_uuid>",
"roulette_id": "<roulette_uuid>",
"roulette_version": 1,
"ticket_id": "<consumed_ticket_uuid>",
"reward": { "slot_id": "<slot_uuid>", "label": "100P", "display_order": 0,
"reward_type": "point", "point": 100 },
"event_log_id": "<event_log_uuid>",
"postback_id": null,
"remaining_tickets": 2,
"duplicate": false,
"claim_status": "unclaimed"
}claim_status는 지연 지급으로 뽑은 포인트 당첨에만 있습니다."unclaimed"는 '보상 받기' 전,"claimed"는 지급 처리가 끝났다는 뜻입니다. 즉시 지급 추첨에는 이 필드가 없습니다.- 꽝(0포인트)은 받을 것이 없으므로
claim: "deferred"여도 늘 즉시 완료되며claim_status가 없습니다. 꽝에는 보상 받기를 호출하지 않아도 됩니다. - 지급 방식은 처음 추첨할 때 정해집니다. 같은 키로 재요청하면서
claim값을 바꿔도 바뀌지 않으며, 미수령 당첨은 추첨 재요청으로 지급되지 않습니다(지급은 보상 받기에서만). - 사용자가 팝업을 닫거나 이탈해 보상 받기를 못 했으면 미수령으로 남습니다. 다음 진입 때 미수령 당첨 조회로 다시 안내하세요.
idempotency_key로 재시도하세요. 이미 저장된 추첨이면 같은 칸을 돌려주고 미완료 지급을 이어갑니다(지연 지급 당첨은 claim_status: "unclaimed" 그대로 돌려줍니다). 해결 전 키를 보존하고 추첨 버튼을 중복 실행하지 마세요. 응답의 확률표 버전이 화면과 다르면 상세를 다시 조회한 뒤 결과를 표시하세요.오류 처리
400 INVALID_PARAM— 필수 값 누락·형식 오류, 허용되지 않은claim값.401 UNAUTHORIZED/SESSION_EXPIRED— 세션 인증 실패·만료.404 NOT_FOUND— 경로의 콘텐츠 또는 본문 세션 ID가 세션 토큰과 불일치합니다.409 ALREADY_EXISTS— 같은 멱등 키를 다른 룰렛 또는 티켓 유형에 재사용했습니다.499 NOT_FOUND— 룰렛·지급 경로·해당 유형의 이용 가능한 티켓이 없습니다.499 ROULETTE_UNAVAILABLE/ROULETTE_COMPLETED/TICKET_NOT_ACCEPTED— 운영 상태 또는 허용 티켓 조건 불일치.499 BUDGET_EXHAUSTED/CAMPAIGN_PAUSED/CAMPAIGN_EXPIRED/DAILY_LIMIT_EXCEEDED/USER_LIMIT_EXCEEDED/USER_BLOCKED— 지급 조건 거부. 지연 지급에서도 이 판정은 추첨 시점에 합니다.
당첨 전 거부에는 티켓을 소비하지 않거나 반환합니다. 응답을 받지 못한 경우에는 추첨 원장이 남았을 수 있으므로 반드시 같은 키로 결과를 확인하세요. 오류 본문은 공통 { code, message, data } 형식입니다.