Skip to main content

REST API Guide

This guide explains what the NativeAds REST API does and the recommended path from a brand to finished creatives. For request and response schemas, field types, and every endpoint, use the API Reference. The raw headless.yaml spec is also downloadable for Postman or Insomnia.

What NativeAds does​

NativeAds is a creative-generation platform you drive over HTTP. You manage brands, teach the system each brand’s look and voice (Brand DNA), upload product and reference assets, then generate on-brand product images and videos.

The usual path looks like this:

Brand DNA is what keeps output on-brand. You can generate without it, but results will look generic.

Get an API key​

  1. Sign in at https://app.nativeads.ai.
  2. Open Settings → Account → API Keys.
  3. Click Create, give the key a name (optional expiry), and confirm.
  4. Copy the full token immediately and store it in a secret manager. It is shown once and cannot be retrieved again.

Keys look like nak_production_<keyId>.<secret>.

A key acts as its owning user inside that user’s organization — same permissions, no more. Deleting or regenerating a key takes effect on the next request. Treat it like a password.

Base URL and authentication​

Base URL: https://creative-v1.nativeads.ai/v1

Send the key as a bearer token on every request:

Authorization: Bearer nak_production_<keyId>.<secret>

Quick smoke test — list brands:

curl https://creative-v1.nativeads.ai/v1/brands \
-H "Authorization: Bearer nak_production_<keyId>.<secret>"

A 200 with a list (even empty) means the key works. Invalid or expired keys return 401. Endpoints outside the developer surface return 403.

End-to-end workflow​

Follow the steps in order. Each step links to the matching operations in the API Reference for exact payloads. Brand DNA, prompt enhancement, image generation, and video generation are asynchronous: the create call returns a resource id immediately, then you poll that resource’s GET endpoint until it finishes.

1. Create a brand​

A brand is the container for everything about one product or company: name, industry, description, tone, and later its DNA, assets, and generations.

Create one with a name (other fields are optional), or list existing brands if you already have them.

API Reference: Create a brand · List brands · Get a brand · Update a brand

2. Upload assets​

Upload product photos, logos, environment images, brand-guideline PDFs, or videos.

Uploading is always three steps:

  1. Get an upload URL (initiate-upload) — send the file’s name, type, size, and dimensions. You get a short-lived upload URL, plus an uploadId and assetId.
  2. Upload the file — send the file to that URL. Do not send your API key here; the link already authorizes the upload and expires quickly.
  3. Confirm the upload (confirm-upload) — tell NativeAds the file is in place. NativeAds then processes it (thumbnails, checks). Poll Get asset until status is complete (or failed) before using the asset in Brand DNA or generation.

Allowed types: JPEG, PNG, GIF, TIFF, MP4, QuickTime, PDF, DOC, DOCX, and the TTF/OTF/WOFF/WOFF2 fonts (max 500 MB). SVG is not accepted — rasterise it first. For a logo, set isLogo: true in the initiate request.

API Reference: Initiate upload · Confirm upload · Cancel upload · Get asset · List brand assets

Or extract assets from a product page​

If your images are already on a public web page, you can skip uploading. Submit the page URL and NativeAds scrapes it together with up to 15 related pages on the same site (its tabs, sub-pages, galleries, sibling products and the other sections of the same catalogue), ranks what it finds by how central each image is to the page's subject, and returns candidates for review. Nothing is stored in the brand until you commit.

  1. Submit the URL — send url plus the brandId that will own the results. The call returns an extractionId; a run usually takes one to five minutes, depending on how many related pages the site has.

  2. Poll Get extraction until status is completed or failed. A completed extraction carries a candidates array, best first, each with a preview URL, a relevance score and a one-line reason. While it is still running there is no candidates key at all, so read it defensively.

    Each candidate also carries looksLikeLogo, the extractor's own guess that this one is the brand's logo. It is advisory. It is a different field from the isLogo you send at commit: that one is the user's decision and is what actually sets the asset's type. Use looksLikeLogo to pre-tick a box or to phrase the question, not to answer it.

  3. Commit the ones you want — post the candidate ids you chose. Sending an empty body commits every candidate the ranker kept, so if you are driving this from a user's selection, do not call the endpoint when nothing is selected: there is no commit-nothing request shape.

Committed candidates become normal assets, so the same rule as uploading applies: poll Get asset until status is complete before referencing one in generation. Mark a logo with isLogo: true on its first commit; because commit is idempotent, setting it later on an already-committed candidate is ignored. Asset type is fixed at creation and there is no endpoint that changes it. A logo committed as a plain image can still be committed with isLogo: true from a fresh extraction, which creates a separate logo asset; committing the same image again as a plain image returns the one already saved. Ask before you send isLogo: true.

Commit does not copy what the brand already has. A candidate whose image this brand had already saved when the commit started, as the same kind of asset (logo or not), returns that existing asset, and alreadyInLibraryCount on the response says how many of the returned assets were already there, so assets minus that count is what the commit added. The same image means the same bytes from any source, including a logo captured from an inline SVG; an image saved before this matching existed is matched by its image URL instead. A deleted asset is never reused.

To withdraw a scrape — wrong page, or media you would rather not have held — delete the extraction. That removes it and its uncommitted staged copies; anything you already committed is a normal asset and is untouched.

API Reference: Extract from URL · Get extraction · Commit candidates · Delete extraction

3. Extract and activate Brand DNA​

Brand DNA is the platform’s model of visual and verbal identity — colors, fonts, tone, audience — learned from website URLs and/or uploaded assets. Extraction is asynchronous.

Brand DNA is a paid-plan capability. On a plan that does not include it every /brands/{brandId}/brand-dna/* endpoint answers 403, reads as well as writes, as does the legacy GET /brands/{brandId}/dna. Generation is unaffected unless you ask for Brand DNA explicitly: useBrandDna: true on a plan without it is a 403, while omitting the field simply generates without Brand DNA.

  1. Create a DNA version from urls and/or assetIds (logo + brand assets + PDFs + site together work best).
  2. Poll Get DNA version until status is ready (or failed). Re-run is also async — poll the same GET after rerun.
  3. Review confidence score and any missing fields; re-run with richer sources if it’s weak.
  4. Activate the version. Creation alone does not apply it — generation only uses an active version.

You can rename or correct DNA fields, cancel an in-flight extraction, or delete a version when needed.

API Reference: Create DNA version · Get DNA version · Activate · List versions · Active version · Update · Re-run · Cancel · Delete

4. (Optional) Enhance the prompt​

Before generating, you can send a draft prompt through enhancement. The create call returns a job id immediately.

Poll until status is completed (or failed):

Then review the optimized prompt (and theme, for images) and pass it into generation with promptIsEnhanced: true. For video enhancement, Brand DNA is off by default — pass useBrandDna: true to apply it.

If the scene will use transparentBackground: true (step 5), pass transparentBackground: true to the Scene Forge enhancement too, so the optimized prompt describes the subject alone, with no setting. Like on create, it cannot be combined with environmentAssetId (400). The enhancement returns it as transparentBackground.

API Reference: Enhance Scene Forge prompt · Enhance image-to-video prompt

5. Generate a product image (Scene Forge)​

Describe the scene in plain language (for example, “a bag of coffee on a sunlit marble kitchen counter”). Optionally pass product and environment asset IDs so the real product appears in the shot.

Scene Forge applies Brand DNA by default when an active version exists and the plan includes Brand DNA; on a plan without it, an omitted useBrandDna resolves to false rather than failing. The create call returns immediately with a job id. Poll Get Scene Forge until status is completed or failed. A completed job typically yields several image variations with download URLs.

If you called prompt enhancement (step 4) and are submitting its output as blendingPrompt, also pass authoredPrompt — the text you wrote before enhancement, up to 2500 characters (over that, 400). Omit it otherwise; the server then stores blendingPrompt as the authored prompt too. The response returns authoredPrompt, which is absent (omitted) on Scene Forges created before this field existed.

Scene Forge create accepts adverteyesScoring (default false). Set it to true to have AdverEyes score that generation's variations. A scored create takes one Creative Optimization from the organization's allowance, and gives it back if none of its variations ends up with a score. When no Creative Optimization is left, a scored create is refused with 400 and error code USAGE_LIMIT_EXCEEDED (error.details.feature is creative_optimizations) and nothing starts; send false to generate unscored. Nothing is taken or refused when AdverEyes is not available to the organization. The allowance resets when the billing period does. Get Feature Usage reports it as addons.creative_optimizations (usage, cap, remaining, unlimited). Get and List return adverteyesScoring on the scene forge and adverteyesRoundInFlight on each variation, and omit both when AdverEyes is not available to the organization. Scoring a single variation on demand is available in the web app only.

Set transparentBackground: true to render the subject alone on a transparent background, with no backdrop: each variation is a PNG with an alpha channel, ready to place on a layout. It cannot be combined with environmentAssetId (400). Extending or refining the scene forge keeps it, and Get and List return it as transparentBackground.

API Reference: Create Scene Forge · Get Scene Forge · List Scene Forges

6. Generate video​

Video takes frames or reference images, and the model you send decides which is legal. Always send model explicitly: an omitted value resolves to seedance-2.0-pro today, and the default may change.

A new video accepts six models, each with an exact list of lengths. duration must be one of them; omitted, it is the model's default.

modelduration (seconds)
optimizedthe lengths of the model it renders on for your plan (below); default 8
seedance-2.5-pro6, 8, 10, 15, 20, 30, within your plan's Seedance 2.5 limits (below)
seedance-2.0-pro6, 8, 10, 12, 15
kling-v3-omni-pro6, 8, 10, 12, 15, 20, 30; 20 and 30 need intermediate frames (below)
veo-3.16, 8
grok-imagine-video6, 8, 10, 12, 15

Any other model, including the legacy veo-3.1-fast, kling-v3-pro, seedance-1.5-pro and pixverse-v6, and any length not in the model's row, is refused with 400 before anything starts. Prompt enhancement checks the same. Videos already made on a legacy model still read back with that model.

resolution is optional: 720p (the default) or 1080p. Starter makes 720p only, and 1080p there is refused with 403. Pro and Ultra may send either. The video group returns the resolution it was made at. A group created before resolutions were recorded omits it until its first extend, which records the plan's default resolution it renders and bills at.

Each video is billed video credits from your plan's video allowance, by model, length and resolution. Most videos cost 1. A request makes one video per prompt and bills the sum over its prompts. Get Feature Usage counts video usage in these credits, and its video_options returns this table for your plan: resolutions, your plan's resolutions with the default first, and units, by model, then resolution, then length in seconds. units lists only the models, lengths and resolutions your plan may request. A blank cell means the model does not take that length, and the 1080p rows apply on Pro and Ultra.

An optimized video costs what its render model costs at that length and resolution.

modelResolution6s8s10s12s15s20s30s
seedance-2.5-pro720p111234
seedance-2.5-pro1080p2335710
seedance-2.0-pro720p11111
seedance-2.0-pro1080p11222
kling-v3-omni-pro720p1111112
kling-v3-omni-pro1080p1111112
veo-3.1720p12
veo-3.11080p12
grok-imagine-video720p11111
grok-imagine-video1080p11112

Start-frame models turn a single still into motion. Provide a start-frame asset (often a Scene Forge output), a prompt, and dimensions; optional end or intermediate frames, duration and audio depend on the model. Only kling-v3-omni-pro takes intermediateImageAssetIds, with a start frame and exactly one prompt; they make a longer video of several clips. Their number is bounded by duration: up to 1 at 6s and 8s, 2 at 10s and 12s, 3 at 15s, and 20s and 30s require 1 to 4 and 1 to 5 respectively. Every other model, optimized included, refuses them with 400. The start-frame asset must be complete.

optimized renders on your plan's default model, today seedance-2.0-pro on Starter and seedance-2.5-pro on Pro and Ultra, and takes that model's inputs, lengths and price. On Starter that is a start frame (optional end frame) or 1 to 9 reference images. On Pro it is 1 to 15 reference images and no reference videos; more than 15 images, or any reference video, fails with 403 (explicit seedance-2.5-pro on Pro takes 30 images). On Ultra it is seedance-2.5-pro's Ultra limits below. Responses keep showing optimized, and so do errors: a refused optimized request names optimized, never the model behind it (for example Duration 20s is not supported by optimized on this plan), with the same 400 or 403 as an explicit model. Earlier optimized videos rendered on Kling; they still read as optimized and extend on Kling.

seedance-2.5-pro is reference-to-video. It takes a set of reference images and/or videos rather than frames:

  • Pass referenceImageAssetIds and/or referenceVideoAssetIds — at least one reference in total.
  • It rejects startImageAssetId, endImageAssetId and intermediateImageAssetIds.
  • A reference image only needs status uploaded, not complete. It must be JPEG or PNG, 30MB or smaller, and an image, logo or environment asset.
  • Reference videos are MP4 or QuickTime, 200MB or smaller, 2-30s each and 30s combined.
  • A reference video's dimensions, when we know them, must satisfy both model rules: a pixel count (width × height) of 407,696-8,295,044, and an aspect ratio (width / height) of 0.4-2.5. They are independent — 1400x300 is 420,000 pixels, inside the band, and is still refused on its 4.67 ratio. 640x480 fails the pixel count; DCI-4K 4096x2160 exceeds it. A video whose dimensions were never measured skips both checks rather than being rejected. We only know the size if it was declared at upload or measured by our post-upload probe; a video whose dimensions were never captured skips the check rather than being rejected.
  • What it may use depends on your plan. Over your plan the request fails with 403 rather than being trimmed.
Planseedance-2.5-proReference imagesReference videosLongest duration
Starternot available
Proyesup to 30none15s
Ultrayesup to 30up to 1030s

seedance-2.0-pro and kling-v3-omni-pro take a start frame or reference images, never both.

  • Frames: startImageAssetId, with an optional endImageAssetId, as for the start-frame models above.
  • References: referenceImageAssetIds with no start, end or intermediate frame. Up to 9 images on seedance-2.0-pro and up to 7 on kling-v3-omni-pro, on every plan. Plan-tier narrowing applies to seedance-2.5-pro only.
  • A frame and references together fail with 400, and so does a request with neither (startImageAssetId is required).
  • Neither model takes referenceVideoAssetIds.
  • A reference image follows the seedance-2.5-pro image rules above. kling-v3-omni-pro allows up to 50MB instead of 30MB, and when we recorded the image's dimensions it must also have an aspect ratio (width / height) between 0.4 and 2.5. An image with no recorded dimensions skips that check.

Every other model takes a start frame and rejects both reference fields. grok-imagine-video renders from the start frame only, so an endImageAssetId fails with 400.

Unlike Scene Forge, Brand DNA is off by default for video — pass useBrandDna: true when you want it applied. The create call returns a group id immediately. Poll Get video group until status is completed or failed, then download the video assets.

On a group with no start frame (every seedance-2.5-pro group, and a seedance-2.0-pro or kling-v3-omni-pro group sent with references), sourceAsset is null. Each variation's previewUrl is a still of the output when the pipeline saved one, otherwise null. It is never one of your reference images. Your inputs come back under referenceImageAssets and referenceVideoAssets, in the order you sent them.

If you called prompt enhancement (step 4) and are submitting its output, also pass authoredPrompts — an array parallel to userPrompts, each entry up to 5000 characters (over that, 400) — with the text you wrote before enhancement, at the same index. If you send it, it must be the same length as userPrompts, or the request fails with 400. An empty entry, or omitting the array, makes the server store that entry's userPrompts text as its authored prompt instead. Each group in the response carries authoredPrompt, which is absent (omitted) on groups created before this field existed.

API Reference: Generate video · Get video group · List video groups

7. (Optional) Upscale an image​

Upscale needs the Pro or Ultra plan, or Upscale enabled for your organization. On Starter, creating an upscale fails with 403 and nothing is charged; reading and deleting existing upscale groups still works. gated_features.upscale on GET /organizations/current/feature-usage says whether you have it.

Upscale enlarges one image asset to up to 4 sizes in one request, one output per size. Each output is a PNG with the source's aspect ratio. Send the source as source_asset_id and the sizes as targets:

  • {"mode": "factor", "value": 2} enlarges by 2, 3 or 4.
  • {"mode": "long_edge", "value": 4096} enlarges until the longer side is that many pixels.

A size is accepted only when it enlarges the image by more than 1x and at most 4x, its longer side is at most 8192 px, and the source's longer side is between 256 and 8192 px. Two sizes that come out the same in one request fail with 400. When a size is refused, the message gives the range this source allows.

Print size raises the output limit to 16384 px on the longer side. It comes with the Pro and Ultra plans, or when it is enabled for your organization. Without it, a request with any size above 8192 px fails with 403, and nothing is charged.

The source must be an image asset of the brand with status complete: a PNG, JPEG or WebP upload, or an image generated on the platform. Each output counts against the organization's images allowance by its size: 1 up to 24 MP, 2 up to 48 MP, 4 up to 96 MP, and 11 above that (print size, up to 268.4 MP). The whole request is charged when it is accepted, and a failed output is given back. When the allowance cannot cover the request, it fails with 400 and error code USAGE_LIMIT_EXCEEDED, and nothing starts.

The create call returns the group with every output pending. Poll Get upscale group until its status is completed (at least one output finished) or failed (every output failed). A finished output carries its asset with a download url. Upscaled images are not listed among the brand's assets: reach them through the group, or list the brand's groups.

Deleting a group or one output removes it from every response. An output that is still processing keeps running, and its usage is not given back.

API Reference: Create upscale group · Get upscale group · List upscale groups · Delete upscale group · Delete upscale output

Endpoints not available to keys​

API keys are limited to the developer surface. Not available to keys: brand deletion, asset deletion, API-key management, campaign/theme generation, trends, Walmart-creative submission, and upscaling an image inside a generation (POST /brands/{brandId}/upscale; use an upscale group, step 7). Those remain available to signed-in users in the app.

Troubleshooting​

SymptomWhat to check
401Missing Bearer prefix, mistyped key, or expired/revoked key
400 on video or prompt enhancementThe model is not one a new video accepts (the legacy veo-3.1-fast, kling-v3-pro, seedance-1.5-pro, pixverse-v6), or duration is not in that model's list (step 6)
403Endpoint is outside the key’s developer surface, or the feature needs a higher plan (including seedance-2.5-pro on Starter, more seedance-2.5-pro references or a longer duration than your plan allows, Upscale on Starter, and an upscale above 8192 px without print size)
422An input asset is not ready. A start-frame asset must be complete; a reference image needs only uploaded
400 on upscaleA size outside what this source allows (the message gives the range), two sizes that come out the same, more than 4 sizes, a source that is not an image or whose longer side is under 256 px, or a source with no recorded dimensions (re-upload the image). USAGE_LIMIT_EXCEEDED means the images allowance cannot cover the request (step 7)
422 on upscaleThe source image is still being processed. Nothing is charged; retry shortly
Job never finishesStop polling; GET the resource once and read status / error fields
Weak or off-brand outputConfirm Brand DNA is active, and that generation requested DNA where required (especially video)
Asset / DNA / generation rejects an idConfirm the asset status is complete before referencing it (reference images also accept uploaded)

Next steps​

  • API Reference — full schemas and every operation a key can call
  • MCP Guide — same capabilities as tools for Claude, Cursor, ChatGPT, and custom clients
  • MCP Tool Catalog — tool-by-tool map of the workflow above