HTTP API Reference¶
This document describes the HTTP API layer that clients interact with. The API sits between external clients (CLI, web previewer) and the internal gRPC CoordinatorService, providing authentication, rate limiting, ownership enforcement, scene normalization, and signed URL generation.
Located in: orchestration/internal/api/
Architecture¶
Middleware Stack¶
Each request passes through the following middleware in order:
- Authentication — Firebase ID token validation
- Rate Limiting — Per-email rate limiting
- Ownership — Job ownership verification
- Scene Normalization — Layer file upload and path resolution
- Signed URL Generation — GCS signed URLs for direct upload
Endpoints¶
POST /v1/jobs/init¶
Initialize a new job and upload scene files.
Request (multipart/form-data):
| Field | Type | Description |
|---|---|---|
scene.json |
file |
Scene manifest file [Required] |
files[] |
file[] |
Additional layer/asset files [Required] |
frames |
int |
Number of frames to render (default: 1) |
samples |
int |
Override max samples per pixel |
width |
int |
Override image width |
height |
int |
Override image height |
deep |
bool |
Enable deep EXR output |
Limits:
- Maximum 2048 files per request
- Paths must be ≤ 512 characters
- Paths cannot contain ..
Response:
{
"job_id": "skw-abc123",
"upload_urls": {
"data/00_scene.json": "https://storage.googleapis.com/...",
"data/01_layer_mercury.json": "https://storage.googleapis.com/..."
}
}
POST /v1/jobs/{id}/submit¶
Submit an initialized job for rendering.
Request:
{
"scene_path": "data/00_scene.json",
"frames": 1,
"overrides": {
"samples": 256,
"width": 1920,
"height": 1080,
"enable_deep": true
}
}
Rate Limit: 5 requests per hour per email.
Response:
{
"job_id": "skw-abc123",
"status": "JOB_STATUS_RUNNING",
"progress": 0.0,
"created_at": "2025-02-20T12:00:00Z",
"updated_at": "2025-02-20T12:00:05Z"
}
GET /v1/jobs/{id}¶
Get the current status of a job.
Response:
{
"job_id": "skw-abc123",
"status": "JOB_STATUS_RUNNING",
"progress": 45.2,
"layers": [
{"name": "mercury", "status": "completed"},
{"name": "venus", "status": "rendering", "progress": 62.0},
{"name": "earth", "status": "pending"}
],
"created_at": "2025-02-20T12:00:00Z",
"updated_at": "2025-02-20T12:05:00Z"
}
GET /v1/jobs¶
List all jobs for the authenticated user.
Response:
{
"jobs": [
{
"job_id": "skw-abc123",
"status": "JOB_STATUS_RUNNING",
"progress": 45.2,
"created_at": "2025-02-20T12:00:00Z"
}
]
}
POST /v1/jobs/{id}/cancel¶
Cancel a running job.
Response:
Authentication¶
All endpoints require a Firebase ID token in the Authorization header:
The API verifies the token with Firebase Admin SDK and extracts the user's email for rate limiting and ownership.
Authorization¶
- Ownership: Jobs are owned by the email extracted from the Firebase token. Only the owner can view or cancel their job. This is enforced via a
_owner.txtfile stored alongside the job's data. - Admin Access: Emails listed in the
admin_emailsTerraform variable can view and cancel any job.
Configuration¶
The following Terraform variables control the API:
| Variable | Default | Description |
|---|---|---|
admin_emails |
[] |
Emails with admin access to all jobs |
previewer_authorized_domains |
[] |
Allowed domains for the previewer |
api_rate_init_per_hour |
60 |
Max /init requests per hour per email |
api_rate_submit_per_hour |
5 |
Max /submit requests per hour per email |
Error Responses¶
400 Bad Request¶
401 Unauthorized¶
403 Forbidden¶
404 Not Found¶
429 Too Many Requests¶
Headers:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests per hour |
X-RateLimit-Remaining |
Remaining requests in current window |
Retry-After |
Seconds until the rate limit resets |
See Also¶
- gRPC API - Internal service definitions
- Coordinator Architecture - Service internals and deployment
- GCP Deployment - Terraform configuration