Nodaro Docs
DocumentationNode ReferenceModelsAI Agents (MCP)DevelopersSelf-hostingResearch
REST API

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 runsBase URL
Nodaro Cloudhttps://app.nodaro.ai
A self-hosted installThe 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 use multipart/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 with adjustments or warnings beside it.
  • Lists use cursors. A list returns a cursor, usually nextCursor (next on GET /v1/jobs). Pass it back as ?cursor= for the next page. A null cursor 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_data and created_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 on code. See Errors.

Two optional headers change how a request is handled:

HeaderWhat it does
X-Nodaro-WorkspaceActs in one workspace of an organization: which workspace a list reads and where a create lands. See Workspaces.
X-Nodaro-ClientRecords 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

PageWhat it coversMain endpoints
WorkflowsRun a saved workflow, with or without inputs, and manage workflowsPOST /v1/workflows/:id/run, POST /v1/api/run, GET /v1/api/schema
NodesRun one node without a workflow, and discover nodes, models and pickersPOST /v1/<node-type>, GET /v1/nodes, GET /v1/models
JobsJob status and results, batch polling, cancelling, Video Pro run controlGET /v1/jobs/:id/status, POST /v1/jobs/batch-status
ExecutionsThe status and history of workflow runsGET /v1/workflow-executions/:id, GET /v1/workflows/:id/executions
UploadsUpload images, video and audio, or copy a URL into storagePOST /v1/upload, POST /v1/save-to-storage
WebhooksStart a workflow from an HTTP call or a schedule, and send results outPOST /v1/webhooks/:token, POST /v1/workflow-triggers

Resources

PageWhat it coversMain endpoints
CharactersCharacters, portrait candidates, expressions, poses and motion/v1/characters, POST /v1/generate-character
ObjectsProps, products and vehicles with their main image and variants/v1/objects, POST /v1/generate-object
LocationsPlaces with their main image and variants/v1/locations, POST /v1/generate-location
CreaturesCreatures with their main image and variants/v1/creatures
PresetsYour node presets and the built-in catalog, read-onlyGET /v1/node-presets, GET /v1/node-presets/factory
CommunityBrowse and clone shared characters, locations and objectsGET /v1/community/browse
PipelinesStory-to-Video pipelinesPOST /v1/pipelines/:id/branch
Prompt WizardImprove a prompt for a generation nodePOST /v1/prompt-helper/wizard
RecastRegenerate an analyzed video with your own castPOST /v1/recast
Studio productionsShot-by-shot productions/v1/studio/productions
Voice and mediaVoices, voice changing, dubbing, media import and audio tools/v1/voices, /v1/download-video, /v1/transcribe
Character trainingTrain a model on one characterPOST /v1/characters/:id/train
3D scenesEditable 3D scenes and 3D Render ProPOST /v1/3d-scene/generate, POST /v1/pro-3d-render

Account

PageWhat it coversMain endpoints
Workspaces and organizationsActing in a workspace, organizations, members, invitations and usage/v1/orgs, /v1/workspaces
CreditsBalance, transactions and cost lookupsGET /v1/credits/balance, GET /v1/credits/transactions

Reference

PageWhat it covers
ErrorsThe error envelope, every error code, and job failure hints
Rate limitsPer-token limits, per-route limits, and how to handle 429
OpenAPI specThe 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 --watch and --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

Last updated on

On this page