Skip to main content

OpenAPI 3.1 · Generation Surface

Generation API Reference

The surface a third-party integration (e.g. a Minds Bazaar-style skill) calls at runtime to generate assets. Machine-readable version at /openapi.yaml. Key creation happens once, out of band, at /dashboard/keys— not through this API.

Bearer authJSON only, no multipartX-Request-Id on every response120 req/min default

Endpoints at a glance

POST/api/v1/generate/2d2D sprite/asset
POST/api/v1/generate/3d3D model — prefer /jobs
POST/api/v1/generate/imageHigh-res image
POST/api/v1/generate/voiceText to speech
POST/api/v1/generate/musicMusic — mock only today
POST/api/v1/generate/vfxVFX / video clip
POST/api/v1/generate/editingUpscale / inpaint / outpaint / remove-bg
POST/api/v1/jobsSubmit an async job
GET/api/v1/jobsList your recent jobs
GET/api/v1/jobs/{jobId}Job status + output
GET/api/v1/creditsShard balance
GET/api/v1/projectsList folders + assets
POST/api/v1/projects/foldersCreate a folder
PATCH/api/v1/projects/folders/{folderId}Rename / move a folder
DELETE/api/v1/projects/folders/{folderId}Delete a folder

Authentication

Every endpoint requires Authorization: Bearer <api-key>. Bearer is the only supported scheme — there is no x-api-key-style header.

Keys come in two forms, otherwise functionally identical — same base URL, same schemas, same real-or-mock provider dispatch per category:

gr_live_…— real key, billed against the account's real shard balance.

gr_test_… — sandbox key, for pre-launch integration testing. Minted the same way as a live key, via /dashboard/keys, selecting the "Test" environment. There is no separate test API surface to point at.

A Portal AIR session token is also accepted on these endpoints, but that's the Nexus dashboard's own auth path — not relevant to external integrations.

Billing & output

Every generation — synchronous or async — reserves and captures "shards" from the calling account's balance, keyed by the API key used. Studio, MCP, the Nexus UI, and this API all bill identically; there is no unmetered path. A fresh account starts with a default free-tier balance — coordinate separately if an integration needs it topped up.

Every category has at least one real, configured provider except music (Mubert is not currently configured). An unconfigured or partially-tried provider degrades gracefully to a mock output rather than erroring, so a call always succeeds structurally even when the asset itself is a placeholder. Check the top-level mock boolean on the response (or job output) to distinguish a mock result from a real provider result — the mock URL prefix (https://cdn.gamerouter.dev/mock/…) still holds too, but mock is the supported way to check it.

/api/v1/generate/{category} blocks for the duration of the generation, up to a 300s server-side ceiling. For 3d specifically — the slowest category — prefer /api/v1/jobs (submit + poll) instead of the synchronous endpoint. Other categories are safe synchronously.

Reference inputs

For image-to-image or reference-audio use cases, pass inputFiles — always a URL in the JSON body, never multipart:

"inputFiles": [{ "url": "https://...", "name": "ref.png", "mimeType": "image/png" }]

Only the first entry is currently used. Malformed entries (missing url) are dropped rather than rejecting the whole request; name / mimeType default if omitted.

Generation

POST/api/v1/generate/2d

Generate a 2D sprite/asset

Request body
promptrequired
string
tool
string — explicit provider id, e.g. pixellab. Omit to auto-select via routing.
routing
cheapest · best · fastest — default best
inputFiles
array of { url, name?, mimeType? }
options.resolution
string, e.g. "32x32"
options.frames
integer ≥ 1
options.format
string, e.g. png
Responses
200
Generated (real or mock). Body: { id, tool, provider, output: { url, format, width, height, frames }, outputUrl, mock, shardCost, latencyMs, routing }
401
Unauthorized
402
Insufficient shard balance
422
Validation error
429
Rate limited
502
No compatible tool, or the provider call failed. Hold released automatically.
POST/api/v1/generate/3d

Generate a 3D model

Slowest category — prefer /api/v1/jobs over this synchronous endpoint
Request body
promptrequired
string
tool
string, e.g. meshy
routing
cheapest · best · fastest
inputFiles
reference image — required when options.mode is image-to-3d
options.mode
text-to-3d · image-to-3d
options.format
string, e.g. glb
options.polyCount
integer
options.textured / rigged
boolean
Responses
200
Generated (real via Meshy, or mock). Body: { id, tool, provider, output: { url, format, polyCount, textured, rigged }, mock, shardCost, latencyMs, routing }
401
Unauthorized
402
Insufficient shard balance
422
Validation error
429
Rate limited
502
No compatible tool, or the provider call failed
POST/api/v1/generate/image

Generate a high-resolution image

Request body
promptrequired
string
tool
string, e.g. stability, leonardo
routing
cheapest · best · fastest
inputFiles
array of { url, name?, mimeType? }
options.model
string
options.resolution
string, e.g. "1024x1024"
Responses
200
Generated (real or mock). Body: { id, tool, provider, output: { url, format, width, height }, mock, shardCost, latencyMs, routing }
401
Unauthorized
402
Insufficient shard balance
422
Validation error
429
Rate limited
502
No compatible tool, or the provider call failed
POST/api/v1/generate/voice

Generate speech from text

Also accepts a reference-audio inputFiles entry for voice cloning, provider-dependent
Request body
textrequired
string — alias for prompt; at least one of the two is required
prompt
string
tool
string, e.g. elevenlabs
routing
cheapest · best · fastest
inputFiles
array of { url, name?, mimeType? }
options.voice_id
string
options.model
string
Responses
200
Generated (real or mock). Body: { id, tool, provider, output: { url, format, durationMs, characters }, mock, shardCost, latencyMs, routing }
401
Unauthorized
402
Insufficient shard balance
422
Neither text nor prompt was provided, or another validation error
429
Rate limited
502
No compatible tool, or the provider call failed
POST/api/v1/generate/music

Generate music

Mock only today — MUBERT_API_KEY is not currently configured
Request body
promptrequired
string
tool
string, e.g. mubert
routing
cheapest · best · fastest
options.duration
integer, seconds — default 30
Responses
200
Generated — currently always mock. Body: { id, tool, provider, output: { url, format, durationMs }, mock, shardCost, latencyMs, routing }
401
Unauthorized
402
Insufficient shard balance
422
Validation error
429
Rate limited
502
No compatible tool, or the provider call failed
POST/api/v1/generate/vfx

Generate a VFX/video clip

Request body
promptrequired
string
tool
string, e.g. luma-video
routing
cheapest · best · fastest
options.duration
integer, seconds — default 5
options.resolution
string, e.g. 720p
Responses
200
Generated (real via Luma, or mock). Body: { id, tool, provider, output: { url, format, durationMs }, outputUrl, mock, shardCost, latencyMs, routing }
401
Unauthorized
402
Insufficient shard balance
422
Validation error
429
Rate limited
502
No compatible tool, or the provider call failed
POST/api/v1/generate/editing

Edit an existing image

Upscale, inpaint, outpaint, or remove background — requires inputFiles
Request body
promptrequired
string
inputFilesrequired
source image — inputFiles[0].url
tool
stability-upscale · stability-inpaint · stability-outpaint · stability-remove-bg — explicit mode selection is recommended
options.mask_url
string, URL — required for inpaint
options.left / right / up / down
integer — outpaint margins
Responses
200
Generated (real, via Stability). Body: { id, tool, provider, output: { url, format, width, height }, outputUrl, mock, shardCost, latencyMs, routing }
401
Unauthorized
402
Insufficient shard balance
422
Validation error
429
Rate limited
502
No compatible tool, or the provider call failed

Jobs

POST/api/v1/jobs

Submit an async generation job

Preferred for 3D — submit here, poll GET /jobs/{jobId}
Request body
categoryrequired
2d · 3d · voice · music · image · vfx · editing
promptrequired
string
tool
string
routing
cheapest · best · fastest — default best
options
object — same per-category fields as the matching synchronous endpoint
inputFiles
array of { url, name?, mimeType? }
saveTo
{ folderId, name? } — optional. Get a folderId from GET /api/v1/projects (its defaultSaveFolderId, or any id in folders[]) or create one via POST /api/v1/projects/folders. If folderId is omitted or empty, saveTo is silently ignored — the job still succeeds and returns output normally, nothing is saved, and no error is raised.
source
nexus_ui · studio · mcp · minds · api — self-reported, observability only
Example
{ "category": "3d", "prompt": "a mossy stone archway", "source": "minds" }

→ 202 { "jobId": "5f2c…", "status": "queued" }
Responses
202
Job queued. Body: { jobId, status: "queued" }
401
Unauthorized
402
Insufficient shard balance
422
Validation error
429
Rate limited
502
Failed to enqueue — shard hold released automatically
503
Async jobs not configured in this environment
GET/api/v1/jobs

List your recent jobs

Most recent 50
Responses
200
Body: { jobs: Job[] } — see the Job schema below
401
Unauthorized
GET/api/v1/jobs/{jobId}

Get a job's status and output

Responses
200
Body: { job: Job }
401
Unauthorized
404
Job not found, or not owned by this key's account

Account

GET/api/v1/credits

Get the current shard balance

Responses
200
Body: { balance: number, currency: "USD" }
401
Unauthorized

Projects

GET/api/v1/projects

List your project folders and assets

Query params
folderId
string — filter assets to one folder. Omit for every asset on the account.
Responses
200
Body: { folders: Folder[], assets: Asset[], defaultSaveFolderId: string | null }. defaultSaveFolderId is a ready-made folderId for saveTo that needs no lookup, when the account has one set.
401
Unauthorized
POST/api/v1/projects/folders

Create a project folder

Request body
namerequired
string
parentId
string | null — nest under an existing folder. Omit or null for top-level.
kind
project · folder — default folder
engine
godot · unreal · null — only meaningful when kind is project
Responses
201
Body: { folder: Folder }
401
Unauthorized
422
Validation error
PATCH/api/v1/projects/folders/{folderId}

Rename or move a folder

Request body
name
string
parentId
string | null — set to move the folder; null moves it to the top level
Responses
200
Body: { folder: Folder }
401
Unauthorized
422
Validation error
DELETE/api/v1/projects/folders/{folderId}

Delete a folder

Responses
200
Body: { ok: true }
401
Unauthorized
422
Validation error

Schemas

Shared shapes referenced across the endpoints above.

InputFile

urlrequired
string, URI
name
string — defaults to "input"
mimeType
string — defaults to application/octet-stream

Category

enum: 2d · 3d · voice · music · image · vfx · editing

npc / video / skybox exist internally but have no generate/* endpoint or configured tool yet.

Routing

enum: cheapest · best · fastest, default best

JobStatus

enum: queued · running · succeeded · failed

Job

id
string, uuid
userId
string
source
nexus_ui · studio · mcp · minds · api
category
Category
toolId
string | null
routing
Routing
input
object — echo of the original request (prompt, options, tool, saveTo, inputFiles)
status
JobStatus
output
object | null — present once status is succeeded. Not the generate/* body: { tool: { id, name, provider }, category, outputUrl, format, mimeType, width?, height?, frames?, durationMs?, shardCost, latencyMs, mock, savedAs? }
error
string | null — present when status is failed
shardCost
number | null
createdAt / startedAt / completedAt
string, date-time (startedAt / completedAt nullable)

Folder

id
string
name
string
parentId
string | null
kind
project · folder
engine
godot · unreal · null
createdAt / updatedAt
string, date-time

Asset

A generated (or uploaded) file saved into a folder via saveTo.

id
string
folderId
string
name
string
type
2d · 3d · voice · music · image · vfx · other
source
generated · upload
toolId / toolName / provider
string
outputUrl
string, URI
format / prompt
string
createdAt / updatedAt
string, date-time

Error codes

Every non-2xx response returns { error: { code, message } }. Complete set of code values across this surface:

unauthorized
validation_error
no_tool_available
tool_not_found
provider_error
insufficient_shards
rate_limited
jobs_not_configured
enqueue_failed
job_not_found
internal_error
server_error
Portal Nexus Generation API · OpenAPI 3.1.0 · Machine-readable spec: /openapi.yaml