ZUKU API — Getting Started
ZUKU API에 처음 붙는 개발자를 위한 빠른 시작 가이드입니다.
상세 계약은 Authentication · Contents · Errors를 이어서 읽으세요.
목차
1. Base URL · Versioning
| 환경 | Base URL |
|---|---|
| 프로덕션 | https://zuzunza.com/api/v1 |
| 로컬 | http://localhost:3001/api/v1 |
| Next 게이트(개발) | 동일 출처 /api/v1 → 백엔드로 리라이트 |
- URL에 항상
/api/v1을 붙입니다. 버전 없는/api/feeds는 지원하지 않습니다. - 응답 헤더:
X-API-Version: v1 - 봉투 필드:
meta.version="v1" - 현재 활성 버전은 v1뿐이며, v2는 기획 단계입니다. 자세한 폐기·호환 정책은 Changelog.
예외(버전 접두사 없음, 기존 계약 유지):
| 메서드 | 경로 | 설명 |
|---|---|---|
GET |
/api/health |
헬스체크 |
GET |
/api/wasm/contract |
WASM 격리 경계·리소스 한도 계약(내부 필터 규칙은 비공개) |
GET |
/uploads/... |
업로드 파일 정적 서빙 |
2. 요청 헤더
| 헤더 | 필수 | 설명 |
|---|---|---|
Content-Type |
JSON 본문 시 | application/json |
Authorization |
인증 필요 시 | Bearer <access_token> |
X-API-Key |
서버-투-서버 시 | 개발자 키 (sk_live_…). 예: POST /contents |
X-Request-ID |
권장 | 클라이언트 UUID (추적용) |
Accept-Language |
선택 | ko-KR (기본) |
업로드(POST /uploads)는 multipart/form-data이며, 브라우저가 boundary를 포함한 Content-Type을 설정하도록 둡니다.
3. 응답 봉투
성공:
{
"success": true,
"data": { },
"meta": {
"request_id": "req_…",
"timestamp": "2026-08-22T04:00:00Z",
"version": "v1"
}
}
실패:
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "유효한 Bearer 세션이 필요합니다"
},
"meta": { "request_id": "…", "timestamp": "…", "version": "v1" }
}
검증 실패 시 error.details: [{ field, message }]가 붙을 수 있습니다.
일부 삭제·폐기 응답은 HTTP 204로 본문이 없을 수 있습니다.
4. 5분 퀵스타트
4.1 공개 피드 조회 (curl)
curl -sS "https://zuzunza.com/api/v1/feeds/hype?page=1&per_page=20" \
-H "Accept-Language: ko-KR" \
-H "X-Request-ID: $(uuidgen)"
4.2 로그인 → me (JS/TS fetch)
const API = "https://zuzunza.com/api/v1";
async function login(identifier: string, password: string) {
const res = await fetch(`${API}/auth/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept-Language": "ko-KR",
"X-Request-ID": crypto.randomUUID(),
},
body: JSON.stringify({ identifier, password }),
});
const env = await res.json();
if (!env.success) throw new Error(`${env.error.code}: ${env.error.message}`);
return env.data.tokens as {
access_token: string;
refresh_token: string;
token_type: string;
expires_in: number;
};
}
async function me(accessToken: string) {
const res = await fetch(`${API}/auth/me`, {
headers: { Authorization: `Bearer ${accessToken}` },
});
const env = await res.json();
if (!env.success) throw new Error(env.error.message);
return env.data;
}
const tokens = await login("honggildong", "SecureP@ss123");
const profile = await me(tokens.access_token);
console.log(profile);
4.3 콘텐츠 생성 (Bearer 또는 API 키)
# Bearer
curl -sS -X POST "https://zuzunza.com/api/v1/contents" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"category":"hype","type":"video","title":"첫 작품"}'
# 또는 X-API-Key (서버-투-서버)
curl -sS -X POST "https://zuzunza.com/api/v1/contents" \
-H "X-API-Key: $ZUKU_API_KEY" \
-H "Content-Type: application/json" \
-d '{"category":"swipe","type":"video","title":"숏폼"}'
가입·캡차·키 발급 절차는 Authentication · Captcha를 참고하세요.
5. Rate Limits
모든 JSON 응답에 다음 헤더가 붙습니다 (format_response).
| 헤더 | 의미 |
|---|---|
X-RateLimit-Limit |
윈도우당 허용 한도 |
X-RateLimit-Remaining |
남은 횟수 |
X-RateLimit-Reset |
리셋 epoch(초) |
구현 참고: 현재 스테이징 백엔드는 헤더에 정적 더미 값(예: Limit 1000 / Remaining 999)을 넣습니다. 설계 문서(docs/06-api/03-rate-limiting.md)의 등급별 한도는 목표 계약이며, 실제 차단(429)은 인프라·게이트웨이 정책과 함께 점진 적용됩니다.
권장 클라이언트 동작:
429또는 Remaining ≤ 0이면Reset까지 대기 후 재시도- 인증 API(register/login)는 IP당 더 낮은 한도를 가정하고 지수 백오프
- 배치 작업은
X-API-Key+ 서버 사이드 큐로 분산
설계상 등급 개요(목표):
| 등급 | 요청/분 (목표) |
|---|---|
| 익명 | 30 |
| 일반 | 60 |
| 크리에이터 | 120 |
| 프리미엄 | 200 |
6. 페이네이션
page / per_page
피드·댓글·알림·Jump 목록 등 다수가 사용합니다.
| 파라미터 | 기본 | 비고 |
|---|---|---|
page |
1 |
1부터 |
per_page |
구현 기본(대개 20) | 상한은 엔드포인트마다 clamp |
응답의 pagination 객체는 Pagination::compute 결과(page, per_page, total, has_next 등)를 포함합니다.
cursor (before / after)
커뮤니티 GET /feed, DM 메시지, 일부 스레드 API는 before / after 커서를 사용합니다. 상세는 Feeds · Social.
recommendations
GET /contents/{id}/recommendations는 limit(1–50, 기본 8) · offset을 사용합니다.
7. 다음 문서
- Authentication — 토큰·캡차·API 키
- Contents / Feeds — 읽기·쓰기 핵심
- Media — 업로드·Jump 재생
- Social — 댓글·알림·DM
- Errors — 코드 표와 처리 패턴
웹 미리보기: /docs/api · /docs/api/getting-started