API reference

The Licensed Likeness API

Generate with real, licensed people. Mirai checks the selected model's terms on every call, keeps drafts watermarked and records each licence. Version 1.0.0.

Base URL
https://mirai.inc/api/v1
Auth
Authorization: Bearer mirai_sk_…

Manage keys in your brand account. API usage requires generation entitlement and follows the same watermark and licence rules as Studio. Character APIs below are experimental and disabled by default, not a live third-party catalogue.

Roster

The bookable model roster and per-model character sheets.

GET/modelsscope: read

List the bookable model roster

Public-safe fields only, no reference photos, likeness configuration, earnings, or contact details. Only models who are signed, available, have granted partner-distribution consent and have a complete six-photo reference kit appear; anyone else is omitted entirely rather than flagged. Each entry carries the model's binding restrictions (excluded_categories, excluded_brands, restricted_regions) so an integrator can refuse an out-of-scope brief before writing it, and references_available, which is false unless the reference lane is open for your key and that model. lanes.references says whether the reference lane is open for your key at all. The response also carries approved_renderers, the exhaustive list of engines a likeness may be sent to.

60/min per key

GET/models/{id}/referencesscope: read

Short-lived reference URLs for a consented model

Closed by default. Available only to a partner with a signed partner agreement that covers rendering on its own infrastructure, for a model whose consent covers the same; otherwise every call returns 403 references_lane_closed, and the lanes where Mirai renders (POST /generate, POST /briefs) are the ones to use. When open, returns signed, expiring proxy URLs to the model's canonical reference kit, for feeding into an APPROVED renderer as identity references. Both renderer and brand are required; category is required for a model with excluded categories, and brand_country for a model with territory restrictions: the declared renderer must be on the approved list (the 400 response enumerates it), and the declared brand is checked against the model's exclusions before anything is served, a brand they have excluded is refused outright. URLs expire in 15 minutes, every fetch is logged, and revocation applies to already-issued URLs immediately. The response carries their binding restrictions; they travel with the references.

60/min per key

Parameters
idrequiredstring (path)
rendererrequiredstring (query)The exact endpoint id these references will be used with, e.g. bytedance/seedream/v5/pro/edit. Must be on the approved-renderer list; anything else is refused with the list attached.
brandrequiredstring (query)The brand this shoot is for. Checked against the model's excluded brands before any reference is issued.
categorystring (query)The product category of the shoot. Required when the model has excluded categories, and checked against them.
brand_countrystring (query)Two-letter country code where the brand is based. Required when the model has territory restrictions, and checked against them.
GET/characters/{modelId}scope: read

Fetch a roster model's character sheet

The structured identity profile distilled at model approval, appearance descriptors, delivery notes, categories, for writing prompts that stay coherent with the real person. Visibility matches GET /models: only bookable models exist; unknown and unavailable ids 404 identically. A roster model without a sheet yet also 404s with code character_sheet_not_ready, the sheet is enrichment, built at approval time.

60/min per key

Parameters
modelIdrequiredstring (path)Model id from GET /models.

Generation

Create draft images and video clips.

POST/generatescope: generate

Generate a draft image with a model's AI likeness

Renders a watermarked draft anchored to the model's canonical identity kit. Sparse prompts are automatically enhanced; every prompt receives Mirai's editorial house style and passes a safety scan before delivery. Streaming transport: generation takes 1-5 minutes, so once it starts the HTTP status is ALWAYS 200 and the body streams heartbeat whitespace until the final JSON. Read the full body, then JSON.parse it (leading whitespace is valid JSON) and check for an error field before treating it as success. Pre-flight failures (auth, validation, entitlement) return real 4xx statuses with JSON bodies. Supports the Idempotency-Key header.

20/min per key, 40/min per brand

Parameters
Idempotency-Keystring (header)Any string unique to this logical request. Retries with the same key replay the stored result instead of re-rendering.
POST/videosscope: generate

Animate one of your generated images into a video clip

Starts an image-to-video render (Seedance 2.0; face-reveal prompts route to Kling v3 Pro with the model's canonical headshot as an identity anchor; both engines are named in the Model Release). The source is the asset_id of one of YOUR generated images, raw URLs are not accepted. Open-IP sources: when the source asset came from POST /ip/{slug}/generate, the render follows the character sheet instead of the fashion pipeline, the sheet's Seedance motion notes are the default motion direction (your prompt overrides them), the era style lock replaces the photorealism clause, and the sheet's legal exclusions are enforced in the prompt. Async contract: responds 202 immediately with an asset_id. Poll GET /assets/{asset_id} until status leaves processing (typically 1-5 minutes): ready delivers the watermarked draft_url; failed carries an error message and nothing was billed. Billing: on Starter, Growth and Scale a clip is paid from your monthly credits, priced by its length (see Billing); Starter does not include video, and a prepaid video credit pack covers a clip when credits do not. Enterprise follows its order form. A failed render refunds any credit consumed. Supports the Idempotency-Key header, a replay returns the SAME asset_id.

6/min per key, 10/min per brand

Parameters
Idempotency-Keystring (header)Any string unique to this logical request. A replay returns the same 202 body (same asset_id) instead of starting a second render.
GET/usagescope: read

Credits used and remaining this period

Starter, Growth and Scale pay for API generations from the account's monthly credits (see Billing). billing: credits returns credits_monthly, credits_used and credits_remaining for the current period. Enterprise accounts return billing: enterprise (not credit-metered; usage follows the order form) and accounts without a subscription return billing: none.

Response 200
billingrequiredcredits | enterprise | none
planstring,null
statusstring
credits_monthlyinteger
credits_usedinteger
credits_remaininginteger
period_startstring,null
period_endstring,null

Licensing

License approved assets for commercial use via Stripe Checkout.

POST/usagescope: license

Record a licence for an image a partner rendered on its own pipeline

Approved generation partners only. Report each delivered asset here. Print, Print + OOH and Digital + OOH are recorded here like digital (at her print rate, and a region may be named) when the talent has print on demand switched on and has accepted the partner consent version that covers it; otherwise they are refused (403 individual_approval_required) and go through POST /briefs. The model must be signed, available, opted into partner licensing and have a complete reference kit, and the brand, category and country are checked against the model's restrictions. Mirai records a metered external licence priced from the model's rate table (video at the video rate, per 10 seconds of runtime) and computes the model's payout; settlement is invoiced periodically. Idempotent on external_asset_ref: re-reporting the same asset never double-bills.

Request body
model_idrequiredstring
external_asset_refrequiredstringYour stable id for the delivered asset.
brandrequiredstringThe brand the asset is for. Checked against the model's excluded brands.
categorystringProduct category. Required when the model has excluded categories.
brand_countrystringTwo-letter country code where the brand is based. Required when the model has territory restrictions.
mediaimage | videoDefault image.
runtime_secondsnumberVideo only, required: clip length in seconds. Priced per 10 seconds, 10 second minimum.
reference_tokenstringThe token from the reference URL used, so the licence ties to the exact references served.
formatstringUsage format, default Digital. Digital only.
durationstringLicence duration, default 6 months.
territorystringGlobal, the default. Digital licences are always Global.
GET/licenses/quotescope: read

Price a licence without committing

Non-binding and side-effect free. Called with image_ids alone it returns the full priced option matrix for those assets (formats, durations, per-format territories) so no integrator ever holds a stale copy of the rate card; called with format and duration it returns the exact quote. Every gate the real POST /licenses enforces is evaluated here too and returned as blockers rather than errors, including the instant-scope boundary: images auto-approved under a model's standing digital consent can be licensed for digital use only unless she has print on demand switched on, and otherwise print / out-of-home requires their individual approval. Digital licences are always Global; regions exist for Print + OOH at the same price.

60/min per key

Parameters
image_idsrequiredstring (query)Comma-separated asset ids from /generate. One model per quote.
formatstring (query)
durationstring (query)
territorystring (query)
POST/licensesscope: license

Create a licence checkout for approved images

Creates a pending license plus a Stripe Checkout session; complete payment in a browser via checkout_url (the session and the pending license both expire after 1 hour). On payment, the license activates and the assets' clean URLs unlock on GET /assets/{id}. The approval gate: only assets with approval_status: "approved" (the model's sign-off) can be licensed, this is the platform's load-bearing invariant and cannot be bypassed. All images in one license must be from the same model. Image licenses only on v1 (video licensing runs through the Studio). Pricing: fee_cents = image_count x base(format) x multiplier(duration) x multiplier(territory). Base rates, Digital: $50/image; Print + OOH: $120/image; Social: $50/image; Print: $120/image. Duration multipliers, 6 months: x1; 12 months: x1.8; 24 months: x2.5; 10 years: x3.5.

10/min per key

Assets

Poll asset state and retrieve deliverable URLs.

GET/assets/{id}scope: read

Fetch the state of one of your generated assets

One id namespace covers images and videos; the response is discriminated by kind. Returns YOUR assets only, not-owned and not-found are both 404 so ids can't be probed. The authenticated url is non-null IF AND ONLY IF the asset is licensed (model approval + paid license). It streams the original without exposing its permanent storage URL. Licensed image and video downloads carry signed C2PA Content Credentials; X-Content-Credentials on the download says whether they were embedded, and where Mirai enforces them a file that cannot be signed returns 503 credential_unavailable instead of an unsigned copy. Send the same bearer key when following it. draft_url is the watermarked deliverable before licensing, an image thumbnail afterwards, and null for licensed video. For video assets this is the polling endpoint of the POST /videos async contract, watch status (processing → ready | failed).

60/min per key

Parameters
idrequiredstring (path)Asset id returned by POST /generate or POST /videos.
GET/assets/{id}/downloadscope: read

Download a licensed asset

Streams the licensed image or video without exposing its permanent storage URL. Images and videos (MP4) carry signed C2PA Content Credentials (X-Content-Credentials: embedded). Where Mirai enforces them, a file that cannot be signed returns 503 credential_unavailable, retry shortly; otherwise the header reads unavailable. The caller must own the asset and hold an active licence covering it. Send the same bearer key when following the URL returned by GET /assets/{id}.

60/min per key

Parameters
idrequiredstring (path)Licensed image or video asset id.

Enterprise lane

Approved generation partners. Brief a talent for images, video or both; the talent approves the brief, you render on your own stack, submit each final, and the talent approves it before it is licensed.

GET/briefsscope: license

Your briefs, newest first

POST/briefsscope: license

Submit a campaign brief for a talent's approval, before anything is created

Approved generation partners only. JSON, or multipart/form-data with the same fields plus up to 8 reference images. media says what the brief covers: image (default), video or both. Images and videos are counted separately (image_deliverables, video_deliverables), and a video brief sets video_seconds, the longest a single video may run. deliverables is still accepted as the old name for image_deliverables. advertiser_country (two-letter code) is required when the talent has territory restrictions. Checked at once against the talent's excluded advertisers, categories and territories, then waits for the talent's approval on Mirai. The talent sees the counts and the video length on the brief.

Request body
model_idrequiredstringThe talent, from GET /models.
advertiserrequiredstringThe brand the campaign is for.
categoryrequiredstringChecked against the talent's excluded categories.
descriptionrequiredstringThe creative idea, looks, settings and where it will run.
advertiser_countrystringTwo-letter country code. Required when the talent has territory restrictions.
mediaimage | video | bothWhat the brief covers. Default image, so existing clients are unchanged.
image_deliverablesintegerStills the brief covers, for image and both. Default 1.
video_deliverablesintegerVideos the brief covers, for video and both. Default 1.
video_secondsintegerRequired for video and both: the longest a single video may run, in seconds.
deliverablesintegerDeprecated: the old name for image_deliverables, still accepted. Not allowed on a video brief.
formatstringImages: Digital, Print + OOH. Video: Digital, Digital + OOH. Both: Digital.
duration6 months | 12 months | 24 months | 10 years
territoryGlobal | Asia | Middle East | Europe | Australia | North America | South America | Africa
Examples

Images only (the default)

{
  "model_id": "08975092-607e-47d9-b416-b2e456b0e011",
  "advertiser": "Example Skincare",
  "category": "Beauty",
  "description": "Morning routine in natural window light, three looks.",
  "media": "image",
  "image_deliverables": 3,
  "format": "Digital",
  "duration": "6 months"
}

Video only

{
  "model_id": "08975092-607e-47d9-b416-b2e456b0e011",
  "advertiser": "Example Skincare",
  "category": "Beauty",
  "description": "Two short clips: applying serum, then a smile to camera.",
  "media": "video",
  "video_deliverables": 2,
  "video_seconds": 15,
  "format": "Digital",
  "duration": "6 months"
}

Images and video

{
  "model_id": "08975092-607e-47d9-b416-b2e456b0e011",
  "advertiser": "Example Skincare",
  "category": "Beauty",
  "description": "Launch set: three stills and two 15 second clips.",
  "media": "both",
  "image_deliverables": 3,
  "video_deliverables": 2,
  "video_seconds": 15,
  "format": "Digital",
  "duration": "12 months"
}
GET/briefs/{id}scope: license

A brief's status and the finals submitted under it

Parameters
idrequiredstring (path)
POST/briefs/{id}/submissionsscope: license

Submit a final image or video rendered on your own stack, under an approved brief

multipart/form-data with file and external_asset_ref. The file is read from its bytes: an MP4 is a video final, anything else an image. An image must fit the brief's media (image or both) and is kept under 25 MB. A video must fit a video or both brief, be an MP4 in avc1, avc3, hvc1, hev1, av01, vp09, run no longer than the brief's video_seconds, and stay under 5 MB plus 3 MB per second of video_seconds (50 MB for a 15 second brief, 185 MB for 60 seconds). Images and videos count against their own deliverables. Waits for the talent's approval; once approved it is licensed (a video at the video rate, by runtime, per second with a ten-second minimum per clip) and available from /submissions/{id}/file. Re-submitting the same external_asset_ref returns the existing submission.

Parameters
idrequiredstring (path)
Request body
filerequiredstringThe final: an image, or an MP4 for video.
external_asset_refrequiredstringYour id for this asset. Idempotency key.
GET/submissions/{id}scope: license

A final's status, media and duration_seconds; once approved, the licence, file_url and verify_url

Parameters
idrequiredstring (path)
GET/submissions/{id}/filescope: license

The approved final with signed C2PA Content Credentials

An image is served as image/jpeg (mirai-xxxxxxxx.jpg) with signed Content Credentials. A video is served as video/mp4 (mirai-xxxxxxxx.mp4). Video Content Credentials are not embedded yet: X-Content-Credentials reads unsigned, and where Mirai enforces credentials a video returns 503 credential_unavailable until video signing ships.

Parameters
idrequiredstring (path)

Open IP

Experimental catalogue, disabled by default and not a licensed third-party IP offering. Routes return 404 unless separately enabled for a reviewed partner pilot. Public-domain assessments are jurisdiction- and depiction-specific, not blanket commercial clearance.

GET/ipscope: read

List the open-IP character catalog

Experimental open-IP catalogue, not a commercial FAL partnership announcement or a signed third-party catalogue. Disabled unless OPEN_IP_PARTNER_API=1. Query filters: tier (A|B|C), risk (low|medium|high), franchise, commercial_use (true|false). Review the entry's rights assessment and intended jurisdiction before any use. Tier C is a watchlist, entries not yet public domain; they always carry commercial_use: false and the detail route withholds prompt packs for them.

60/min per key

Parameters
tierstring (query)Filter by tier.
riskstring (query)Filter by trademark risk.
franchisestring (query)Filter by franchise key (e.g. oz, hundred-acre-wood).
commercial_usestring (query)true = only licensable entries; false = only watchlist/restricted.
GET/ip/{slug}scope: read

Fetch an open-IP character sheet with FAL prompt packs

Full character sheet (identity, legal dossier, visual DNA, voice spec) plus drop-in FAL prompt packs: image2 for openai/gpt-image-2/edit (including the 6-slot reference kit) and seedance for bytedance/seedance-2.0/reference-to-video. Legal avoid-lists are pre-merged into the negatives. Watchlist (Tier C / commercial_use false) entries return prompt_packs: null and license_terms: null with a watchlist_note.

60/min per key

Parameters
slugrequiredstring (path)Character slug from GET /ip.
POST/ip/{slug}/generatescope: generate

Generate a licensed open-IP character image

One-call Mirai × FAL flow: name a catalog character, receive a watermarked, licensable draft generated by the same gpt-image-2 chain as POST /generate. The character sheet anchors identity (visual DNA, palette, era style lock) and its legal avoid-list is enforced as an exclusion clause on every render. prompt is optional scene direction. Open-IP images are born approval_status "approved", there is no human likeness to consent, so the returned asset_id can go straight to POST /licenses. To animate, pass asset_id to POST /videos (Seedance); motion guidance lives in the character's prompt_packs. Watchlist (Tier C / commercial_use false) slugs refuse with 403 ip_not_commercial and are never generated.

20/min per key, 40/min per brand

Parameters
slugrequiredstring (path)Character slug from GET /ip.

Errors

Inspect response bodies as well as HTTP status. Long-running generation can return an error in its final JSON body after HTTP 200 has already been sent.

invalid_formatThe format value is not in the accepted enum.
invalid_durationThe duration value is not in the accepted enum.
invalid_territoryThe territory value is not in the accepted enum.
brand_country_missingSet your brand's country in Settings before working with a region-restricted model.
region_restrictedThis model is not available to brands based in your country.
images_not_approvedOnly model-approved images can be licensed; unapprovedIds lists the offenders.
duplicate_licenseAn active or pending license already covers one of these images.
model_not_payout_readyThe model's payout account isn't ready; the booking is refused rather than stranding funds.
insufficient_creditsThe plan's monthly credits do not cover this request. The body carries creditsNeeded and creditsRemaining. Nothing was reserved or charged.
video_quota_exceededVideo is not included in the plan and no prepaid credit pack covers it, or (Enterprise) the video allowance is used up with no pack or overage.
source_has_watermarkThe video source image only has a watermarked file; generate a fresh image.
character_sheet_not_readyThe model is on the roster but has no character sheet yet.
key_limit_reachedA brand can hold at most 10 active API keys.
invalid_mediaBrief media must be "image", "video" or "both".
invalid_deliverablesA deliverables count is missing, out of range, or does not match the brief's media.
invalid_video_secondsA video brief needs video_seconds from 5 to 60.
media_mismatchA video was sent under an image-only brief, or an image under a video-only brief.
unsupported_videoThe video is not a playable MP4 (avc1, avc3, hvc1, hev1, av01, vp09) with a readable runtime.
video_too_longThe video runs longer than the brief's video_seconds.
deliverables_exhaustedThe brief's images or videos are used up. Ask the talent to approve a new brief.