API Docs
기업 시스템과 바로 연결할 수 있는 API
업로드 시작, 처리 완료, 재생 발급, 과금 상태 업데이트라는 핵심 흐름을 중심으로 정리했습니다.
OpenAPI 스펙
/docs/openapi.yaml
빠른 시작
요청 3번으로 첫 영상 재생까지
# 1. 자산을 생성하고 사전 서명된 업로드 URL을 받습니다
curl -X POST http://127.0.0.1:3000/api/v1/uploads/initiate \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": 1,
"filename": "demo.mp4",
"bytes_expected": 1024,
"source_height": 720,
"content_type": "video/mp4"
}'
# 2. 반환된 upload_url로 파일을 PUT한 뒤 완료 처리합니다
curl -X PUT "$UPLOAD_URL" --upload-file demo.mp4
curl -X POST http://127.0.0.1:3000/api/v1/uploads/$UPLOAD_ID/complete \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"bytes_received": 1024}'
# 3. playback_status가 ready가 되면 재생 URL을 조회합니다
curl http://127.0.0.1:3000/api/v1/playback/$ASSET_ID \
-H 'X-API-Key: YOUR_API_KEY'한 줄 임베드
어떤 페이지에도 바로 삽입하세요
playback_status가 ready가 되면 iframe이나 nulx-player 웹 컴포넌트로 자산을 임베드할 수 있습니다. 두 방식 모두 /embed/:id를 가리키며 호스팅된 시청 페이지와 동일한 자동재생 및 토큰 규칙을 따릅니다.
방법 A: iframe
<iframe src="https://nulx.dev/embed/YOUR_ASSET_ID" style="width: 100%; aspect-ratio: 16 / 9; border: 0;" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen ></iframe>
방법 B: 웹 컴포넌트
<script src="https://nulx.dev/nulx-player.js" async></script> <nulx-player playback-id="YOUR_ASSET_ID"></nulx-player>
음소거 자동재생을 원하면 ?autoplay=1 (또는 <nulx-player>의 autoplay 속성)을 추가하고, 재생 토큰이 필요한 자산에는 token 속성/쿼리 파라미터를 추가하세요.
대표 엔드포인트
GET /api/v1/tenants POST /api/v1/uploads/initiate POST /api/v1/uploads/:id/complete POST /api/v1/transcoding_jobs/next (Idempotency-Key 필수, 1~255바이트) POST /api/v1/transcoding_jobs/:id/heartbeat POST /api/v1/transcoding_jobs/:id/complete GET /api/v1/playback/:id POST /api/v1/billing/checkout POST /api/v1/billing/webhook
프로덕션 환경에서는 고정된 개발용 토큰 대신, 길고 무작위한 SSTREAM_ADMIN_TOKEN 값을 사용하세요.
인증 방식
- X-API-Key — 테넌트 범위의 API 호출
- X-SSTREAM-ADMIN-TOKEN — worker 및 부트스트랩 관리
- PayPal webhook — 프로덕션에서는 서명을 검증하세요. 시뮬레이션된 헤더는 로컬 또는 비프로덕션 흐름에서만 사용하세요
Launch flow
First video path
01
Create or select a tenant and API key with assets:write.
02
Initiate upload, PUT the file to R2, then complete the upload.
03
Worker leases the job, publishes HLS/DASH/thumbnail/captions, and sends heartbeats.
04
Read /api/v1/playback/:id with either numeric id or external_id and embed the returned HLS URL.
Endpoint contracts
| Endpoint | Purpose | Must include |
|---|---|---|
| POST /api/v1/uploads/initiate | Create a tenant-scoped direct upload session. | tenant_id, filename, bytes_expected, content_type, source_width, source_height |
| POST /api/v1/uploads/:id/complete | Mark upload complete and enqueue transcode. | bytes_received no larger than bytes_expected |
| POST /api/v1/transcoding_jobs/next | Lease one job for a trusted worker. | X-SSTREAM-ADMIN-TOKEN; Idempotency-Key (required, 1–255 bytes) |
| POST /api/v1/transcoding_jobs/:id/heartbeat | Renew lease and publish progress. | X-SSTREAM-JOB-LEASE-TOKEN, progress, worker_id, stage |
| POST /api/v1/transcoding_jobs/:id/complete | Publish finished playback artifacts. | manifest_path; dash_manifest_path when DASH requested; thumbnail_path when thumbnail enabled; subtitle_paths for requested captions |
| GET /api/v1/playback/:id | Issue playback URLs and token. | Use numeric id or asset external_id; asset must be ready |
업로드 예시
curl -X POST http://127.0.0.1:3000/api/v1/uploads/initiate \
-H 'X-SSTREAM-ADMIN-TOKEN: YOUR_LONG_RANDOM_ADMIN_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"tenant_id": 1,
"filename": "demo.mp4",
"bytes_expected": 1024,
"source_height": 720,
"content_type": "video/mp4"
}'Common errors
- 401 unauthorized — missing or invalid X-API-Key / admin token.
- 403 insufficient_scope — API key lacks a required scope such as assets:write or billing:write.
- 409 stale or invalid lease token — worker callback is no longer the active lease owner.
- 422 invalid_transcoding_result — completion omitted required HLS/DASH/thumbnail/caption artifact paths.
- 429 rate_limited — retry after the upload or billing window resets.