Media generation
Generate images synchronously and video, music, code builds, walkable 3D rooms from a few photos or a video, and research as jobs.
Images (sync)
Image generation is synchronous: the response carries the finished image. Pick an engine or omit it — the default is theo-ultra on paid plans (Free-plan calls fall back to theo-creative and the response says so):
promptrequiredstringengineauto | theo-creative | theo-imagine | theo-photo | theo-rapid | theo-design | theo-studio | theo-type | theo-ultra | grok-theoaspectRatio1:1 | 16:9 | 9:16 | 4:3 | 3:4stylestringreferenceImageUrlsarray<uri> (max 5)includeBase64booleancurl https://www.opencharts.com/api/v1/images \
-H "Authorization: Bearer $OPENCHARTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "prompt": "Isometric pixel-art data center, neon accents", "aspectRatio": "16:9" }'Theo Moonlight (our own model)
POST /images/moonlight renders on Theo Moonlight, the first-party image model OpenCharts serves on its own hardware. It is the endpoint to point a benchmark or an arena at: synchronous, seedable, and with only a prompt it renders at the model's published defaults (1024x1024, 8 steps, guidance 1). The response carries the PNG bytes and the seed that was used; nothing is stored for you.
promptrequiredstringnegativePromptstringaspectRatio1:1 | 3:4 | 4:3 | 2:3 | 3:2 | 9:16 | 16:9seedintegerSafe-for-work only
This endpoint renders safe-for-work images. A prompt describing adult content is refused with a 400 before anything renders, and a finished render the safety check scores as adult is refused with a 403. Neither is charged.
curl https://www.opencharts.com/api/v1/images/moonlight \
-H "Authorization: Bearer $OPENCHARTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "prompt": "A lighthouse keeper reading by lamplight, rain on the window, oil painting", "seed": 42 }'Videos
Video renders return a 202 job envelope immediately:
promptrequiredstringaspectRatio16:9 | 9:16modelTierfast | maxreferenceImageUrluriSongs
stylerequiredstringtitlestringlyricsstringautoLyricsbooleaninstrumentalbooleantierauto | premium | fastCompleted jobs return two versions, each with audio, cover art, and a Theo-branded engine label.
Code builds
Build a full Code Canvas project (site or app) from a prompt; the finished project opens in the OpenCharts editor:
promptrequiredstringnamestringframeworkhtml | react | autoplanFirstbooleanReal World spaces (photos or a video of a room, a walkable 3D space)
POST /real-world/spaces turns photos of ONE room into an imagined, walkable 3D room on Theo Real World. Send up to eight photos taken from one spot, turning between shots so each overlaps the last (imageUrls), or one short video of the room (videoUrl), and Theo works out where each photo was taken, builds the room, and imagines every wall, floor and corner the photos did not show. The job answers in two tiers on the same space_ job: a walkable quick room lands on the poll while the job is still processing (about a minute and a half), and the full room at real scale (with metricScale, a 360 panorama and a collider mesh) completes it a few minutes later. One photo alone (imageUrl) builds a room too; on a deployment without the room engine it becomes a measured, imagined, walkable space instead, with the 360 preview and the room's dimensions first.
imageUrlsuri[] (1 to 8)videoUrluriimageUrluriqualitypreview | fulltitlestringHonest about what is imagined
The photos are the only real part. Every result carries imagined: true. A room is truest where the photos looked; a one-photo space's dimensions are estimates with a confidence each (monocular scale is typically within 5 to 15 percent), and a wall the photo did not show makes a value a floor, flagged lowerBound: true. Say so to your users too. A photo of an object or a person is not a space; captures are not on this API.
curl https://www.opencharts.com/api/v1/real-world/spaces \
-H "Authorization: Bearer $OPENCHARTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "imageUrls": ["https://example.com/photos/living-room-1.jpg", "https://example.com/photos/living-room-2.jpg", "https://example.com/photos/living-room-3.jpg"], "quality": "full" }'{
"stage": "space",
"imagined": true,
"source": "photos",
"photoCount": 3,
"panoramaUrl": "https://www.opencharts.com/api/canvas-video/...",
"spaceUrl": "https://www.opencharts.com/api/canvas-video/...",
"spaceFullUrl": "https://www.opencharts.com/api/canvas-video/...",
"format": "spz",
"metricScale": 1.38,
"floorOffsetM": 1.351,
"colliderUrl": "https://www.opencharts.com/api/canvas-video/...",
"depthUrl": null,
"posterUrl": "https://...",
"gaussians": null,
"dimensions": null,
"engine": "Theo Real World 1.1"
}Register a webhook for space.completed / space.failed to be told when the job ends instead of polling. A completed job may stay at stage: preview when only the preview was asked for, or when the walkable tier did not finish; the result's notes say so. The full walkthrough, from the key to rendering the splat, is the Real World spaces guide.
Deep research
Multi-step web research with citations, returned as a markdown report plus sources:
/researchStart a deep-research job (returns a res_-prefixed job id).GET/research/{jobId}Legacy poll alias (accepts raw or res_-prefixed ids).Poll research like every other job at GET /jobs/{id} using the returned res_… id. The legacy GET /research/{jobId} path stays for older integrations: it accepts both id forms and returns its original (pre-jobs) response shape.
curl https://www.opencharts.com/api/v1/research \
-H "Authorization: Bearer $OPENCHARTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "query": "State of AI-native documentation tooling in 2026" }'Idempotent retries
Every generation POST accepts Idempotency-Key
Retries with the same key replay the original response: the async job creators return the same job (billed once), and the synchronous /images + /extract-flowchart replay the original finished result. Pair with webhooks for a fully event-driven pipeline. See Idempotency.