API Reference
OpenAI-compatible. Use any OpenAI SDK by pointing it at our base URL.
Authentication
All endpoints require a Studio API key passed as a Bearer token:
Authorization: Bearer sk_live_<your_key>
Get a key from your Studio dashboard.
Keys carry scopes:
llm:read,llm:write— chat completionsimggen:read,imggen:write— image + video generation and status pollingtraining:read,training:write— fine-tuning jobs (coming soon)
Anonymous access is not permitted. 401 means key missing/invalid; 403 means key lacks the scope.
Service status
Live state of Studio Inference surfaces:
| Surface | State | Notes |
|---|---|---|
POST /api/v1/llm/chat | OK | Jessi VL 30B (Qwen3-VL-30B-A3B-Instruct, MoE) served via in-cluster vLLM. ~1.5s p50 first-token. |
POST /api/v1/imggen/generate + status | OK | z-image-pro and flux-krea via studio-cloud. ~80s end-to-end. |
POST /api/v1/video/generate + status | OK | Studio Video v2. ~2-5 min/clip. |
GET /api/public/models | OK | Public catalog (white-labeled). |
Vision input on jessi-vl | DEGRADED | Currently text-only mode in deployment. We're re-enabling multimodal. |
Model catalog
Browse models programmatically (no auth required):
curl https://api.yourjessi.com/api/public/models # all curl 'https://api.yourjessi.com/api/public/models?category=llm' # filter curl 'https://api.yourjessi.com/api/public/models?vision=true' # vision-capable
Response shape (vendor-redacted):
{
"models": [
{
"slug": "jessi-vl",
"label": "Jessi VL 30B (Qwen3-VL-30B-A3B)",
"description": "Multimodal LLM (MoE 3B active). Currently text-only mode.",
"category": "llm",
"family": "multimodal",
"accepts_vision": false,
"vision_status": "degraded",
"context_window": 32768,
"tags": ["reasoning", "tool-use"],
"pricing": { "unit": "token_per_1k", "input_per_1k": 0.0008, "output_per_1k": 0.0024 },
"pool": "studio-llm",
"status": "active"
}
],
"count": 10
}POST /api/v1/llm/chat
OpenAI chat-completion shape. Streaming supported with stream: true.
curl -X POST https://api.yourjessi.com/api/v1/llm/chat \
-H "Authorization: Bearer $STUDIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jessi-vl",
"messages": [{"role":"user","content":"Hello!"}],
"max_tokens": 256,
"temperature": 0.7
}'Streaming
Pass stream: true. Response is SSE; final chunk is data: [DONE]:
{ "model": "jessi-vl", "messages": [...], "stream": true }Vision input currently degraded
The API accepts OpenAI content-parts:
{
"model": "jessi-vl",
"messages": [{
"role": "user",
"content": [
{"type":"text","text":"What's in this image?"},
{"type":"image_url","image_url":{"url":"https://example.com/photo.jpg"}}
]
}]
}⚠ The current deployment is in text-only mode. image_url parts are accepted but the model will not interpret them. Tracking in the next deployment iteration.
OpenAI SDK
from openai import OpenAI
client = OpenAI(
base_url="https://api.yourjessi.com/api/v1/llm",
api_key="$STUDIO_API_KEY",
)
resp = client.chat.completions.create(
model="jessi-vl",
messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)POST /api/v1/imggen/generate
Submit an async image generation job. Returns 202 with a job id; poll /api/v1/imggen/status/[id].
curl -X POST https://api.yourjessi.com/api/v1/imggen/generate \
-H "Authorization: Bearer $STUDIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "z-image-pro",
"prompt": "a green parrot perched on a branch"
}'Response (HTTP 202):
{
"id": "57ae954c-7026-4e84-ba03-ee63e337bc01",
"upstream_job_id": "ed988aae-d72d-4408-afa9-a774dee78b65-u1",
"status": "queued",
"model": "z-image-pro",
"pool": "studio-cloud",
"status_url": "/api/v1/imggen/status/57ae954c-7026-4e84-ba03-ee63e337bc01",
"unit_type": "image",
"price_per_unit": 0.012,
"estimated_price": 0.012
}Polling status
curl https://api.yourjessi.com/api/v1/imggen/status/$JOB_ID \ -H "Authorization: Bearer $STUDIO_API_KEY"
Response when complete (HTTP 200):
{
"id": "57ae954c-7026-4e84-ba03-ee63e337bc01",
"model": "z-image-pro",
"status": "complete",
"output_url": "https://studio-bucket.yourjessi.com/u/<user>/2026/05/z-image-pro-...png",
"output_urls": ["https://studio-bucket.yourjessi.com/..."],
"pool": "studio-cloud"
}Status values: queued, processing, complete, failed. Output images are persisted to public R2 storage and the URL is permanent. Typical end-to-end: 10-40s for image, 2-5min for video.
POST /api/v1/video/generate
Same shape as imggen, plus length_seconds and (optional) image_url for image-to-video:
curl -X POST https://api.yourjessi.com/api/v1/video/generate \
-H "Authorization: Bearer $STUDIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan2-video",
"prompt": "A cat playing in a sunbeam.",
"length_seconds": 5,
"image_url": "https://example.com/cat.jpg"
}'Status polling: GET /api/v1/video/status/[id] (same response shape as imggen).
Rate limits
Default: 300 requests per minute per key. Sliding 60-second window.
Every successful response carries:
X-RateLimit-Limit: 300 X-RateLimit-Remaining: 287 X-RateLimit-Reset: 1715520000 # unix epoch seconds
429 responses are not billed. Retry with exponential backoff. If you need a higher limit (production usage), contact us via your Studio dashboard.
Error responses
All errors return JSON of the shape:
{ "error": { "code": "invalid_model", "message": "Unknown LLM model 'foo'." } }Common codes:
| HTTP | code | Cause |
|---|---|---|
| 400 | invalid_json | Body wasn't parseable JSON. |
| 400 | invalid_request | Required field missing or wrong type. |
| 400 | invalid_model | Unknown model slug. See /api/public/models. |
| 400 | wrong_endpoint | Tried image model on /llm/chat or vice versa. |
| 401 | unauthorized | Bearer token missing/malformed/revoked. |
| 403 | forbidden | Key lacks the required scope (e.g. llm:write). |
| 429 | rate_limit_exceeded | Key over its requests-per-minute. Not billed. |
| 502 | upstream_unreachable | Backend (vLLM / RunPod) didn't respond. Retry; we autopage on >5min. |
| 502 | upstream_error | Backend returned an error (HTTP 5xx, OOM, etc.). |
| 503 | model_paused | Model is in maintenance. Try a different model in same family. |
| 503 | provider_unavailable | Pool offline. Same as above. |
Webhooks (coming soon)
For long-running image/video jobs, you'll be able to register a webhook URL on your dashboard. We'll POST { event, generation_id, status, output_url } on completion or failure with an HMAC-SHA256 signature in X-Studio-Signature.
Recent changes
- 2026-05-13 — Public launch on
api.yourjessi.com. LLM chat (text), image gen (z-image-pro, flux-krea), video gen (wan2-video) all live. - 2026-05-13 — Cluster control plane recovered after etcd quorum loss. vLLM serving Jessi VL 30B (Qwen3-VL-30B-A3B-Instruct, MoE) again.
- 2026-05-13 — Catalog corrected:
jessi-vlis the 30B MoE model, not 72B. The 72B yaml in repo is unused/aspirational. - Pending — Re-enable vision input on jessi-vl (deployment in text-only mode currently).
- Pending — Webhooks, fine-tuning, custom domains.