REST API overview
The Nodaro REST API runs workflows and single nodes, polls jobs, uploads media and manages assets over HTTPS with JSON and a bearer token.
The Nodaro REST API is the HTTP interface to Nodaro: it runs workflows and single nodes, reports the status of their jobs, stores your media, and manages characters, presets and workspaces. Requests and responses are JSON over HTTPS, and every request carries a bearer token. The same API serves Nodaro Cloud and self-hosted installs, and the TypeScript SDK and the CLI are thin clients of it.
Base URL
| Where Nodaro runs | Base URL |
|---|---|
| Nodaro Cloud | https://app.nodaro.ai |
| A self-hosted install | The install's own address, for example http://localhost:3000 for a default Community Edition install |
Every path starts with /v1/, for example https://app.nodaro.ai/v1/nodes. Some endpoints exist only on Nodaro Cloud, such as credits and organizations, and answer 404 on other editions. Each page says when an endpoint is limited.
Authentication
Send Authorization: Bearer <token> on every request. Use a personal API token (ndr_…) from Settings › API Tokens for your own account, an OAuth access token (ndr_app_…) when your product acts for other Nodaro users, or your session JWT on a Community Edition install. A handful of discovery endpoints, such as GET /v1/nodes and GET /v1/models, need no token at all. Read Authentication to create a token.
Your first call
This example generates an image with one node and reads the result. Generation is asynchronous: the first call returns a job id, and you poll the job until it is complete.
export NODARO_API_KEY="ndr_..."
# 1. Start the job
curl -s -X POST https://app.nodaro.ai/v1/generate-image \
-H "Authorization: Bearer $NODARO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "a snow leopard on a mountain ridge at dawn",
"provider": "nano-banana-pro",
"aspectRatio": "16:9"
}'
# {"jobId":"0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10"}
# 2. Poll the job until its status is "completed"
curl -s https://app.nodaro.ai/v1/jobs/0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10/status \
-H "Authorization: Bearer $NODARO_API_KEY"{
"data": {
"id": "0f1a9c2e-5b7d-4e8a-9c31-6d2f8b4a7e10",
"status": "completed",
"progress": 100,
"output_data": { "imageUrl": "https://…/0f1a9c2e.png" },
"error_message": null
}
}import { createClient, StaticTokenAuth } from '@nodaro/sdk'
const client = createClient({
baseUrl: 'https://app.nodaro.ai',
auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})
// Starts the job and polls it until it finishes.
const output = await client.nodes.runAndWait('generate-image', {
prompt: 'a snow leopard on a mountain ridge at dawn',
provider: 'nano-banana-pro',
aspectRatio: '16:9',
})
console.log(output.imageUrl)nodaro nodes run generate-image \
--param prompt="a snow leopard on a mountain ridge at dawn" \
--param provider=nano-banana-pro \
--param aspectRatio=16:9 \
--watch --json | jq -r '.output_data.imageUrl'The same pattern runs every generation node: POST /v1/<node-type> with the node's settings, then poll the job. See Run a single node.
Request and response conventions
- JSON in, JSON out. Send bodies as JSON with
Content-Type: application/json. File uploads are the exception: they usemultipart/form-data. - Ids are UUIDs. A malformed id answers
400 validation_error. - Most responses are wrapped in
data. A read returns{ "data": … }, and a delete or a cancel returns{ "success": true }. The legacy workflow endpoints under/v1/api/return their payload directly. - Generations return a job id.
POST /v1/<node-type>answers with{ "jobId": "…" }, sometimes withadjustmentsorwarningsbeside it. - Lists use cursors. A list returns a cursor, usually
nextCursor(nextonGET /v1/jobs). Pass it back as?cursor=for the next page. Anullcursor means there are no more rows. Cursors are opaque: never parse or build one. - Two field styles. Job objects use snake_case, such as
output_dataandcreated_at. Workflows, executions and most other resources use camelCase. - Responses grow. New fields appear over time. Ignore the fields you do not know instead of failing on them.
- Errors share one shape. A failed call returns an HTTP status and
{ "error": { "code": "…", "message": "…" } }. Dispatch oncode. See Errors.
Two optional headers change how a request is handled:
| Header | What it does |
|---|---|
X-Nodaro-Workspace | Acts in one workspace of an organization: which workspace a list reads and where a create lands. See Workspaces. |
X-Nodaro-Client | Records which client created a job: sdk/<version>, cli/<version> or extension/<name>. See Identify your client. |
Sync or async
Most work in Nodaro takes seconds to minutes, so the API is asynchronous. A generation route answers at once with a jobId, and a workflow run answers 202 Accepted with an executionId. You then poll the job or the execution every 2 to 5 seconds until it reaches a final status. For a workflow you expect to finish in under a minute, POST /v1/api/run?wait=true holds the connection for up to 600 seconds and returns the result. A few routes answer synchronously, such as inline text nodes, free media processing and the structured LLM call. Read Sync or async for the details.
Endpoints by area
Run things
| Page | What it covers | Main endpoints |
|---|---|---|
| Workflows | Run a saved workflow, with or without inputs, and manage workflows | POST /v1/workflows/:id/run, POST /v1/api/run, GET /v1/api/schema |
| Nodes | Run one node without a workflow, and discover nodes, models and pickers | POST /v1/<node-type>, GET /v1/nodes, GET /v1/models |
| Jobs | Job status and results, batch polling, cancelling, Video Pro run control | GET /v1/jobs/:id/status, POST /v1/jobs/batch-status |
| Executions | The status and history of workflow runs | GET /v1/workflow-executions/:id, GET /v1/workflows/:id/executions |
| Uploads | Upload images, video and audio, or copy a URL into storage | POST /v1/upload, POST /v1/save-to-storage |
| Webhooks | Start a workflow from an HTTP call or a schedule, and send results out | POST /v1/webhooks/:token, POST /v1/workflow-triggers |
Resources
| Page | What it covers | Main endpoints |
|---|---|---|
| Characters | Characters, portrait candidates, expressions, poses and motion | /v1/characters, POST /v1/generate-character |
| Objects | Props, products and vehicles with their main image and variants | /v1/objects, POST /v1/generate-object |
| Locations | Places with their main image and variants | /v1/locations, POST /v1/generate-location |
| Creatures | Creatures with their main image and variants | /v1/creatures |
| Presets | Your node presets and the built-in catalog, read-only | GET /v1/node-presets, GET /v1/node-presets/factory |
| Community | Browse and clone shared characters, locations and objects | GET /v1/community/browse |
| Pipelines | Story-to-Video pipelines | POST /v1/pipelines/:id/branch |
| Prompt Wizard | Improve a prompt for a generation node | POST /v1/prompt-helper/wizard |
| Recast | Regenerate an analyzed video with your own cast | POST /v1/recast |
| Studio productions | Shot-by-shot productions | /v1/studio/productions |
| Voice and media | Voices, voice changing, dubbing, media import and audio tools | /v1/voices, /v1/download-video, /v1/transcribe |
| Character training | Train a model on one character | POST /v1/characters/:id/train |
| 3D scenes | Editable 3D scenes and 3D Render Pro | POST /v1/3d-scene/generate, POST /v1/pro-3d-render |
Account
| Page | What it covers | Main endpoints |
|---|---|---|
| Workspaces and organizations | Acting in a workspace, organizations, members, invitations and usage | /v1/orgs, /v1/workspaces |
| Credits | Balance, transactions and cost lookups | GET /v1/credits/balance, GET /v1/credits/transactions |
Reference
| Page | What it covers |
|---|---|
| Errors | The error envelope, every error code, and job failure hints |
| Rate limits | Per-token limits, per-route limits, and how to handle 429 |
| OpenAPI spec | The machine-readable spec at GET /v1/openapi.json, and clients in other languages |
Limits and errors
A personal API token allows 30 requests per minute by default, up to 120, on the workflow-run and workflow-list endpoints, and a few routes have limits of their own. Status polls do not count against the token's limit. A 429 means slow down and retry with backoff; a 4xx means fix the request before you retry; a 5xx is usually temporary. Read Rate limits and Errors.
Clients for your language
- TypeScript and JavaScript:
npm install @nodaro/sdk. The SDK wraps these endpoints with types, typed errors and polling helpers. - The terminal and CI:
npm install -g @nodaro/cli. The CLI runs workflows, apps and single nodes, with--watchand--json. - Any other language: generate a client from the OpenAPI spec, or send plain HTTPS requests.
- AI assistants: connect the MCP server instead of writing code.
Frequently asked questions
Related
Authentication
Workflows
Nodes
Jobs
Errors
Last updated on
Developers
Build on Nodaro with the REST API, the TypeScript SDK and the CLI. Use API tokens or OAuth, generate clients from OpenAPI and connect AI agents over MCP.
Authentication
Authenticate Nodaro API calls with a personal API token, an OAuth app token or a session JWT, and create, scope, bind and revoke your API tokens.