Public API

Generate video, images and music from your own code

Create a key, send a request with Bearer auth and poll the task until your file is ready. Same models, prices, plan limits and refunds as the NovaMotions AI studio, from one shared credit balance.

Base URLhttps://novamotions.com/api/v1

Quickstart

Three steps from zero to a finished video. Every request is plain HTTPS with JSON, so any language or tool works.

  1. 1

    Create a key

    Open the API page in your account and create a key. The full key is shown once, so store it in an environment variable called API_KEY.

  2. 2

    Submit a task

    Send the model, a prompt and any options. Credits are charged once, at submit, and the response tells you how many and what is left.

    curl -X POST https://novamotions.com/api/v1/videos \
      -H "Authorization: Bearer $API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "model": "seedance-2-pro",
        "prompt": "A slow dolly shot through a rainy neon street at night, reflections on wet asphalt, cinematic",
        "duration": 5,
        "resolution": "720p",
        "aspect_ratio": "16:9"
      }'
  3. 3

    Poll until it is ready

    Check the task every few seconds. When the status is succeeded, download the file from output_url. If it failed, the credits are already back in your balance.

    TASK_ID=your_task_id
    while true
    do
      TASK=$(curl -s https://novamotions.com/api/v1/tasks/$TASK_ID -H "Authorization: Bearer $API_KEY")
      STATUS=$(echo "$TASK" | jq -r .status)
      echo "$STATUS"
      if [ "$STATUS" = "succeeded" ] || [ "$STATUS" = "failed" ]
      then
        echo "$TASK" | jq
        break
      fi
      sleep 5
    done

Authentication

Send your key in the Authorization header of every request. Keys start with nm_live_ and belong to one account.

HTTP
Authorization: Bearer nm_live_your_api_key
Content-Type: application/json
Base URL
All endpoints live under https://novamotions.com/api/v1 and return JSON.
Keep keys secret
Call the API from your server, never from a browser or a mobile app. A revoked key stops working right away.
One balance
API calls spend the key owner's credits, the same balance the studio uses. Plan limits per generation apply too.
Media URLs
Images, videos and audio you pass in must be public https URLs that load without cookies or a login.

List models

GET/api/v1/models

Every model the API serves, with its modes, durations, resolutions, aspect ratios, audio support, reference limits and its lowest price in credits. Use it to build a model picker instead of hard-coding options.

Request

curl https://novamotions.com/api/v1/models \
  -H "Authorization: Bearer $API_KEY"

Response

JSON
{
  "object": "list",
  "data": [
    {
      "slug": "seedance-2-pro",
      "name": "Seedance 2.0 Pro",
      "kind": "video",
      "endpoint": "/api/v1/videos",
      "available": true,
      "modes": [
        "text-to-video",
        "image-to-video",
        "reference-to-video"
      ],
      "durations": [
        4,
        5,
        6,
        8,
        10,
        12,
        15
      ],
      "default_duration": 5,
      "resolutions": [
        "480p",
        "720p",
        "1080p",
        "4K"
      ],
      "aspect_ratios": [
        "16:9",
        "9:16",
        "1:1",
        "4:3",
        "3:4",
        "21:9"
      ],
      "audio": {
        "supported": true,
        "extra_credits": 20
      },
      "references": {
        "images": 9,
        "videos": 3,
        "audio": 3,
        "end_frame": true
      },
      "max_count": 4,
      "prompt_max_length": 10000,
      "from_credits": 35
    }
  ]
}

Check balance

GET/api/v1/balance

The credits the key owner can spend right now, split into pools with their expiry dates, plus the current plan.

Request

curl https://novamotions.com/api/v1/balance \
  -H "Authorization: Bearer $API_KEY"

Response

JSON
{
  "object": "balance",
  "balance": 1175,
  "never_expiring": 375,
  "next_expiry": "2026-11-17T00:00:00.000Z",
  "pools": [
    {
      "source": "subscription",
      "remaining": 800,
      "granted": 2000,
      "expires_at": "2026-11-17T00:00:00.000Z"
    },
    {
      "source": "topup",
      "remaining": 375,
      "granted": 375,
      "expires_at": null
    }
  ],
  "plan": {
    "name": "Pro",
    "status": "active",
    "cycle": "monthly",
    "renews_or_ends_at": "2026-11-14T00:00:00.000Z"
  }
}

Create a video

POST/api/v1/videos

Text to video, image to video (a start frame and optionally an end frame) or reference to video (images, clips and audio that guide the result). The mode is picked from the inputs when you leave it out.

Parameters

  • modelstring
    RequiredModel slug from the models endpoint.
  • promptstring
    RequiredWhat should happen in the clip. Optional for image-to-video, where the start frame leads.
  • modestring
    Optionaltext-to-video, image-to-video or reference-to-video. Picked from your inputs when left out.
  • durationinteger
    OptionalClip length in seconds. Must be one of the model's durations, otherwise its default is used.
  • resolutionstring
    OptionalOutput resolution such as 720p or 1080p, from the model's list.
  • aspect_ratiostring
    Optional16:9, 9:16, 1:1, 4:3, 3:4 or 21:9, from the model's list. Defaults to 16:9.
  • audioboolean
    OptionalGenerate a soundtrack with dialogue, effects and ambience on models that support it. Adds 20 credits. Defaults to false.
  • image_urlstring (URL)
    OptionalStart frame for image-to-video.
  • end_image_urlstring (URL)
    OptionalEnd frame, on models that support first and last frame.
  • reference_image_urlsstring[]
    OptionalReference images for reference-to-video, up to the model's limit.
  • reference_video_urlsstring[]
    OptionalReference clips for reference-to-video, up to the model's limit.
  • reference_audio_urlsstring[]
    OptionalAudio that guides the soundtrack, up to the model's limit.
  • countinteger
    OptionalHow many videos to make from the same request, 1 to 4. Each one is a separate task and is charged separately.
  • seedinteger
    OptionalFixed seed for repeatable results. Each extra item in a batch gets the next seed.

Request

curl -X POST https://novamotions.com/api/v1/videos \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-pro",
    "prompt": "A slow dolly shot through a rainy neon street at night, reflections on wet asphalt, cinematic",
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "16:9"
  }'

Response

JSON
{
  "tasks": [
    {
      "id": "cmtask8k2x0001ab7c9d0e1f2",
      "status": "queued",
      "credits": 44,
      "url": "https://novamotions.com/api/v1/tasks/cmtask8k2x0001ab7c9d0e1f2"
    }
  ],
  "credits_charged": 44,
  "balance": 1131
}

Create images

POST/api/v1/images

Text to image, or edit an existing image with a prompt. Ask for up to four images per request, each one is its own task.

Parameters

  • modelstring
    RequiredModel slug from the models endpoint.
  • promptstring
    RequiredWhat the image should show, or how to change the image you pass in.
  • modestring
    Optionaltext-to-image or image-edit. Picked from your inputs when left out.
  • resolutionstring
    Optional1K, 2K or 4K, from the model's list.
  • aspect_ratiostring
    OptionalAspect ratio from the model's list, including Auto on models that support it.
  • image_urlstring (URL)
    OptionalThe image to edit. Required for image-edit.
  • reference_image_urlsstring[]
    OptionalExtra reference images for an edit, up to the model's limit.
  • countinteger
    OptionalImages per prompt, 1 to 4. Each one is a separate task.
  • seedinteger
    OptionalFixed seed for repeatable results. Each extra item in a batch gets the next seed.

Request

curl -X POST https://novamotions.com/api/v1/images \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "Studio product photo of a ceramic coffee cup on oak, soft window light, shallow depth of field",
    "resolution": "1K",
    "aspect_ratio": "1:1",
    "count": 1
  }'

Response

JSON
{
  "tasks": [
    {
      "id": "cmtask8k2x0001ab7c9d0e1f2",
      "status": "queued",
      "credits": 3,
      "url": "https://novamotions.com/api/v1/tasks/cmtask8k2x0001ab7c9d0e1f2"
    }
  ],
  "credits_charged": 3,
  "balance": 1172
}

Create a song

POST/api/v1/music

A full song from a description, with your own lyrics or as an instrumental.

Parameters

  • modelstring
    RequiredModel slug from the models endpoint.
  • promptstring
    RequiredGenre, mood, instruments and tempo of the song.
  • durationinteger
    OptionalSong length in seconds, from the model's durations.
  • lyricsstring
    OptionalYour own lyrics. Leave out to let the model write them.
  • instrumentalboolean
    OptionalMake a song without vocals. Defaults to false.

Request

curl -X POST https://novamotions.com/api/v1/music \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ai-music",
    "prompt": "Warm lo-fi hip hop with soft piano, vinyl crackle and a relaxed late-night groove",
    "duration": 60,
    "instrumental": false
  }'

Response

JSON
{
  "tasks": [
    {
      "id": "cmtask8k2x0001ab7c9d0e1f2",
      "status": "queued",
      "credits": 11,
      "url": "https://novamotions.com/api/v1/tasks/cmtask8k2x0001ab7c9d0e1f2"
    }
  ],
  "credits_charged": 11,
  "balance": 1164
}

Get a task

GET/api/v1/tasks/{id}

Poll a task by its id. Once the status is succeeded, output_url points to the finished file. Polling uses the read limit, so it never eats into your submit budget.

Request

curl https://novamotions.com/api/v1/tasks/cmtask8k2x0001ab7c9d0e1f2 \
  -H "Authorization: Bearer $API_KEY"

Response

JSON
{
  "id": "cmtask8k2x0001ab7c9d0e1f2",
  "object": "task",
  "kind": "video",
  "model": "seedance-2-pro",
  "mode": "text-to-video",
  "status": "succeeded",
  "progress": 100,
  "prompt": "A slow dolly shot through a rainy neon street at night, reflections on wet asphalt, cinematic",
  "params": {
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "16:9",
    "audio": false,
    "seed": null
  },
  "output_url": "https://novamotions.com/uploads/videos/2026/10/example.mp4",
  "thumbnail_url": "https://novamotions.com/uploads/videos/2026/10/example.jpg",
  "width": 1280,
  "height": 720,
  "duration_seconds": 5,
  "credits": 44,
  "refunded": false,
  "error": null,
  "created_at": "2026-10-18T09:30:00.000Z",
  "completed_at": "2026-10-18T09:31:12.000Z"
}

List tasks

GET/api/v1/tasks

Tasks you created through the API in the last 30 days, newest first, with the same shape as a single task. Pass next_cursor as cursor to load the next page.

Parameters

  • limitinteger
    OptionalResults per page, 1 to 50. Defaults to 20.
  • cursorstring
    OptionalThe next_cursor value from the previous page.
  • statusstring
    OptionalOnly tasks with this status: queued, running, succeeded or failed.

Request

curl https://novamotions.com/api/v1/tasks?limit=20 \
  -H "Authorization: Bearer $API_KEY"

Response

JSON
{
  "object": "list",
  "data": [
    {
      "id": "cmtask8k2x0001ab7c9d0e1f2",
      "object": "task",
      "kind": "video",
      "model": "seedance-2-pro",
      "mode": "text-to-video",
      "status": "succeeded",
      "progress": 100,
      "prompt": "A slow dolly shot through a rainy neon street at night, reflections on wet asphalt, cinematic",
      "params": {
        "duration": 5,
        "resolution": "720p",
        "aspect_ratio": "16:9",
        "audio": false,
        "seed": null
      },
      "output_url": "https://novamotions.com/uploads/videos/2026/10/example.mp4",
      "thumbnail_url": "https://novamotions.com/uploads/videos/2026/10/example.jpg",
      "width": 1280,
      "height": 720,
      "duration_seconds": 5,
      "credits": 44,
      "refunded": false,
      "error": null,
      "created_at": "2026-10-18T09:30:00.000Z",
      "completed_at": "2026-10-18T09:31:12.000Z"
    }
  ],
  "next_cursor": null
}

Task statuses

A task moves from queued to running and ends as succeeded or failed. Stop polling at either end state.

queued
Accepted and waiting for a render slot. Keep polling.
running
Rendering now. progress goes from 0 to 99.
succeeded
Done. output_url and thumbnail_url point to the finished files.
failed
Ended without a result. error explains why and refunded is true, the credits are back in your balance.

Error codes

Every error has the same shape. Branch on code and show message to a person. A task that was accepted can still fail later, so check its status when you poll.

Error response
{
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits for this request. Top up or renew your plan, then retry.",
    "needed": 44,
    "balance": 14
  }
}
  • 400invalid_jsonThe body is not a JSON object.
  • 401unauthorizedNo Bearer key in the Authorization header.
  • 401invalid_api_keyThe key does not exist or is malformed.
  • 401key_revokedThe key was revoked. Create a new one.
  • 402insufficient_creditsNot enough credits for this request. The response includes needed and balance.
  • 403plan_limit_exceededThe request is above the per-generation limit of the plan. Lower the duration or resolution.
  • 403account_suspendedThe account that owns the key is suspended.
  • 403api_disabledThe API is turned off for now.
  • 404not_foundThe task or endpoint does not exist on this account.
  • 404model_not_foundNo model with this slug. Check the models endpoint.
  • 409too_many_runningThis account already has 3 tasks running. Wait for one to finish.
  • 422invalid_requestA field is missing or has the wrong type. details lists each problem.
  • 422wrong_endpointThe model belongs to another endpoint, for example an image model sent to videos.
  • 422invalid_modeThe mode is not one this endpoint knows.
  • 422mode_not_supportedThe model does not support this mode.
  • 422prompt_requiredThis mode needs a prompt.
  • 422image_requiredThis mode needs image_url.
  • 429rate_limitedToo many requests. Wait for the seconds in Retry-After, then retry.
  • 500internal_errorSomething broke on our side. Retry in a moment.
  • 503service_busyWe are at capacity right now. Retry in a few minutes.

Credits and refunds

Charged once, at submit

Each task costs the same as the same settings in the studio. The submit response returns credits_charged and your new balance. Audio on video adds 20 credits.

Failed tasks refund in full

If a task fails for any reason, all of its credits go back to the pools they came from and the task shows refunded as true. Nothing to claim.

Plan limits apply

The per-generation limit of your plan applies to API tasks too. Credits that expire soonest are spent first, top-up credits last.

Rate limits

Limits count per key over a rolling minute. Over the limit you get HTTP 429 with a Retry-After header in seconds. Every response carries the X-RateLimit headers so you can slow down before that.

Submit
30 per minute
Creating videos, images and songs.
Read
120 per minute
Tasks, balance and models. Counted separately from submits.
Running at once
3
Tasks per account rendering at the same time.
Rate limit headers
HTTP/1.1 429 Too Many Requests
Retry-After: 42
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 42

Models

The models you can call today with their slugs and lowest price. The models endpoint returns the same list with every option.

  • Seedance 2.5seedance-2-545 credits
  • Seedance 2.0 Proseedance-2-pro35 credits
  • Seedance 2.0 Miniseedance-2-mini24 credits
  • Wan 3.0wan-346 credits
  • MiniMax H3minimax-h330 credits
  • Kling 3kling-330 credits
  • Seedance 1.5 Proseedance-1-5-pro31 credits
  • Seedance 1.0seedance-132 credits
  • Kling O3kling-o346 credits
  • Kling 2.6kling-2-641 credits
  • Wan 2.7wan-2-735 credits
  • Wanwan32 credits
  • Grokgrok-video47 credits
  • Veo 3veo-342 credits
  • GPT Image 2.5gpt-image-2-54 credits
  • GPT Image 2gpt-image-23 credits
  • Seedream 5 Proseedream-5-pro4 credits
  • Seedream 5seedream-53 credits
  • Nano Banana Pronano-banana-pro5 credits
  • Nano Banana 2nano-banana-23 credits
  • Nano Banana 2 Litenano-banana-2-lite2 credits
  • AI Musicai-music6 credits

Ready to build?

Create a key in your account and send your first request in a minute.

Create an API key