diff --git a/content/docs-ko/api/cookbook.md b/content/docs-ko/api/cookbook.md new file mode 100644 index 0000000..7aa7d71 --- /dev/null +++ b/content/docs-ko/api/cookbook.md @@ -0,0 +1,210 @@ +--- +title: API cookbook +description: 인증, 작업, 생성, 업로드, Asset Library, Reference Analysis를 위한 Sume Public API 예시입니다. +--- + +이 cookbook은 자주 쓰는 Sume API 워크플로를 짧은 예시로 정리합니다. 정확한 +필드와 enum은 [API 레퍼런스](/ko/api/reference)와 +[`/api/openapi.json`](/api/openapi.json)을 사용하세요. + +## Setup + +```bash +export SUME_API_KEY="sume_live_..." +export SUME_API_BASE_URL="https://www.sume.so/api/v1" +``` + +키 확인: + +```bash +curl "$SUME_API_BASE_URL/me" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +크레딧 확인: + +```bash +curl "$SUME_API_BASE_URL/credits" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +## 비디오 작업 생성과 폴링 + +작업 생성: + +```bash +curl "$SUME_API_BASE_URL/videos/generations" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "A creator holds a moisturizer jar in soft morning light.", + "duration": 4, + "aspect_ratio": "9:16", + "resolution": "480p", + "generate_audio": false + }' +``` + +응답의 `job_id`를 저장합니다. + +상태 폴링: + +```bash +curl "$SUME_API_BASE_URL/jobs/job_123" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +결과 가져오기: + +```bash +curl "$SUME_API_BASE_URL/jobs/job_123/result" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +## Brand reference로 이미지 생성 + +현재 Brand DNA 프로필 조회: + +```bash +curl "$SUME_API_BASE_URL/brand/current" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +응답에 `images[].reference_url`이 있으면 이미지 생성 reference로 전달할 수 +있습니다. + +```bash +curl "$SUME_API_BASE_URL/images/generations" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "Premium skincare product ad using the brand reference.", + "aspect_ratio": "1:1", + "image_count": 1, + "reference_image_urls": [ + "https://media.sume.so/example-reference.jpg" + ] + }' +``` + +워크스페이스에 반환된 reference URL만 사용하고, private 또는 signed URL을 +로그에 남기지 마세요. + +## Asset Library 비디오 업로드 + +업로드 대상 요청: + +```bash +curl "$SUME_API_BASE_URL/uploads/presign" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "purpose": "asset_library_video", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +반환된 `upload_url`과 `required_headers`로 파일 바이트를 업로드합니다. Storage +PUT 요청에는 Sume API `Authorization` 헤더를 넣지 마세요. + +업로드 finalize: + +```bash +curl "$SUME_API_BASE_URL/assets" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "object_key": "uploads/...", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +## Asset Library 장면 검색 + +```bash +curl "$SUME_API_BASE_URL/assets?q=product%20demo%20hook&limit=5&sort=relevance" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +하나의 장면 조회: + +```bash +curl "$SUME_API_BASE_URL/assets/asset_123" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +Scene asset에는 scene-level `media_url`, `thumbnail_url`, `source_video`, +`scene` metadata, search context가 포함될 수 있습니다. + +## Face Swap source video 준비 + +Face Swap은 `face_swap_source_video` purpose로 업로드한 Sume media URL이 +필요합니다. + +```bash +curl "$SUME_API_BASE_URL/uploads/presign" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "purpose": "face_swap_source_video", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +바이트 업로드 후 Face Swap 작업 생성: + +```bash +curl "$SUME_API_BASE_URL/face-swap" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "source_video_url": "https://media.sume.so/example-source.mp4", + "avatar_ids": ["avatar_123"], + "duration_seconds": 6, + "aspect_ratio": "9:16" + }' +``` + +반환된 각 job id를 `GET /jobs/{jobId}`로 폴링합니다. + +## Reference Analysis + +Reference Analysis는 공개 TikTok 또는 Instagram Reel URL을 받습니다. + +```bash +curl "$SUME_API_BASE_URL/reference-analysis" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "url": "https://www.tiktok.com/@example/video/123", + "locale": "ko" + }' +``` + +응답에는 `required_credits`와 `job_id`가 포함됩니다. Jobs endpoint로 폴링하고 +최종 결과를 가져오세요. + +## 실패 처리 + +API 요청 실패 시 `request_id`를 보관합니다. + +```json +{ + "error": { + "code": "invalid_request", + "message": "A human-readable error message.", + "details": {} + }, + "request_id": "req_123" +} +``` + +Job 실패 시 job id, status, 정리된 error code/message만 기록하세요. API 키, +signed URL, storage object key, provider payload, private media URL, 사용자 +이메일, workspace/user id는 로그에 남기지 마세요. diff --git a/content/docs-ko/api/reference.md b/content/docs-ko/api/reference.md index e271cb2..2ce6a17 100644 --- a/content/docs-ko/api/reference.md +++ b/content/docs-ko/api/reference.md @@ -1,25 +1,26 @@ --- title: API 레퍼런스 -description: Sume Public API의 라우트 맵과 스키마 링크입니다. +description: Sume Public API의 라우트 맵, 요청 메모, 응답 패턴입니다. --- -이 페이지는 Sume 문서 셸 안의 가벼운 라우트 레퍼런스입니다. 정확한 요청과 응답 스키마는 OpenAPI JSON을 사용하세요. +이 페이지는 Sume Public API의 라우트 단위 레퍼런스입니다. 정확한 필드와 +enum은 OpenAPI schema를 source of truth로 사용하세요. ## OpenAPI 스키마 -현재 미리보기의 스키마 스냅샷은 다음에서 확인할 수 있습니다. +미리보기 스키마: ```text /api/openapi.json ``` -프로덕션 Sume은 live schema를 다음 경로에서 제공합니다. +프로덕션 스키마: ```text https://www.sume.so/api/v1/openapi.json ``` -스키마 다운로드: +다운로드: ```bash curl https://www.sume.so/api/v1/openapi.json \ @@ -35,49 +36,154 @@ curl https://www.sume.so/api/v1/me \ -H "Authorization: Bearer $SUME_API_KEY" ``` -요청 본문에 `workspace_id`나 `user_id`를 전달하지 마세요. Sume은 API 키에서 범위를 결정합니다. +기존 키는 legacy `X-Api-Key` 헤더도 지원할 수 있지만, +`Authorization: Bearer`를 권장합니다. Sume은 API 키에서 워크스페이스와 +owner 범위를 결정하므로 요청 본문에 `workspace_id`나 `user_id`를 넣지 +마세요. -## 읽기 엔드포인트 +## Account와 credits -| 엔드포인트 | 목적 | -|---|---| -| `GET /me` | 인증된 사용자, API 키 메타데이터, 워크스페이스 컨텍스트를 읽습니다. | -| `GET /credits` | 크레딧, 플랜, 활성 생성 용량을 읽습니다. | -| `GET /brand` | 정리된 Brand DNA 프로필을 나열합니다. | -| `GET /brand/current` | 현재 워크스페이스 Brand DNA 프로필을 읽습니다. | -| `GET /avatars` | 사용할 수 있는 공개/워크스페이스 아바타를 나열합니다. | -| `GET /jobs` | 워크스페이스 범위 작업을 나열합니다. | -| `GET /jobs/{jobId}` | 한 작업의 상태를 읽습니다. | -| `GET /jobs/{jobId}/result` | 한 작업의 결과를 읽습니다. | -| `GET /assets` | 색인된 Asset Library 장면 에셋을 나열하거나 검색합니다. | -| `GET /assets/{assetId}` | 한 장면 에셋을 읽습니다. | +| Method | Path | 반환 | 메모 | +|---|---|---|---| +| `GET` | `/me` | `account` | 인증된 사용자, 워크스페이스, API 키 메타데이터. | +| `GET` | `/credits` | `credits` | 플랜, 월간/보너스 크레딧, 남은 크레딧, 활성 생성 용량. | -## 생성 엔드포인트 +## Brand DNA -생성 엔드포인트는 크레딧을 사용할 수 있습니다. 에이전트는 사용자가 명확히 생성 작업을 승인하지 않았다면 호출 전에 확인해야 합니다. +| Method | Path | 반환 | 메모 | +|---|---|---|---| +| `GET` | `/brand` | `brand` 목록 | 워크스페이스에서 볼 수 있는 정리된 Brand DNA 프로필. | +| `GET` | `/brand/current` | `brand` | 서버가 선택한 현재 워크스페이스 Brand DNA 프로필. | -| 엔드포인트 | 목적 | -|---|---| -| `POST /images/generations` | 비동기 이미지 생성 작업을 만듭니다. | -| `POST /videos/generations` | 비동기 비디오 생성 작업을 만듭니다. | -| `POST /ads/videos` | AI Ads 비디오 작업을 만듭니다. | -| `POST /face-swap` | 하나 이상의 Face Swap 작업을 만듭니다. | -| `POST /reference-analysis` | 공개 TikTok 또는 Instagram Reel URL 분석 작업을 만듭니다. | -| `POST /uploads/presign` | 미디어 업로드용 임시 URL을 만듭니다. | -| `POST /assets` | 업로드된 에셋을 finalize하고 Asset Library ingest를 enqueue합니다. | +Brand 응답의 `images[].reference_url`은 이미지 생성의 +`reference_image_urls`로 사용할 수 있습니다. + +## Avatars -## 예시 +| Method | Path | 반환 | 메모 | +|---|---|---|---| +| `GET` | `/avatars` | `avatar` 목록 | API 키로 사용할 수 있는 공개/워크스페이스 아바타. | +| `GET` | `/avatars/{avatarId}` | `avatar` | 하나의 아바타와 media/capability 메타데이터. | -크레딧 확인: +`capabilities`는 talking-head video, UGC ad video, Face Swap 사용 가능 여부를 +나타냅니다. + +## Jobs + +| Method | Path | 반환 | 메모 | +|---|---|---|---| +| `GET` | `/jobs` | `job` 목록 | `limit`, `cursor`, `type`, `status`를 지원합니다. | +| `GET` | `/jobs/{jobId}` | `job` | 현재 상태와 정리된 error/result URL 필드. | +| `GET` | `/jobs/{jobId}/result` | `job` with `result` | 완료된 작업의 최종 결과. | ```bash -curl https://www.sume.so/api/v1/credits \ +curl "https://www.sume.so/api/v1/jobs?limit=5&status=completed" \ -H "Authorization: Bearer $SUME_API_KEY" ``` -Asset Library 장면 검색: +Job 객체는 공개 상태와 output 필드만 노출합니다. 내부 provider payload는 +public contract가 아닙니다. + +## 생성 엔드포인트 + +생성 엔드포인트는 크레딧을 예약하거나 사용할 수 있습니다. + +| Method | Path | 반환 | 주요 입력 | +|---|---|---|---| +| `POST` | `/images/generations` | `image_generation` | `prompt`, `aspect_ratio`, `image_count`, `reference_image_urls` | +| `POST` | `/videos/generations` | `video_generation` | `prompt`, `duration`, `aspect_ratio`, `resolution`, `generate_audio` | +| `POST` | `/ads/videos` | `ad_video_generation` | `script`, `ad_format`, `avatar_id` 또는 `avatar_slug` | +| `POST` | `/face-swap` | `face_swap` | `source_video_url`, `avatar_ids`, `duration_seconds` | +| `POST` | `/reference-analysis` | `reference_analysis` | public TikTok 또는 Instagram Reel `url`, `locale` | + +예시: ```bash -curl "https://www.sume.so/api/v1/assets?q=product%20demo&limit=5" \ - -H "Authorization: Bearer $SUME_API_KEY" +curl https://www.sume.so/api/v1/videos/generations \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "Four-second product demo video on a studio table.", + "duration": 4, + "aspect_ratio": "9:16", + "resolution": "480p", + "generate_audio": false + }' ``` + +## Uploads와 Asset Library + +| Method | Path | 반환 | 메모 | +|---|---|---|---| +| `POST` | `/uploads/presign` | `upload` | 임시 signed upload URL을 만듭니다. | +| `POST` | `/assets` | `asset_upload` | 업로드된 영상을 finalize하고 Asset Library processing을 시작합니다. | +| `GET` | `/assets` | `asset` 목록 | 색인된 scene asset을 나열하거나 검색합니다. | +| `GET` | `/assets/{assetId}` | `asset` | 하나의 scene asset을 읽습니다. | + +업로드 purpose: + +| Purpose | 용도 | +|---|---| +| `asset_library_video` | Asset Library scene search에 ingest할 영상. | +| `face_swap_source_video` | Face Swap source video. | + +```bash +curl https://www.sume.so/api/v1/uploads/presign \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "purpose": "asset_library_video", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +업로드 응답의 `upload_url`, `object_key`, `media_url`, `required_headers`는 +민감한 operational 값입니다. Storage upload URL에는 Sume API +`Authorization` 헤더를 보내지 마세요. + +## List response + +```json +{ + "object": "list", + "data": [], + "has_more": false, + "next_cursor": null +} +``` + +`limit`로 페이지 크기를 조정하고, `next_cursor`를 `cursor`로 전달해 다음 +페이지를 가져옵니다. + +## Error response + +```json +{ + "error": { + "code": "invalid_request", + "message": "A human-readable error message.", + "details": {} + }, + "request_id": "req_123" +} +``` + +대표 상태 코드: + +| Status | 의미 | +|---|---| +| `400` | 잘못된 요청 본문, 지원하지 않는 입력, validation error. | +| `401` | API 키 누락 또는 invalid key. | +| `402` | 크레딧 부족. | +| `403` | API 키가 요청 리소스나 액션에 접근할 수 없음. | +| `404` | 현재 워크스페이스 범위에서 리소스를 찾을 수 없음. | +| `409` | conflict, duplicate, incompatible state. | +| `413` | 업로드 또는 요청 미디어가 너무 큼. | +| `429` | rate limit 또는 active generation limit. | +| `500`, `502`, `503` | internal, upstream, provider availability failure. | + +문제 제보 시에는 `request_id`와 정리된 endpoint/job id를 포함하세요. API 키, +signed URL, object key, private media URL, provider payload, 사용자 이메일, +workspace/user id는 포함하지 마세요. diff --git a/content/docs-ko/public-api.md b/content/docs-ko/public-api.md index fe5d7e4..fb1c615 100644 --- a/content/docs-ko/public-api.md +++ b/content/docs-ko/public-api.md @@ -3,29 +3,84 @@ title: 개요 description: Sume 생성, 작업, 크레딧, Brand context, 아바타, 업로드, Asset Library 장면에 접근합니다. --- -Sume Public API는 워크스페이스 범위의 Sume 앱 기능을 얇게 노출하는 프로그래밍 인터페이스입니다. 서버 연동, CLI 자동화, MCP 래퍼, 에이전트 도구를 위해 설계되었습니다. +Sume Public API는 서버 연동, CLI 자동화, MCP 래퍼, 에이전트 도구를 위한 +워크스페이스 범위 API입니다. Sume 앱의 핵심 기능인 생성 작업, 작업 +폴링, Brand DNA, 아바타, 업로드, Asset Library 장면 검색을 제공합니다. -## 엔드포인트 그룹 +## Base URL -| 그룹 | 엔드포인트 | 용도 | +```text +https://www.sume.so/api/v1 +``` + +이 페이지의 모든 엔드포인트 경로는 위 base URL 기준입니다. + +## 인증 + +서버 환경에서 워크스페이스 API 키를 전달하세요. + +```bash +export SUME_API_KEY="sume_live_..." + +curl https://www.sume.so/api/v1/me \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +Bearer 인증을 권장합니다. 기존 Dashboard 발급 키는 legacy `X-Api-Key` +헤더도 지원할 수 있지만, 새 연동은 `Authorization: Bearer`를 사용하세요. + +요청 본문에 `workspace_id`나 `user_id`를 넣지 마세요. Sume은 API 키에서 +사용자와 워크스페이스 범위를 결정합니다. + +> API 키, signed upload URL, storage object key, private media URL은 모두 +> 민감 정보로 취급하세요. 프롬프트, 로그, 이슈, 공개 지원 채널에 붙여넣지 +> 마세요. + +## 빠른 시작 + +1. API dashboard에서 Sume API 키를 만들거나 복사합니다. +2. `GET /me`로 키가 동작하는지 확인합니다. +3. `GET /credits`로 크레딧 용량을 확인합니다. +4. `POST /videos/generations` 같은 엔드포인트로 비동기 작업을 만듭니다. +5. 종료 상태가 될 때까지 `GET /jobs/{jobId}`를 폴링합니다. +6. `GET /jobs/{jobId}/result`로 생성 미디어나 분석 결과를 가져옵니다. + +```bash +curl https://www.sume.so/api/v1/credits \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +## 엔드포인트 맵 + +| 영역 | 엔드포인트 | 용도 | |---|---|---| | Account | `GET /me`, `GET /credits` | 인증, 워크스페이스 범위, 플랜, 크레딧, 활성 생성 용량을 확인합니다. | -| Brand | `GET /brand`, `GET /brand/current` | 워크스페이스에서 사용할 수 있는 정리된 Brand DNA 프로필을 읽습니다. | -| Avatars | `GET /avatars`, `GET /avatars/{avatarId}` | 광고와 Face Swap 워크플로에 사용할 아바타를 선택합니다. | -| Jobs | `GET /jobs`, `GET /jobs/{jobId}`, `GET /jobs/{jobId}/result` | 작업을 나열하고, 상태를 폴링하고, 결과를 가져옵니다. | +| Brand | `GET /brand`, `GET /brand/current` | 정리된 Brand DNA 프로필과 현재 Brand context를 읽습니다. | +| Avatars | `GET /avatars`, `GET /avatars/{avatarId}` | 광고와 Face Swap 워크플로에 사용할 공개/워크스페이스 아바타를 선택합니다. | +| Jobs | `GET /jobs`, `GET /jobs/{jobId}`, `GET /jobs/{jobId}/result` | 작업을 나열하고, 상태를 폴링하고, 생성/분석 결과를 가져옵니다. | | Generation | `POST /images/generations`, `POST /videos/generations`, `POST /ads/videos`, `POST /face-swap`, `POST /reference-analysis` | 비동기 미디어 또는 분석 작업을 만듭니다. 크레딧을 사용할 수 있습니다. | | Uploads | `POST /uploads/presign`, `POST /assets` | 영상을 업로드하고 Asset Library ingest 또는 기능별 워크플로로 finalize합니다. | | Asset Library | `GET /assets`, `GET /assets/{assetId}` | 색인된 장면 에셋을 검색하고 재사용 가능한 클립/소스 메타데이터를 조회합니다. | -## 비동기 워크플로 +## 비동기 작업 생명주기 + +대부분의 쓰기 엔드포인트는 빠르게 `job_id`를 반환합니다. 해당 id를 저장한 +뒤 작업이 종료 상태가 될 때까지 폴링하세요. + +```text +create endpoint + -> job_id + -> GET /jobs/{jobId} + -> GET /jobs/{jobId}/result +``` -대부분의 쓰기 엔드포인트는 작업을 만듭니다. +| 상태 | 연동 동작 | +|---|---| +| `queued`, `processing` 또는 기타 진행 상태 | backoff를 두고 계속 폴링합니다. 비디오 작업은 이미지 작업보다 오래 걸립니다. | +| `completed` | 결과를 가져오고 output URL 또는 구조화된 결과 데이터를 사용합니다. | +| `failed`, `canceled`, `expired` | 폴링을 중단하고 정리된 오류 메시지를 표시합니다. | -1. `/me`와 `/credits`로 계정과 크레딧을 확인합니다. -2. `POST /videos/generations` 같은 엔드포인트로 작업을 만듭니다. -3. 작업이 종료 상태에 도달할 때까지 `GET /jobs/{jobId}`를 폴링합니다. -4. `GET /jobs/{jobId}/result`로 결과를 가져옵니다. -5. 반환된 공개 미디어 URL이나 메타데이터를 다음 단계에서 사용합니다. +예시 비디오 작업: ```bash curl https://www.sume.so/api/v1/videos/generations \ @@ -41,30 +96,28 @@ curl https://www.sume.so/api/v1/videos/generations \ ## 업로드 워크플로 -엔드포인트가 사용자 제공 미디어를 필요로 할 때 업로드를 사용합니다. +사용자 제공 비디오가 필요할 때 업로드를 사용합니다. + +1. `POST /uploads/presign`으로 임시 업로드 대상을 요청합니다. +2. 반환된 `upload_url`에 `required_headers`를 사용해 바이트를 업로드합니다. +3. Asset Library ingest는 `POST /assets`로 finalize합니다. +4. Face Swap은 반환된 `media_url`을 `POST /face-swap`에 전달합니다. ```bash curl https://www.sume.so/api/v1/uploads/presign \ -H "Authorization: Bearer $SUME_API_KEY" \ -H "Content-Type: application/json" \ -d '{ + "purpose": "asset_library_video", "file_name": "reference.mp4", "content_type": "video/mp4", "size_bytes": 12000000 }' ``` -반환된 `upload_url`로 바이트를 업로드할 때는 함께 반환된 `required_headers`를 사용합니다. Asset Library ingest는 다음 요청으로 finalize합니다. - -```bash -curl https://www.sume.so/api/v1/assets \ - -H "Authorization: Bearer $SUME_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "object_key": "uploads/...", - "file_name": "reference.mp4" - }' -``` +`purpose`는 `asset_library_video` 또는 `face_swap_source_video`입니다. +`upload_url`, `object_key`, `required_headers`는 업로드 플로우용 민감한 +값이므로 로그에 남기지 마세요. ## 페이지네이션 @@ -79,7 +132,7 @@ curl https://www.sume.so/api/v1/assets \ } ``` -계속 조회하려면 `next_cursor`를 `cursor`로 다시 전달합니다. +계속 조회하려면 `next_cursor`를 `cursor`로 전달합니다. ## 오류 envelope @@ -90,8 +143,19 @@ curl https://www.sume.so/api/v1/assets \ "message": "A human-readable error message.", "details": {} }, - "request_id": "req_..." + "request_id": "req_123" } ``` -정확한 요청/응답 스키마는 [`/api/openapi.json`](/api/openapi.json)을 참고하세요. +지원 문의에는 `request_id`를 보관하세요. API 키, signed URL, storage +object key, private media URL, 사용자 이메일, workspace/user id는 외부 로그에서 +제거하세요. + +## 스키마와 예시 + +- [API 레퍼런스](/ko/api/reference)는 현재 엔드포인트를 나열합니다. +- [API cookbook](/ko/api/cookbook)은 복사해 쓸 수 있는 워크플로 예시를 제공합니다. +- 미리보기 OpenAPI 스냅샷은 [`/api/openapi.json`](/api/openapi.json)에 있습니다. +- 프로덕션 live schema는 `https://www.sume.so/api/v1/openapi.json`에서 제공합니다. + +정확한 요청/응답 필드는 OpenAPI schema를 source of truth로 사용하세요. diff --git a/content/docs/api/cookbook.md b/content/docs/api/cookbook.md new file mode 100644 index 0000000..dd3e7c7 --- /dev/null +++ b/content/docs/api/cookbook.md @@ -0,0 +1,216 @@ +--- +title: API cookbook +description: Copy-paste Sume Public API workflows for auth, jobs, generation, uploads, Asset Library, and Reference Analysis. +--- + +This cookbook gives short, composable examples for common Sume API workflows. +For exact fields and enums, use the [API reference](/api/reference) and +[`/api/openapi.json`](/api/openapi.json). + +## Setup + +```bash +export SUME_API_KEY="sume_live_..." +export SUME_API_BASE_URL="https://www.sume.so/api/v1" +``` + +Check that the key works: + +```bash +curl "$SUME_API_BASE_URL/me" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +Check available credits before starting paid work: + +```bash +curl "$SUME_API_BASE_URL/credits" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +## Create and poll a video job + +Create the job: + +```bash +curl "$SUME_API_BASE_URL/videos/generations" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "A creator holds a moisturizer jar in soft morning light.", + "duration": 4, + "aspect_ratio": "9:16", + "resolution": "480p", + "generate_audio": false + }' +``` + +The response includes `job_id`. + +Poll status: + +```bash +curl "$SUME_API_BASE_URL/jobs/job_123" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +Fetch the result: + +```bash +curl "$SUME_API_BASE_URL/jobs/job_123/result" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +## Create an image from Brand references + +Read the current Brand DNA profile: + +```bash +curl "$SUME_API_BASE_URL/brand/current" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +If the response includes `images[].reference_url`, pass selected references to +image generation: + +```bash +curl "$SUME_API_BASE_URL/images/generations" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "Premium skincare product ad using the brand reference.", + "aspect_ratio": "1:1", + "image_count": 1, + "reference_image_urls": [ + "https://media.sume.so/example-reference.jpg" + ] + }' +``` + +Only use reference URLs that Sume returned to your workspace. Do not paste +private or signed URLs into logs. + +## Upload a video to Asset Library + +Request an upload target: + +```bash +curl "$SUME_API_BASE_URL/uploads/presign" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "purpose": "asset_library_video", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +Upload the file bytes to the returned `upload_url` using the returned +`required_headers`. Do not include the Sume API `Authorization` header in the +storage PUT request. + +Finalize the uploaded asset: + +```bash +curl "$SUME_API_BASE_URL/assets" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "object_key": "uploads/...", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +The asset upload enters processing. Use Asset Library search after ingest +completes. + +## Search Asset Library scenes + +```bash +curl "$SUME_API_BASE_URL/assets?q=product%20demo%20hook&limit=5&sort=relevance" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +Fetch one scene: + +```bash +curl "$SUME_API_BASE_URL/assets/asset_123" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +Scene assets may include a scene-level `media_url`, `thumbnail_url`, +`source_video`, `scene` metadata, and search context. Prefer scene-level media +when present; fall back to source video plus timecodes only when your workflow +supports trimming. + +## Prepare a Face Swap source video + +Face Swap requires an uploaded Sume media URL with purpose +`face_swap_source_video`. + +```bash +curl "$SUME_API_BASE_URL/uploads/presign" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "purpose": "face_swap_source_video", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +After uploading bytes to the returned upload URL, create Face Swap jobs: + +```bash +curl "$SUME_API_BASE_URL/face-swap" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "source_video_url": "https://media.sume.so/example-source.mp4", + "avatar_ids": ["avatar_123"], + "duration_seconds": 6, + "aspect_ratio": "9:16" + }' +``` + +Poll each returned job id with `GET /jobs/{jobId}`. + +## Analyze a public reference + +Reference Analysis accepts public TikTok or Instagram Reel URLs. + +```bash +curl "$SUME_API_BASE_URL/reference-analysis" \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "url": "https://www.tiktok.com/@example/video/123", + "locale": "en" + }' +``` + +The response includes `required_credits` and `job_id`. Poll the job and fetch +the final result through the jobs endpoints. + +## Handle failures safely + +For failed API requests, preserve the request id: + +```json +{ + "error": { + "code": "invalid_request", + "message": "A human-readable error message.", + "details": {} + }, + "request_id": "req_123" +} +``` + +For failed jobs, preserve the job id, status, and sanitized error code/message. +Do not log API keys, signed URLs, storage object keys, raw provider payloads, +private media URLs, user emails, or workspace/user ids. diff --git a/content/docs/api/reference.md b/content/docs/api/reference.md index de14886..875ac35 100644 --- a/content/docs/api/reference.md +++ b/content/docs/api/reference.md @@ -1,25 +1,27 @@ --- title: API reference -description: Route map and schema links for the Sume Public API. +description: Route map, request notes, and response patterns for the Sume Public API. --- -This page is a lightweight route reference inside the Sume docs shell. For exact request and response schemas, use the OpenAPI JSON directly. +This page is a route-level reference for the Sume Public API. It is designed to +be readable in the docs shell while keeping the OpenAPI schema as the exact +source of truth. ## OpenAPI schema -The current schema snapshot for this preview is available here: +Preview schema: ```text /api/openapi.json ``` -Production Sume serves the live schema here: +Production schema: ```text https://www.sume.so/api/v1/openapi.json ``` -Download the schema: +Download it: ```bash curl https://www.sume.so/api/v1/openapi.json \ @@ -35,55 +37,85 @@ curl https://www.sume.so/api/v1/me \ -H "Authorization: Bearer $SUME_API_KEY" ``` -Do not pass `workspace_id` or `user_id` in request bodies. Sume derives scope from the API key. +The legacy `X-Api-Key` header is accepted for existing keys, but +`Authorization: Bearer` is preferred. Sume resolves workspace and owner scope +from the key, so request bodies should not include `workspace_id` or `user_id`. -## Read endpoints +## Account and credits -| Endpoint | Purpose | -|---|---| -| `GET /me` | Read the authenticated user, API key metadata, and workspace context. | -| `GET /credits` | Read credit, plan, and active generation capacity. | -| `GET /brand` | List sanitized Brand DNA profiles. | -| `GET /brand/current` | Read the current workspace Brand DNA profile. | -| `GET /avatars` | List usable public and workspace avatars. | -| `GET /avatars/{avatarId}` | Read one avatar. | -| `GET /jobs` | List workspace-scoped jobs. | -| `GET /jobs/{jobId}` | Read one job status. | -| `GET /jobs/{jobId}/result` | Read one job result. | -| `GET /assets` | List or search indexed Asset Library scene assets. | -| `GET /assets/{assetId}` | Read one Asset Library scene asset. | - -## Create endpoints - -Generation endpoints may spend credits. Agents should ask for explicit confirmation before calling them unless the user has clearly authorized generation. - -| Endpoint | Purpose | -|---|---| -| `POST /images/generations` | Create an async image generation job. | -| `POST /videos/generations` | Create an async video generation job. | -| `POST /ads/videos` | Create an async AI Ads video job. | -| `POST /face-swap` | Create one or more Face Swap jobs. | -| `POST /reference-analysis` | Create a Reference Analysis job for a public TikTok or Instagram Reel URL. | -| `POST /uploads/presign` | Create a temporary upload URL for media bytes. | -| `POST /assets` | Finalize an uploaded asset and enqueue Asset Library ingest. | +| Method | Path | Returns | Notes | +|---|---|---|---| +| `GET` | `/me` | `account` | Authenticated user, workspace, and API key metadata. | +| `GET` | `/credits` | `credits` | Plan, monthly and bonus credits, remaining credits, and active generation capacity. | + +```bash +curl https://www.sume.so/api/v1/me \ + -H "Authorization: Bearer $SUME_API_KEY" -## Endpoint examples +curl https://www.sume.so/api/v1/credits \ + -H "Authorization: Bearer $SUME_API_KEY" +``` -Check credits: +## Brand DNA + +| Method | Path | Returns | Notes | +|---|---|---|---| +| `GET` | `/brand` | `brand` list | Lists sanitized Brand DNA profiles visible to the workspace. | +| `GET` | `/brand/current` | `brand` | Returns the current server-selected workspace Brand DNA profile. | + +Brand responses can include `images[].reference_url` values. Use those URLs as +`reference_image_urls` for image generation when present. ```bash -curl https://www.sume.so/api/v1/credits \ +curl https://www.sume.so/api/v1/brand/current \ -H "Authorization: Bearer $SUME_API_KEY" ``` -Search Asset Library scenes: +## Avatars + +| Method | Path | Returns | Notes | +|---|---|---|---| +| `GET` | `/avatars` | `avatar` list | Public and workspace avatars usable by the key. | +| `GET` | `/avatars/{avatarId}` | `avatar` | One avatar with media and capability metadata. | + +Avatar `capabilities` indicate whether the avatar can be used for talking-head +video, UGC ad video, or Face Swap workflows. + +## Jobs + +| Method | Path | Returns | Notes | +|---|---|---|---| +| `GET` | `/jobs` | `job` list | Supports `limit`, `cursor`, `type`, and `status`. | +| `GET` | `/jobs/{jobId}` | `job` | Current status and sanitized error/result URL fields. | +| `GET` | `/jobs/{jobId}/result` | `job` with `result` | Final output payload for completed jobs when available. | ```bash -curl "https://www.sume.so/api/v1/assets?q=product%20demo%20hook&limit=5&sort=relevance" \ +curl "https://www.sume.so/api/v1/jobs?limit=5&status=completed" \ + -H "Authorization: Bearer $SUME_API_KEY" + +curl https://www.sume.so/api/v1/jobs/job_123/result \ -H "Authorization: Bearer $SUME_API_KEY" ``` -Create an image job: +Job objects expose public status and output fields only. Internal provider +payloads are not part of the public contract. + +## Image generation + +| Method | Path | Returns | Credits | +|---|---|---|---| +| `POST` | `/images/generations` | `image_generation` | May reserve or spend credits. | + +Common request fields include: + +| Field | Type | Notes | +|---|---|---| +| `prompt` | string | Main image instruction. | +| `aspect_ratio` | string | Output aspect ratio. | +| `resolution` | string | Output size preference when supported. | +| `quality` | string | Quality preference when supported. | +| `image_count` or `n` | integer | Minimum `1`; current CLI guidance recommends one reliable output per job. | +| `reference_image_urls` | string array | HTTPS image references, including Brand `reference_url` values when available. | ```bash curl https://www.sume.so/api/v1/images/generations \ @@ -96,19 +128,168 @@ curl https://www.sume.so/api/v1/images/generations \ }' ``` -Poll and fetch result: +## Video generation + +| Method | Path | Returns | Credits | +|---|---|---|---| +| `POST` | `/videos/generations` | `video_generation` | May reserve or spend credits. | + +Common request fields include: + +| Field | Type | Notes | +|---|---|---| +| `prompt` | string | Main video instruction. | +| `aspect_ratio` | string | For example `9:16`. | +| `duration` | number | Requested duration in seconds. | +| `generate_audio` | boolean | Whether to request audio when supported. | +| `resolution` | string | Output resolution preference. | ```bash -curl https://www.sume.so/api/v1/jobs/job_123 \ - -H "Authorization: Bearer $SUME_API_KEY" +curl https://www.sume.so/api/v1/videos/generations \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "prompt": "Four-second product demo video on a studio table.", + "duration": 4, + "aspect_ratio": "9:16", + "resolution": "480p", + "generate_audio": false + }' +``` -curl https://www.sume.so/api/v1/jobs/job_123/result \ +## AI Ads video + +| Method | Path | Returns | Credits | +|---|---|---|---| +| `POST` | `/ads/videos` | `ad_video_generation` | Reserves credits before accepting the job. | + +Required field: + +| Field | Type | Notes | +|---|---|---| +| `script` | string | Required, 3 to 1800 characters. | + +Selected optional fields: + +| Field | Type | Notes | +|---|---|---| +| `ad_format` | enum | `talking_heads`, `ugc_ads`, or `video`; defaults to `talking_heads`. | +| `avatar_id` or `avatar_slug` | string | Required for avatar-based ad formats. | +| `locale` | enum | `en` or `ko`. | +| `duration_seconds` | number | Sume may clamp to supported durations by ad format. | +| `reference_image_urls` | string array | Up to 9 HTTPS image references. | +| `reference_video_urls` | string array | Only supported for `ad_format: "video"`. | + +## Face Swap + +| Method | Path | Returns | Credits | +|---|---|---|---| +| `POST` | `/face-swap` | `face_swap` | Reserves credits per avatar/job. | + +Face Swap requires a Sume media URL created with upload purpose +`face_swap_source_video`. + +| Field | Type | Notes | +|---|---|---| +| `source_video_url` | URI | Sume media URL returned by the upload flow. | +| `avatar_ids` | string array | 1 to 5 avatar ids. | +| `duration_seconds` | number | Maximum 15 seconds. | +| `trim_start_seconds` | number | Optional trim start. | +| `trim_end_seconds` | number or null | Optional trim end. | +| `aspect_ratio` | enum | `16:9`, `9:16`, `1:1`, `4:3`, `3:4`, or `21:9`. | + +## Reference Analysis + +| Method | Path | Returns | Credits | +|---|---|---|---| +| `POST` | `/reference-analysis` | `reference_analysis` | Requires credits and creates an async analysis job. | + +```bash +curl https://www.sume.so/api/v1/reference-analysis \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "url": "https://www.instagram.com/reel/...", + "locale": "en" + }' +``` + +Supported input is a public TikTok or Instagram Reel URL. Poll the returned job +id, then fetch the result from `/jobs/{jobId}/result`. + +## Uploads and Asset Library + +| Method | Path | Returns | Notes | +|---|---|---|---| +| `POST` | `/uploads/presign` | `upload` | Creates a temporary signed upload URL. | +| `POST` | `/assets` | `asset_upload` | Finalizes an uploaded video and starts Asset Library processing. | +| `GET` | `/assets` | `asset` list | Lists or searches indexed scene assets. | +| `GET` | `/assets/{assetId}` | `asset` | Reads one scene asset. | + +Upload purposes: + +| Purpose | Use for | +|---|---| +| `asset_library_video` | Videos that should be ingested into Asset Library scene search. | +| `face_swap_source_video` | Source videos used by Face Swap. | + +```bash +curl https://www.sume.so/api/v1/uploads/presign \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "purpose": "asset_library_video", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +The upload response includes a temporary `upload_url`, an `object_key`, +`media_url`, and `required_headers`. Treat them as sensitive operational +values. Do not send the Sume API `Authorization` header to the storage upload +URL. + +Finalize Asset Library upload: + +```bash +curl https://www.sume.so/api/v1/assets \ + -H "Authorization: Bearer $SUME_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "object_key": "uploads/...", + "file_name": "source.mp4", + "content_type": "video/mp4", + "size_bytes": 12000000 + }' +``` + +Search indexed scenes: + +```bash +curl "https://www.sume.so/api/v1/assets?q=product%20demo%20hook&limit=5&sort=relevance" \ -H "Authorization: Bearer $SUME_API_KEY" ``` -## Errors +Asset results include a scene-level `media_url` when available, optional +thumbnail/source video fields, source type, search score, and scene metadata. -Error responses use a consistent envelope: +## List response + +List endpoints use this envelope: + +```json +{ + "object": "list", + "data": [], + "has_more": false, + "next_cursor": null +} +``` + +Use `limit` to control page size and `cursor` to continue from `next_cursor`. + +## Error response ```json { @@ -117,8 +298,24 @@ Error responses use a consistent envelope: "message": "A human-readable error message.", "details": {} }, - "request_id": "req_..." + "request_id": "req_123" } ``` -Keep `request_id` for support, but avoid posting raw private payloads, signed URLs, API keys, user emails, workspace ids, or full media URLs in public logs. +Common status codes include: + +| Status | Meaning | +|---|---| +| `400` | Invalid request body, unsupported input, or validation error. | +| `401` | Missing or invalid API key. | +| `402` | Insufficient credits. | +| `403` | API key lacks access to the requested resource or action. | +| `404` | Resource not found in the current workspace scope. | +| `409` | Conflict, duplicate, or incompatible state. | +| `413` | Uploaded/requested media is too large. | +| `429` | Rate limit or active generation limit. | +| `500`, `502`, `503` | Internal, upstream, or provider availability failure. | + +When reporting an issue to Sume, include `request_id` and the sanitized endpoint +or job id. Do not include API keys, signed URLs, object keys, private media +URLs, full provider payloads, user emails, or workspace/user ids. diff --git a/content/docs/public-api.md b/content/docs/public-api.md index 638ebf8..1b56e14 100644 --- a/content/docs/public-api.md +++ b/content/docs/public-api.md @@ -3,29 +3,86 @@ title: Overview description: Programmatic access to Sume generation, jobs, credits, brand context, avatars, uploads, and Asset Library scenes. --- -The Sume Public API is a thin programmatic surface over workspace-scoped Sume app capabilities. It is designed for server integrations, CLI automation, MCP wrappers, and agent tools. +The Sume Public API is a workspace-scoped interface for server integrations, +CLI automation, MCP wrappers, and agent tools. It exposes the same core +capabilities used by the Sume app: generation jobs, job polling, Brand DNA, +avatars, uploads, and Asset Library scene search. -## Endpoint groups +## Base URL -| Group | Endpoints | Use for | +```text +https://www.sume.so/api/v1 +``` + +All endpoint paths on this page are relative to that base URL. + +## Authentication + +Send a workspace API key from a server-side environment: + +```bash +export SUME_API_KEY="sume_live_..." + +curl https://www.sume.so/api/v1/me \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +Bearer auth is preferred. Existing dashboard-issued keys may also support the +legacy `X-Api-Key` header, but new integrations should use +`Authorization: Bearer`. + +Do not pass `workspace_id` or `user_id` in request bodies. Sume derives user +and workspace scope from the API key. + +> Treat API keys, signed upload URLs, storage object keys, and private media +> URLs as secrets. Do not paste them into prompts, logs, support tickets, or +> public issue trackers. + +## Quickstart + +1. Create or copy a Sume API key from the API dashboard. +2. Verify the key with `GET /me`. +3. Check credit capacity with `GET /credits`. +4. Create an async job, such as `POST /videos/generations`. +5. Poll `GET /jobs/{jobId}` until it reaches a terminal state. +6. Fetch `GET /jobs/{jobId}/result` for generated media or analysis output. + +```bash +curl https://www.sume.so/api/v1/credits \ + -H "Authorization: Bearer $SUME_API_KEY" +``` + +## Endpoint map + +| Area | Endpoints | Use for | |---|---|---| | Account | `GET /me`, `GET /credits` | Verify auth, workspace scope, plan, credits, and active generation capacity. | -| Brand | `GET /brand`, `GET /brand/current` | Read sanitized Brand DNA profiles available to the workspace. | -| Avatars | `GET /avatars`, `GET /avatars/{avatarId}` | Pick public or workspace-owned avatars for ads and Face Swap workflows. | +| Brand | `GET /brand`, `GET /brand/current` | Read sanitized Brand DNA profiles and current brand context. | +| Avatars | `GET /avatars`, `GET /avatars/{avatarId}` | Pick public or workspace avatars for ads and Face Swap workflows. | | Jobs | `GET /jobs`, `GET /jobs/{jobId}`, `GET /jobs/{jobId}/result` | List jobs, poll status, and retrieve generated or analyzed outputs. | | Generation | `POST /images/generations`, `POST /videos/generations`, `POST /ads/videos`, `POST /face-swap`, `POST /reference-analysis` | Create asynchronous media or analysis jobs. These endpoints may spend credits. | | Uploads | `POST /uploads/presign`, `POST /assets` | Upload videos and finalize them for Asset Library ingest or feature-specific workflows. | | Asset Library | `GET /assets`, `GET /assets/{assetId}` | Search indexed scene assets and retrieve reusable clip/source metadata. | -## Async workflow +## Async job lifecycle + +Most write endpoints return quickly with a job id. Store that id and poll until +the job reaches a terminal state. + +```text +create endpoint + -> job_id + -> GET /jobs/{jobId} + -> GET /jobs/{jobId}/result +``` -Most write endpoints create a job: +| Status class | Integration behavior | +|---|---| +| `queued`, `processing`, or another non-terminal status | Continue polling with backoff. Video jobs take longer than image jobs. | +| `completed` | Fetch the result and use output URLs or structured result data. | +| `failed`, `canceled`, or `expired` | Stop polling and surface the sanitized error message. | -1. Check account and credits with `/me` and `/credits`. -2. Create a job, such as `POST /videos/generations`. -3. Poll `GET /jobs/{jobId}` until the job reaches a terminal state. -4. Fetch `GET /jobs/{jobId}/result`. -5. Use returned public media URLs or metadata in the next workflow step. +Example video job: ```bash curl https://www.sume.so/api/v1/videos/generations \ @@ -39,38 +96,49 @@ curl https://www.sume.so/api/v1/videos/generations \ }' ``` +Example job response shape: + +```json +{ + "object": "video_generation", + "id": "gen_123", + "job_id": "job_123", + "status": "queued", + "reused": false, + "reserved_credits": 10, + "request_id": "req_123" +} +``` + ## Upload workflow -Use uploads when an endpoint needs user-provided media. +Use uploads when an endpoint needs user-provided video bytes. + +1. Request a temporary upload target with `POST /uploads/presign`. +2. Upload bytes directly to the returned `upload_url` using the returned + `required_headers`. +3. For Asset Library ingestion, finalize with `POST /assets`. +4. For Face Swap, pass the returned `media_url` to `POST /face-swap`. ```bash curl https://www.sume.so/api/v1/uploads/presign \ -H "Authorization: Bearer $SUME_API_KEY" \ -H "Content-Type: application/json" \ -d '{ + "purpose": "asset_library_video", "file_name": "reference.mp4", "content_type": "video/mp4", "size_bytes": 12000000 }' ``` -Then upload bytes to the returned `upload_url` with the returned `required_headers`. For Asset Library ingest, finalize with: - -```bash -curl https://www.sume.so/api/v1/assets \ - -H "Authorization: Bearer $SUME_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "object_key": "uploads/...", - "file_name": "reference.mp4" - }' -``` - -For Face Swap, create the upload URL with the documented purpose, upload the source video, then pass the returned media URL to `POST /face-swap`. +`purpose` is either `asset_library_video` or `face_swap_source_video`. +`upload_url`, `object_key`, and `required_headers` are operational values for +the upload flow and should not be logged. ## Pagination -List endpoints use cursor pagination: +List endpoints use cursor pagination. ```json { @@ -81,10 +149,17 @@ List endpoints use cursor pagination: } ``` -Pass `next_cursor` back as `cursor` to continue. +Pass `next_cursor` back as `cursor` to continue: + +```bash +curl "https://www.sume.so/api/v1/assets?limit=20&cursor=cur_123" \ + -H "Authorization: Bearer $SUME_API_KEY" +``` ## Error envelope +Error responses use a consistent envelope: + ```json { "error": { @@ -92,12 +167,20 @@ Pass `next_cursor` back as `cursor` to continue. "message": "A human-readable error message.", "details": {} }, - "request_id": "req_..." + "request_id": "req_123" } ``` -Common statuses include `400`, `401`, `402`, `403`, `404`, `409`, `413`, `429`, `500`, `502`, and `503`, depending on endpoint and feature state. +Keep `request_id` for support. Redact API keys, signed URLs, storage object +keys, raw private media URLs, user emails, and workspace or user ids from +external logs. + +## Schema and examples -## Source of truth +- [API reference](/api/reference) lists all current endpoints. +- [API cookbook](/api/cookbook) gives copy-paste workflow examples. +- The preview OpenAPI snapshot is available at [`/api/openapi.json`](/api/openapi.json). +- Production Sume serves the live schema from `https://www.sume.so/api/v1/openapi.json`. -This preview embeds the current public OpenAPI schema at [`/api/openapi.json`](/api/openapi.json). Production Sume serves the live schema from `/api/v1/openapi.json`. +For exact request and response fields, treat the OpenAPI schema as the source +of truth. diff --git a/src/data/sidebar-ko.ts b/src/data/sidebar-ko.ts index f5745d7..dfef5f1 100644 --- a/src/data/sidebar-ko.ts +++ b/src/data/sidebar-ko.ts @@ -20,6 +20,7 @@ export const koreanSidebarContent: ISidebarContent = [ content: [ makePage("개요", "/ko/public-api"), makePage("API 레퍼런스", "/ko/api/reference"), + makePage("API cookbook", "/ko/api/cookbook"), makePage("작업과 결과", "/ko/workflows/jobs-and-results"), makePage("Asset Library", "/ko/workflows/asset-library"), makePage("오류와 크레딧", "/ko/workflows/errors-and-credits"), diff --git a/src/data/sidebar.ts b/src/data/sidebar.ts index b1beda6..70efa3c 100644 --- a/src/data/sidebar.ts +++ b/src/data/sidebar.ts @@ -20,6 +20,7 @@ export const sidebarContent: ISidebarContent = [ content: [ makePage("Overview", "/public-api"), makePage("API reference", "/api/reference"), + makePage("API cookbook", "/api/cookbook"), makePage("Jobs and results", "/workflows/jobs-and-results"), makePage("Asset Library", "/workflows/asset-library"), makePage("Errors and credits", "/workflows/errors-and-credits"),