For developers

NAX API

Create photoreal AI video from your own backend. The API runs the exact same rendering pipeline, credit pricing and content safety as the Studio — everything you generate lands in your Library, watermark-free.

Start here

Overview

The NAX API is a small, predictable REST surface: create a render, poll it, download the file. There is no SDK to install and no webhook to configure — every call is plain HTTPS with a JSON body and a bearer key.

PropertyValue
Base URLhttps://naxaigc.com/api/public/v1
AuthAuthorization: Bearer nax_live_…
Content typeapplication/json (UTF-8)
Aspect ratios9:16 (vertical) · 16:9 (landscape)
Length8–64 seconds, in 8-second clips
Resolutions720p · 1080p · 2K · 4K
OutputMP4, H.264, with sound, no watermark
BillingCredits from the key owner's own balance

Everything the API produces is also visible in the Studio Library for the same account, so your team can review, re-download or reuse renders that your code created.

Core concepts

Render. One job. It holds your brief, the format, the credits charged, its status and — once finished — the video file.

Clip. Video is generated in 8-second clips. A 32-second render is four chained clips, each continuing the subject, wardrobe and location of the one before it. This is why duration must be a multiple of 8.

Engine. The quality/price tier of the generator:

EngineBest forCredits per 5s
nax-cineHero ads, faces, cinematic realism140
nax-flowEveryday social content, fast turnaround45
nax-draftCheap previews and storyboard tests16
nax-i2vAnimating a still image or product photo60
nax-ultraNAX Ultra — flagship realism, our most lifelike people & motion320

Credit. The single unit of billing across Studio, NAX Mode and the API — about RM 0.25 each. Every account also receives 50 free credits every day (08:00 Malaysia time, no rollover), and free credits are always spent before paid ones.

Keys & authentication

Sign in and open Studio → Developer API to create a key. Keys look like nax_live_… and the full value is shown only once, at creation — we store only a one-way fingerprint, so nobody (including us) can read your key back afterwards.

Every request
Authorization: Bearer nax_live_your_key

Each key belongs to exactly one account and can only spend that account's credits and read that account's renders. You may hold several keys — one per app or environment — and Rename, Reset (rotate) or Revoke any of them at any time. Revoking takes effect immediately on the next call.

Quickstart

Start a 16-second vertical render, then poll it until the file is ready.

1 · Start a render (curl)
curl -X POST https://naxaigc.com/api/public/v1/videos \
  -H "Authorization: Bearer nax_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A barista pours latte art in a sunlit Penang kopitiam, handheld camera, morning ambience",
    "aspect": "9:16",
    "duration": 16,
    "resolution": "1080p",
    "engine": "nax-cine",
    "language": "Bahasa Melayu",
    "title": "Kopitiam morning"
  }'

# → { "id": "…", "status": "rendering", "credits": 450, "clips": 2,
#     "poll_url": "/api/public/v1/videos/…" }
2 · Poll until complete (Node.js)
const key = process.env.NAX_API_KEY;
const headers = { Authorization: `Bearer ${key}` };

const start = await fetch("https://naxaigc.com/api/public/v1/videos", {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({ prompt: "…", aspect: "9:16", duration: 16 }),
}).then((r) => r.json());

let render = start;
while (render.status === "rendering" || render.status === "queued") {
  await new Promise((r) => setTimeout(r, 8000)); // poll every 5–10s
  render = await fetch(`https://naxaigc.com/api/public/v1/videos/${start.id}`, { headers })
    .then((r) => r.json());
  console.log(render.status, render.progress + "%");
}

if (render.status === "completed") console.log(render.download_url);
Same flow in Python
import os, time, requests

H = {"Authorization": f"Bearer {os.environ['NAX_API_KEY']}"}
B = "https://naxaigc.com/api/public/v1"

job = requests.post(f"{B}/videos", headers=H, json={
    "prompt": "…", "aspect": "16:9", "duration": 24, "resolution": "1080p",
}).json()

while True:
    r = requests.get(f"{B}/videos/{job['id']}", headers=H).json()
    if r["status"] in ("completed", "failed"):
        break
    print(r["status"], r.get("progress"))
    time.sleep(8)

print(r.get("download_url"))
Check your balance first (PHP)
$ch = curl_init("https://naxaigc.com/api/public/v1/credits");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("NAX_API_KEY")],
]);
$balance = json_decode(curl_exec($ch), true);
// → ["paid_credits" => 1200, "free_credits" => 50, "total_credits" => 1250, …]

Endpoints

POST/api/public/v1/videos

Starts a render and charges credits at Studio rates. Returns the render id, the credits taken, the number of clips and a poll URL. A rejected request costs nothing.

GET/api/public/v1/videos/{id}

Poll every 5–10 seconds. Each poll also advances the clip chain on long renders, so keep polling to completion. Ids belonging to another account return 404.

GET/api/public/v1/renders

Your 50 most recent renders with status, format, credits and poll links.

GET/api/public/v1/credits

Live balance: paid credits, free daily credits, total, plan and account standing.

Any other method on these paths returns 405 method_not_allowed — for example a browser GET on the create-video path will never fall through to the website.

Parameter reference

POST /v1/videos — request body

FieldTypeRequiredNotes
promptstringyes1–900 characters. The brief: subject, action, setting, camera, mood.
aspect"9:16" | "16:9"yesVertical or landscape.
durationintegeryesSeconds. Multiple of 8, from 8 to 64.
resolutionstringno720p · 1080p · 2K · 4K. Default 1080p.
enginestringnonax-cine · nax-flow · nax-draft · nax-i2v · nax-ultra. Default nax-draft (cheapest).
languagestringnoSpoken language: English · Bahasa Melayu · Mandarin.
stylestringnoLook and grade, e.g. "warm documentary, 35mm".
titlestringnoName shown in your Library.
hookstringnoOpening line or on-screen hook, up to 500 characters.

Render object — response fields

FieldTypeNotes
idstringRender id. Use it to poll and to find the item in your Library.
statusstringqueued · rendering · completed · failed.
progressinteger0–100, rises as clips finish.
creditsnumberCredits charged to your account for this render.
clipsintegerHow many 8-second clips make up the render.
durationintegerFinished length in seconds.
aspectstring9:16 or 16:9.
download_urlstring | nullSigned MP4 link, present once completed.
poll_urlstringRelative path to poll this render.
errorstring | nullWhy a failed render stopped.

Render lifecycle

Status flow
queued ──▶ rendering ──▶ completed
                  │
                  └────────▶ failed  (credits for unproduced clips are refunded)

Rough timings: a single 8-second clip usually lands in 1–3 minutes; a 64-second chain can take 15–25 minutes because clips are produced in sequence for continuity. Poll every 5–10 seconds and let long jobs run — there is no cost to polling.

If your process dies mid-job, nothing is lost: call GET /v1/renders to find the render again and resume polling.

Downloads & storage

download_url is a signed link to an MP4 with sound and no watermark. Links are time-limited (a few hours) — re-poll the render to get a fresh one, and copy the file into your own storage if you need a permanent URL.

Files stay in your account Library so you can re-download later from the Studio or from GET /v1/renders. You own the commercial rights to what you generate, subject to our terms.

Credits & pricing

API renders are priced exactly like Studio renders: engine rate × length × resolution multiplier, plus a small amount for voice. Resolution multipliers are 720p ×0.8 · 1080p ×1 · 2K ×1.4 · 4K ×2.

Example (16s, with sound)EngineCredits
Cinematic hero ad, 1080pnax-cine450
Everyday social clip, 1080pnax-flow146
Draft preview, 720pnax-draft43

Credits are taken when the render starts, never before. Rejected requests cost nothing, failed clips are refunded automatically, and a clip that comes back shorter than billed is refunded the difference. Check the balance any time with GET /v1/credits; top up from Studio → Credits & plan.

Errors

Every error returns { "error": { "code", "message" } } with a matching HTTP status.

StatusCodeWhat to do
400invalid_request · bad_json · invalid_durationCheck the field named in the message; duration must be a multiple of 8.
401missing_key · invalid_keyThe key is absent, mistyped, rotated or revoked. Create a new one.
402insufficient_creditsTop up, or wait for the daily free credits to reset at 08:00 MYT.
403account_suspendedThe account is suspended — contact support.
403sub_account_not_allowedThe API is a main-account capability; ask your administrator.
404not_foundThat render id does not belong to your account.
405method_not_allowedWrong HTTP method for the path.
422content_blockedThe brief was rejected by content safety. Nothing was charged.
429rate_limitedToo many renders in flight. Retry after the delay in the response.
503maintenanceThe feature is temporarily switched off. Retry shortly.

Retry 429 and 503 with backoff. Never retry 400, 401 or 422 unchanged — the result will not differ.

Rate limits

Up to three renders may be in flight per account at once; a fourth returns 429. Polling is unlimited but 5–10 second intervals are plenty — anything faster just wastes your own requests.

For batch work, keep a queue on your side, run three jobs at a time, and start the next when one completes. Higher concurrency for volume pipelines is available on request.

Content safety

Every brief is screened before a single credit is spent. Sexual or adult material, and content intended to deceive, defraud, impersonate a real person without consent, or promote violence and illegal activity, is refused with 422 content_blocked and charged nothing.

If you generate a person's likeness, you must hold that person's consent. Screening runs on our servers and cannot be disabled by any request field.

Security practices

Call the API only from your server. A key in a mobile app, browser bundle or public repository can be used by anyone who finds it, and it spends your credits.

Keep keys in environment variables or a secret manager, use a separate key per app and environment, rotate with Reset if a key may have leaked, and revoke keys you no longer use. Requests must be HTTPS; plain HTTP is refused.

Your account administrator can see every key on the account with its last use, call count, credits spent and error count, and can revoke any key — or all of them — instantly.

Accounts & isolation

Keys are strictly scoped to the account that created them. A key reads only that account's renders and balance, and every charge and refund lands on that account. There is no shared pool: one team's API usage can never consume another team's credits.

Company sub-accounts use the Studio and NAX Mode, but not the API — the developer key belongs to the main account, which keeps billing and audit in one place.

FAQ

Is there a sandbox? Use nax-draft at 720p for cheap end-to-end tests — the same flow, a fraction of the credits.

Are there webhooks? Not yet; poll the render. Tell us if callbacks would help your pipeline.

Is the video watermarked? No. API output is clean at every resolution.

Can I generate images or voice over the API? Video and balance endpoints are live today; image and voice endpoints are on the roadmap — both are already available in the Studio.

Will the API change under me? The path is versioned (/v1/). New fields may be added, but existing fields will not change meaning inside a version.

Where do I get help? support@nax.com.my or the support page. Include the render id — it identifies everything we need.

Ready to build?

Create a key and your first render is a minute away — every account gets 50 free credits daily.

The signed-in reference adds copyable samples and live key management.