# Neurall > Neurall is a creative API and studio offering curated, composite AI endpoints > that produce finished creative assets in a single call: cinematic logo reveal > clips, studio-quality headshots from a user's own photos, and a growing set of > flagship creative endpoints, plus utility operations (upscale, background > removal). Flat per-call pricing from a prepaid money wallet. Async job API > with webhooks and signed CDN output URLs. An MCP server exposes every > endpoint as an agent-callable tool. Key facts: - Endpoints are recipes (e.g. "logo-reveal"), not model names. Pricing is flat per generation. - All generation is asynchronous: submit a job, poll or receive a webhook, download the output. - Headshots generate images of the user themselves from their own photos, consent-framed, with attestation and AI disclosure. - No free tier. Prepaid balance, no watermark on outputs, full commercial rights. ## Pages - [Home](https://neurall.io/): overview and showcase - [Logo Reveal](https://neurall.io/logo-reveal): cinematic intro clip from a flat logo, template gallery and pricing - [Avatar Video](https://neurall.io/avatar-video): a talking video from one still image, works on people, characters, animals and paintings - [Self-Portrait](https://neurall.io/self-portrait): studio portraits of yourself from a single photo, at 4K, with no training step - [YouTube Thumbnail](https://neurall.io/youtube-thumbnail): a thumbnail built from the video's own transcript, starring your real face - [Product Shot](https://neurall.io/product-shot): a product photo restaged into a new scene, the product itself reproduced exactly - [Docs](https://neurall.io/docs): developer overview, API shape, MCP server - [MCP](https://neurall.io/mcp): connecting an agent, the config block and the tool list - [App](https://app.neurall.io/): sign up, API keys, generation, billing - [Terms](https://neurall.io/terms): prepaid balance, refunds, output ownership, consent rules, liability - [Privacy](https://neurall.io/privacy): what is collected, the 24 hour deletion clock, processors, your rights # Neurall API reference Generated from the live OpenAPI contract at https://api.neurall.io/v3/openapi.json. Every call authenticates with an API key in the Authorization header and is scoped to that key's project. # Generations Submit a generation and collect the finished asset. Every feature in the platform runs through this one collection. Base URL: https://api.neurall.io. Authenticate with `Authorization: nl-YOUR_API_KEY`. ### List Generations `GET /v3/generations` The project's generations, newest first, keyset-paginated via `cursor`. Use it to recover ids you lost (a process that crashed between submitting and recording the id can find its work here) and to show recent activity in your own dashboard. It is NOT an archive: a generation created through the API drops out of this list once its `expiresAt` passes, 24 hours after the request, so treat it as a window on the last day rather than as storage. ```bash curl -X GET "https://api.neurall.io/v3/generations" \ -H "Authorization: nl-YOUR_API_KEY" ``` **Query** - `feature` (string): Only generations for one feature, e.g. `video/logo-reveal`. The legacy flat spelling is accepted too and matches the same rows. - `limit` (integer): Generations per page. Defaults to 24, and anything above 100 is clamped to 100 rather than rejected. - `cursor` (string): The `nextCursor` of the previous page **Responses** - `200`: One page of generations - `generations` (object[]): An async generation. `status` moves from `pending` through `running` to `done`, `error` or `timeout`; once done, `output` holds the asset as a signed URL named by the kind (image, video or audio) plus its `mime`. - `nextCursor` (string): Pass it back as `?cursor=` for the next page; null on the last one. Example: ```json { "generations": [ { "id": "9f2c1d84-6a3b-4f21-9c77-2f0a1b8e5d43", "feature": "image/self-portrait", "kind": "image", "status": "done", "output": { "image": "https://cdn.neurall.io/…/image.png", "mime": "image/png" }, "balanceUsed": 0.05, "requestDate": "2026-08-25T17:04:12.000Z", "responseDate": "2026-08-25T17:04:41.000Z", "expiresAt": "2026-08-26T17:04:12.000Z" } ], "nextCursor": null } ``` - `401`: Unauthorized ### Create Generation `POST /v3/generations` Submits an async generation and returns immediately with status `pending`. Poll GET /v3/generations/{id} until the status is terminal, then read `output`, or pass `webhookUrl` to be notified instead (polling still works as a fallback). ```bash curl -X POST "https://api.neurall.io/v3/generations" \ -H "Authorization: nl-YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "feature": "", "args": { }, "webhookUrl": "" }' ``` **Body** - `feature` (string, required): The generation feature to run, namespaced by output kind ('/'). The pre-namespacing flat spellings (e.g. image-generation, logo-reveal) are still accepted. One of: `image/self-portrait`, `image/generation`, `image/product-shot`, `image/youtube-thumbnail`, `image/ad`, `video/logo-reveal`, `video/object-reveal`, `video/avatar`, `audio/voiceover`. - `args` (object, required): Feature-specific inputs. Reference images and audio are file ids from /v3/files/upload. Every input is validated before the generation is accepted or billed; a file that fails answers a descriptive 400 and nothing is charged. Each feature's own docs page lists its arguments, formats and size caps. - `webhookUrl` (string): Optional https URL to POST the finished generation to when it reaches a terminal status (done / error / timeout). Deliveries are always signed with your project's webhook secret, revealed on the playground's API Keys page. Delivery is best-effort with a brief retry; polling remains authoritative. **Responses** - `200`: The pending generation - `generation` (object): An async generation. `status` moves from `pending` through `running` to `done`, `error` or `timeout`; once done, `output` holds the asset as a signed URL named by the kind (image, video or audio) plus its `mime`. Example: ```json { "generation": { "id": "9f2c1d84-6a3b-4f21-9c77-2f0a1b8e5d43", "projectId": "3e8b2f60-91c4-4d7a-8f02-6b1de0a97c55", "feature": "image/self-portrait", "kind": "image", "status": "pending", "params": { "image": "f_9c21e0b4", "prompt": "Cinematic studio portrait, moody side light against a deep grey backdrop.", "aspectRatio": "3:4" }, "balanceUsed": 0.05, "requestDate": "2026-08-25T17:04:12.000Z", "expiresAt": "2026-08-26T17:04:12.000Z" } } ``` - `400`: Bad request (unknown feature, invalid args) - `401`: Unauthorized - `402`: Insufficient balance ### Get Generation `GET /v3/generations/{id}` The one call you make after submitting: poll it every few seconds (5 to 10 for the minute-scale renders: video, voice cloning) until `status` leaves `pending` and `running`, then read `output`. Statuses are `pending`, `running`, `done`, `error` and `timeout`; loop while the status is one of the first two rather than waiting for `done`, or a failed generation spins forever. The asset in `output` (`image`, `video` or `audio`, named by the generation's kind) is a signed URL you should download, NOT a permanent address: a generation created through the API is reaped at `expiresAt`, 24 hours after the request, and this call then answers 404 as though the generation never existed. ```bash curl -X GET "https://api.neurall.io/v3/generations/" \ -H "Authorization: nl-YOUR_API_KEY" ``` **Path** - `id` (string, required): The generation id returned by POST /v3/generations. **Responses** - `200`: The generation - `generation` (object): An async generation. `status` moves from `pending` through `running` to `done`, `error` or `timeout`; once done, `output` holds the asset as a signed URL named by the kind (image, video or audio) plus its `mime`. Example: ```json { "generation": { "id": "9f2c1d84-6a3b-4f21-9c77-2f0a1b8e5d43", "projectId": "3e8b2f60-91c4-4d7a-8f02-6b1de0a97c55", "feature": "image/self-portrait", "kind": "image", "status": "done", "params": { "image": "f_9c21e0b4", "prompt": "Cinematic studio portrait, moody side light against a deep grey backdrop.", "aspectRatio": "3:4" }, "output": { "image": "https://cdn.neurall.io/…/image.png", "mime": "image/png" }, "balanceUsed": 0.05, "requestDate": "2026-08-25T17:04:12.000Z", "responseDate": "2026-08-25T17:04:41.000Z", "expiresAt": "2026-08-26T17:04:12.000Z" } } ``` - `401`: Unauthorized - `404`: Generation not found ### Delete Generation `DELETE /v3/generations/{id}` Removes the generation and its rendered assets now, instead of waiting for the 24 hour expiry to do it. Reach for this when something has to be gone on request rather than on schedule: a user withdrew consent, or a render came back wrong and you do not want it reachable while your retry runs. It does not refund anything, since the render already happened, and it cannot cancel work that is still in flight. ```bash curl -X DELETE "https://api.neurall.io/v3/generations/" \ -H "Authorization: nl-YOUR_API_KEY" ``` **Path** - `id` (string, required): The generation id returned by POST /v3/generations. **Responses** - `200`: Deleted - `success` (boolean) Example: ```json { "success": true } ``` - `401`: Unauthorized - `404`: Generation not found # Voices Every voice you can speak with, in one collection: the ready-made Neurall catalog, plus the voices you clone yourself. Cloning posts here rather than to generations, because what comes back is a reusable id and not a file. Base URL: https://api.neurall.io. Authenticate with `Authorization: nl-YOUR_API_KEY`. ### List Voices `GET /v3/voices` Every voice this project can speak with: its own cloned voices first (`owner: project`), then the Neurall catalog (`owner: neurall`), which is ready-made and identical for every caller. Filter with `?owner=`. Pass a voice's `id` (or a catalog `slug`, the stable handle worth hardcoding) as `args.voiceId` in an audio/voiceover or video/avatar generation. `preview` is a presigned audition clip on catalog voices and expires after ~6 hours; a clone carries a `status` instead, until it is `done`. ```bash curl -X GET "https://api.neurall.io/v3/voices" \ -H "Authorization: nl-YOUR_API_KEY" ``` **Query** - `owner` ('neurall' | 'project'): `project` for this project's own clones, `neurall` for the ready-made catalog. Omit for both. Anything else is a 400. `tag` and `locale` describe catalog rows only, so they are ignored on clones rather than silently hiding them. - `tag` (string[]): Only voices carrying ALL of these tags. May repeat (?tag=female&tag=warm). Tags are lowercase descriptors: gender, age, accent, style, plus the category (narration, conversational, character, creature). - `locale` (string): Only voices recorded for one locale, matched exactly against the voice's own `locale` (e.g. `en-US`). It is not a prefix: `en` returns nothing. **Responses** - `200`: This project's clones, then the published catalog - `voices` (object[]): A voice this project can speak with. `owner: neurall` is a catalog voice, ready to use and identical for every caller. `owner: project` is one of the project's own clones, which carries the same status lifecycle as a Generation while it trains. A voice's own id is what goes in `args.voiceId`. Example: ```json { "voices": [ { "id": "d77c4b2e-5a90-4f13-b8c6-1e2f3a4b5c6d", "owner": "project", "status": "done", "name": "Founder voice" }, { "id": "5b3a9d10-2c47-4e8f-a6b1-9d0c3e7f2a84", "owner": "neurall", "slug": "aria", "name": "Aria", "tags": [ "female", "warm", "narration" ], "locale": "en-US", "favorite": false, "preview": "https://cdn.neurall.io/…/aria-preview.mp3" } ] } ``` - `401`: Unauthorized ### Clone a Voice `POST /v3/voices` Clone a voice from an audio sample: upload about thirty seconds of clean speech to /v3/files/upload, then POST its file id here. Returns immediately with `status: running`; poll GET /v3/voices/{id} until it is `done`, or pass `webhookUrl` and be told. The id you get back IS the voiceId, usable in `args.voiceId` on audio/voiceover and video/avatar. Charged on submit like a generation, refunded on error or timeout. An organization may have 5 voices training at once. ```bash curl -X POST "https://api.neurall.io/v3/voices" \ -H "Authorization: nl-YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "", "audio": "