ReferenceReference by module

Creative Studio API

Every Creative Studio action (26) and data model (5): endpoints, scopes, input, preconditions, events and examples.

Describe it, see it, use it — product photos, posts, story videos, voice-overs and music, made by AI.

Module code creative · 26 actions · 5 data models · 8 events. A key or token never does more here than the person behind it can; row-level security applies exactly as in the app. Scopes: creative (everything), creative:read (read only) or creative:<capability>.

Resources

ResourceTableList and readPOSTPATCHDELETE
creative_adscreative_ad/api/v1/creative_ads
creative_brand_kitscreative_brand_kit/api/v1/creative_brand_kits
creative_generationscreative_generation/api/v1/creative_generations
creative_postscreative_post/api/v1/creative_posts
creative_voicescreative_voice/api/v1/creative_voices

Lists take limit (up to 200), cursor, order (e.g. -created_at), fields and q; every other query parameter is a column filter: ?status=paid, ?total[gte]=100, ?id[in]=a,b, ?x=null.

Actions

ActionNeedsWhat it does
creative.cancelcreative:writeCancel a generation
creative.cancel_postcreative:writeCancel a scheduled post
creative.clone_voicecreative:writeClone a voice
creative.complete_generationcreative:handleFinish a generation
creative.composecreative:writeSet text on a picture, or make a photo reel
creative.edit_againcreative:writeEdit the video again
creative.fail_generationcreative:handleMark a generation failed
creative.finish_voicecreative:handleFinish cloning a voice
creative.generatecreative:writeGenerate an image, video, voice-over or music
creative.generate_batchcreative:writeMake a batch
creative.generate_setcreative:writeProduct photo studio: make a set
creative.mark_postcreative:handleRecord a post’s progress
creative.note_provider_jobcreative:handleRecord the provider job
creative.park_generationcreative:handleWait for the owner’s computer
creative.record_usecreative:writeRecord where a result was used
creative.removecreative:deleteRemove from history
creative.remove_adcreative:deleteRemove from the ad library
creative.remove_voicecreative:deleteRemove a voice
creative.resume_providercreative:writeCheck the provider result again
creative.save_adcreative:writeSave an ad to the library
creative.save_brand_kitcreative:writeSave the brand kit
creative.save_captioncreative:writeSave the post text
creative.schedule_postcreative:writePost to social media
creative.set_favouritecreative:writeFavourite
creative.start_generationcreative:handleStart a generation
creative.varycreative:writeMore like this

creative.cancel

Cancel a generation — Stops a generation that has not started.

Needs creative:write · removes or cannot be undone

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/cancel
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.cancel

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_queuedOnly a generation that has not started can be cancelled.

What it writes: creative_generation (update) — queued → cancelled

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/cancel \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.cancel("CREATIVE_GENERATION_ID")
era creative_generations cancel CREATIVE_GENERATION_ID
tools/call
{
  "name": "era__creative__cancel",
  "arguments": {
    "id": "CREATIVE_GENERATION_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_queued · 429 slow down

creative.cancel_post

Cancel a scheduled post — Stops a post that has not gone out yet.

Needs creative:write · removes or cannot be undone

POSThttps://app.getera.io/api/v1/creative_posts/{id}/actions/cancel_post
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.cancel_post

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Post · id of creative_post

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_scheduledOnly a scheduled post can be cancelled.

What it writes: creative_post (update) — scheduled → cancelled

curl -X POST https://app.getera.io/api/v1/creative_posts/CREATIVE_POST_ID/actions/cancel_post \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativePosts.cancelPost("CREATIVE_POST_ID")
era creative_posts cancel_post CREATIVE_POST_ID
tools/call
{
  "name": "era__creative__cancel_post",
  "arguments": {
    "id": "CREATIVE_POST_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_scheduled · 429 slow down

creative.clone_voice

Clone a voice — Makes a voice from your own recordings, for voice-overs and lip sync. Only with the speaker’s consent.

Needs creative:write · reaches outside (sends, publishes or charges) · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/creative_voices/actions/clone_voice
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.clone_voice

Input

FieldTypeRequiredNotes
namestringyesVoice name · max 80
sampleFileIdsobject / arrayyesRecordings · File ids of audio recordings of the voice.
consentbooleanyesI have the speaker’s consent

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
empty_nameThe voice needs a name.
consent_requiredA voice is cloned only after the person confirms the speaker agreed.
needs_samplesAt least one recording of the voice.

Events it publishes: creative.voice_requested

What it writes: creative_voice (insert) — A pending voice, made by the studio right after

curl -X POST https://app.getera.io/api/v1/creative_voices/actions/clone_voice \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name":"Voice name","sampleFileIds":{},"consent":true}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.voice_requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeVoices.cloneVoice({
  name: "Voice name",
  sampleFileIds: {},
  consent: true
})
era creative_voices clone_voice --data '{"name":"Voice name","sampleFileIds":{},"consent":true}'
tools/call
{
  "name": "era__creative__clone_voice",
  "arguments": {
    "name": "Voice name",
    "sampleFileIds": {},
    "consent": true
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 empty_name, consent_required, needs_samples · 429 slow down

creative.complete_generation

Finish a generation — Records the results (files) and the real cost. Machine-only.

Needs creative:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/complete_generation
API key or OAuth token · creative:handle
  • Canonical address: POST /api/v1/actions/creative.complete_generation

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation
outputsobject / arrayyesResults
usedModelstringModel · max 160
providerstringProvider · max 40
sourceKindstringPaid by · max 20
costUsdnumberCost (USD) · min 0
connectionobject / arrayWhose connection
checkobject / arraySelf-check

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_runningOnly a running generation can finish.
no_outputsA finished generation has at least one result.

Events it publishes: creative.generated

What it writes: creative_generation (update) — running → succeeded, with results and cost

Errors: 401 no or expired credential · 403 the credential does not hold creative:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_running, no_outputs · 429 slow down

creative.compose

Set text on a picture, or make a photo reel — Made by Era itself — no AI model, no cost. A layout sets real, correctly spelled text over a picture in the brand’s colours and font with the logo (campaign, new_product, price_tag, announcement, story_cta, menu_card, marketplace_band, quote). A photo reel turns 2–10 photos into a vertical video with gentle motion, the hook, music and an end card.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/compose
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.compose

Input

FieldTypeRequiredNotes
kindstring (enum)yesWhat · Allowed values: layout, photo_reel, image_grade
gradeobject / arrayColour adjustments · { exposure:-5..5, contrast:-100..100, saturation:-100..100, hue:-180..180, temperature:-100..100, splitTone:0..1, soften:0..20, vignette:0..1, grain:0..1 }. Local, no model.
fileIdsobject / arrayyesPictures · Files ids: one for a layout, 2–10 for a reel.
layoutobject / arrayLayout · { code, headline, subline, badge, price, oldPrice, cta, logo }
channelstringChannel · max 40
reelobject / arrayReel · { hook, cta, music: upbeat|calm|cafe|none, voiceGenerationId, perPhotoSec, endCard, captions[] }
productIduuidProduct
sourceGenerationIduuidFilled from the path {id} · Made from · id of creative_generation

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
unknown_layoutThe layout must be one Creative Studio offers.
needs_imageA layout goes over exactly one picture.
empty_textA layout shows a headline, a price or a badge.
needs_photosA photo reel needs at least two photos.
unknown_trackThe music must be one of Era’s beds, or none.
not_foundA voice-over named for the reel must exist here.

Events it publishes: creative.requested

What it writes: creative_generation (insert) — Queues the layout or reel; Era makes it without a model

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/compose \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"kind":"layout","fileIds":{}}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.compose("CREATIVE_GENERATION_ID", {
  kind: "layout",
  fileIds: {}
})
era creative_generations compose CREATIVE_GENERATION_ID --data '{"kind":"layout","fileIds":{}}'
tools/call
{
  "name": "era__creative__compose",
  "arguments": {
    "sourceGenerationId": "CREATIVE_GENERATION_ID",
    "kind": "layout",
    "fileIds": {}
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 unknown_layout, needs_image, empty_text, needs_photos, unknown_track, not_found · 429 slow down

creative.edit_again

Edit the video again — Makes a new version of a finished AI video edit from a note ("shorter intro, no music"); the earlier versions stay.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/edit_again
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.edit_again

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Video edit · id of creative_generation
notestringyesWhat should change · max 2000

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
empty_noteThe note must say what to change.
not_editableOnly a finished AI video edit (with its clips) can be edited again.

Events it publishes: creative.requested

What it writes: creative_generation (insert) — A queued video edit: the next version, pointing at the one it changes

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/edit_again \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"note":"What should change"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.editAgain("CREATIVE_GENERATION_ID", {
  note: "What should change"
})
era creative_generations edit_again CREATIVE_GENERATION_ID \
  --note "What should change"
tools/call
{
  "name": "era__creative__edit_again",
  "arguments": {
    "id": "CREATIVE_GENERATION_ID",
    "note": "What should change"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 empty_note, not_editable · 429 slow down

creative.fail_generation

Mark a generation failed — Records why it failed. Machine-only.

Needs creative:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/fail_generation
API key or OAuth token · creative:handle
  • Canonical address: POST /api/v1/actions/creative.fail_generation

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation
errorstringWhy · max 600

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_openOnly a queued or running generation can fail.

Events it publishes: creative.failed

What it writes: creative_generation (update) — → failed

Errors: 401 no or expired credential · 403 the credential does not hold creative:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_open · 429 slow down

creative.finish_voice

Finish cloning a voice — Records the provider’s voice, or why it failed. Machine-only.

Needs creative:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/creative_voices/{id}/actions/finish_voice
API key or OAuth token · creative:handle
  • Canonical address: POST /api/v1/actions/creative.finish_voice

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Voice · id of creative_voice
externalVoiceIdstringProvider voice id · max 120
sourceKindstring (enum)Account · Allowed values: byok
connectionIduuidConnection
errorstringWhy it failed · max 600

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_pendingOnly a voice being cloned can finish.

What it writes: creative_voice (update) — pending → ready / failed

Errors: 401 no or expired credential · 403 the credential does not hold creative:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_pending · 429 slow down

creative.generate

Generate an image, video, voice-over or music — Describe it (or pick a preset like a white-background product shot, an Instagram post, a story video or a menu photo); it is made in the background and lands in Creative Studio and the Files library. The cost is shown first; it runs on your own subscription or key.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/generate
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.generate

Input

FieldTypeRequiredNotes
higgsfieldobject / arrayStudio tool inputs · Open-Higgsfield: {id, values, files}. id is a tool catalogue id, values are model options, files maps typed media field names to Files ids. Requires your MuAPI key. Discover tools with media_make operation catalogue.
promptstringWhat to make · max 4000
studiostring (enum)Studio · The Creative Studio studio it is made in (image, video, cinema, character, lipsync, motion, recast, clip, layers, audio, marketing, product); its history shows it there. · Allowed values: image, video, cinema, character, lipsync, motion, recast, clip, layers, audio, marketing, product
kindstring (enum)Kind · Allowed values: image, video, tts, audio
presetstringPreset · For a person: dance_trend, portrait_avatar, photo_edit, reel, cartoon_me, celebration_card, song_bed. For a business: product_white, product_lifestyle, instagram_post, story_video, product_video, menu_photo, poster, website_banner, voiceover, jingle. Templates that start from a photo need inputFileIds. · max 60
modelstringModel · auto (cheapest that can do it) or a catalogue model id · max 160
aspectstring (enum)Shape · Allowed values: 1:1, 4:5, 9:16, 16:9, 3:2, 2:3
durationSecnumberLength (seconds) · min 1 · max 30
countnumberHow many · min 1 · max 4
voicestringVoice · max 80
inputFileIdsobject / arrayStarting photos · File ids of photos to start from (animate or edit).
inputVideoIdsobject / arrayYour clip · File id of your own 4–30 s clip, for motion transfer.
resolutionstring (enum)Resolution · Allowed values: 480p, 720p, 1080p
inputUrlsobject / arrayStarting photos on the web · https addresses of photos to start from, e.g. a product page image.
inputAudioIdsobject / arrayAudio · File id of the audio for lip sync or a talking photo.
useBrandbooleanUse the brand kit · Adds the brand name, colours and tone (default: the brand kit’s own setting).
harnessstringEditing agent · AI video editor: the coding agent on your computer (claude, codex). · max 40
upscalenumberUpscale · 2× or 4×. · min 2 · max 4
voiceIduuidCloned voice · id of creative_voice
editLastbooleanEdit the last picture · Change the newest picture (sent in chat or made here) instead of drawing a new one: "add X to it", "make this bottle a Fanta". Ignored when starting photos are given.
channelstringChannel · Where it goes — instagram_post, instagram_story, reels, whatsapp_status, google_business, facebook_ad, trendyol, hepsiburada, amazon, website_hero … — sets the shape. · max 40
productIduuidProduct · The shop product it is made for.
sourceGenerationIduuidFilled from the path {id} · Made from · The result this one varies or edits. · id of creative_generation

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
empty_promptThere must be a description or a preset.
unknown_presetThe preset must be one Creative Studio offers.
needs_imageA preset that animates a photo needs the photo; editing the last picture needs one.
no_sourceYour own plan or key must be able to make this kind.
budget_exceededThe workspace AI budget must have room.
voice_not_readyA cloned voice must be ready before it speaks.

Events it publishes: creative.requested

What it writes: creative_generation (insert) — Queues the generation with its estimate

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/generate \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"higgsfield":{}}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.generate("CREATIVE_GENERATION_ID", {
  higgsfield: {}
})
era creative_generations generate CREATIVE_GENERATION_ID --data '{"higgsfield":{}}'
tools/call
{
  "name": "era__creative__generate",
  "arguments": {
    "sourceGenerationId": "CREATIVE_GENERATION_ID",
    "higgsfield": {}
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 empty_prompt, unknown_preset, needs_image, no_source, budget_exceeded, voice_not_ready · 429 slow down

creative.generate_batch

Make a batch — One template for many products, photos or lines at once (up to 20): "these 12 products on white", "a story for every dish on the menu". Each one is its own generation in one batch.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/actions/generate_batch
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.generate_batch

Input

FieldTypeRequiredNotes
presetstringTemplate · max 60
promptstringFor all of them · max 2000
itemsobject / arrayyesLines · A list of { prompt?, inputFileIds?, productId?, label? } — one picture each.
channelstringChannel · max 40
modelstringModel · max 160
aspectstring (enum)Shape · Allowed values: 1:1, 4:5, 9:16, 16:9, 3:2, 2:3
useBrandbooleanUse the brand kit
labelstringName · max 120

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
empty_batchA batch has at least one line.
batch_too_bigA batch holds at most 20.
unknown_presetThe template must be one Creative Studio offers.
empty_promptEach line needs words or a template.
needs_imageA template that starts from a photo needs the photo on every line.
no_sourceYour own plan or key must be able to make it.
budget_exceededThe workspace AI budget must have room.

Events it publishes: creative.requested

What it writes: creative_generation (insert) — Queues one generation per line, sharing a batch

curl -X POST https://app.getera.io/api/v1/creative_generations/actions/generate_batch \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"items":{}}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.generateBatch({
  items: {}
})
era creative_generations generate_batch --data '{"items":{}}'
tools/call
{
  "name": "era__creative__generate_batch",
  "arguments": {
    "items": {}
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 empty_batch, batch_too_big, unknown_preset, empty_prompt, needs_image, no_source, budget_exceeded · 429 slow down

creative.generate_set

Product photo studio: make a set — One photo of a product becomes a set of shots, each made separately so the product stays the product: clean (on white), angles (front · three-quarter · side · back), lifestyle (three scenes for your sector) or listing (main on white · angle · detail · in use, cut for Trendyol or Hepsiburada).

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/actions/generate_set
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.generate_set

Input

FieldTypeRequiredNotes
setstringyesSet · clean (on white) · angles (front, three-quarter, side, back) · lifestyle (three scenes) · listing (main, angle, detail, in use). · max 20
inputFileIdsobject / arrayProduct photo · File id(s) of the product photo (1–2).
inputUrlsobject / arrayProduct photo on the web · https address of a product photo.
productIduuidProduct · The shop product the set is for.
productstringProduct name · max 200
notestringAnything else · max 600
channelstringChannel · trendyol, hepsiburada, amazon, n11, instagram_post … (a listing set defaults to trendyol). · max 40
sectorstringSector · food, cafe, bakery, beauty, barber, fashion, jewellery, cosmetics, home, health, realestate, ecommerce — the scenes it suits. · max 40
modelstringModel · max 160

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
unknown_setThe set must be one the product studio offers.
needs_imageThe product studio starts from a photo of the product.
no_sourceYour own plan or key must be able to make it.
budget_exceededThe workspace AI budget must have room.

Events it publishes: creative.requested

What it writes: creative_generation (insert) — Queues one generation per shot, sharing a batch

curl -X POST https://app.getera.io/api/v1/creative_generations/actions/generate_set \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"set":"Set"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.generateSet({
  set: "Set"
})
era creative_generations generate_set \
  --set "Set"
tools/call
{
  "name": "era__creative__generate_set",
  "arguments": {
    "set": "Set"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 unknown_set, needs_image, no_source, budget_exceeded · 429 slow down

creative.mark_post

Record a post’s progress — scheduled → posting → posted / failed. Machine-only.

Needs creative:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/creative_posts/{id}/actions/mark_post
API key or OAuth token · creative:handle
  • Canonical address: POST /api/v1/actions/creative.mark_post

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Post · id of creative_post
statusstring (enum)yesStatus · Allowed values: posting, posted, failed
externalIdstringPlatform id · max 200
externalUrlstringLink · max 600
errorstringWhy it failed · max 600

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_openA post moves only forward: scheduled → posting → posted or failed.

Events it publishes: creative.posted, creative.post_failed

What it writes: creative_post (update) — Moves the post forward; creative_generation (update) — Adds "used on <channel>"

Errors: 401 no or expired credential · 403 the credential does not hold creative:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_open · 429 slow down

creative.note_provider_job

Record the provider job — Persists a MuAPI request before polling so recovery never submits it twice. Machine-only.

Needs creative:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/note_provider_job
API key or OAuth token · creative:handle
  • Canonical address: POST /api/v1/actions/creative.note_provider_job

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation
requestIdstringyesProvider request · max 200

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_runningOnly a running studio tool can record its provider job.

What it writes: creative_generation (update) — Saves the provider request id

Errors: 401 no or expired credential · 403 the credential does not hold creative:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_running · 429 slow down

creative.park_generation

Wait for the owner’s computer — Parks a generation that runs on a person’s own plan until their computer is back. Machine-only.

Needs creative:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/park_generation
API key or OAuth token · creative:handle
  • Canonical address: POST /api/v1/actions/creative.park_generation

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation
waitingobject / arrayyesRunner job

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_runningOnly a running generation can wait.
bad_waitingThe runner job it waits for must be named.

What it writes: creative_generation (update) — running → waiting

Errors: 401 no or expired credential · 403 the credential does not hold creative:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_running, bad_waiting · 429 slow down

creative.record_use

Record where a result was used — Remembers that a result went onto a product, a post, an email or the website.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/record_use
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.record_use

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation
targetstringyesUsed on · product, blog_post, campaign, website, files, download, social, export, marketplace · max 20
targetIdstringRecord · max 64
labelstringName · max 200

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_foundOnly a finished generation can be used.
bad_targetThe place must be one Creative Studio knows.

Events it publishes: creative.used

What it writes: creative_generation (update) — Appends the use

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/record_use \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"target":"Used on"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.used"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.recordUse("CREATIVE_GENERATION_ID", {
  target: "Used on"
})
era creative_generations record_use CREATIVE_GENERATION_ID \
  --target "Used on"
tools/call
{
  "name": "era__creative__record_use",
  "arguments": {
    "id": "CREATIVE_GENERATION_ID",
    "target": "Used on"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found, bad_target · 429 slow down

creative.remove

Remove from history — Takes a finished generation off the history. Its files stay in the Files library.

Needs creative:delete · removes or cannot be undone · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/remove
API key or OAuth token · creative:delete
  • Canonical address: POST /api/v1/actions/creative.remove

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_foundThe generation must exist and be finished.

What it writes: creative_generation (delete) — Deletes the history row

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/remove \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.remove("CREATIVE_GENERATION_ID")
era creative_generations remove CREATIVE_GENERATION_ID
tools/call
{
  "name": "era__creative__remove",
  "arguments": {
    "id": "CREATIVE_GENERATION_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:delete · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found · 429 slow down

creative.remove_ad

Remove from the ad library — Takes an ad out of the library.

Needs creative:delete · removes or cannot be undone

POSThttps://app.getera.io/api/v1/creative_ads/{id}/actions/remove_ad
API key or OAuth token · creative:delete
  • Canonical address: POST /api/v1/actions/creative.remove_ad

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Ad · id of creative_ad

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_foundThe ad must be in this workspace’s library.

What it writes: creative_ad (delete) — Deletes the ad

curl -X POST https://app.getera.io/api/v1/creative_ads/CREATIVE_AD_ID/actions/remove_ad \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeAds.removeAd("CREATIVE_AD_ID")
era creative_ads remove_ad CREATIVE_AD_ID
tools/call
{
  "name": "era__creative__remove_ad",
  "arguments": {
    "id": "CREATIVE_AD_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:delete · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found · 429 slow down

creative.remove_voice

Remove a voice — Deletes a cloned voice (also at the provider).

Needs creative:delete · removes or cannot be undone · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/creative_voices/{id}/actions/remove_voice
API key or OAuth token · creative:delete
  • Canonical address: POST /api/v1/actions/creative.remove_voice

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Voice · id of creative_voice

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_foundThe voice must exist in this workspace.

What it writes: creative_voice (delete) — Deletes the voice

curl -X POST https://app.getera.io/api/v1/creative_voices/CREATIVE_VOICE_ID/actions/remove_voice \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeVoices.removeVoice("CREATIVE_VOICE_ID")
era creative_voices remove_voice CREATIVE_VOICE_ID
tools/call
{
  "name": "era__creative__remove_voice",
  "arguments": {
    "id": "CREATIVE_VOICE_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:delete · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found · 429 slow down

creative.resume_provider

Check the provider result again — Polls the saved MuAPI job again, without purchasing another generation.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/resume_provider
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.resume_provider

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_foundA failed studio tool must have a saved provider request to resume.

Events it publishes: creative.requested

What it writes: creative_generation (update) — Requeues polling of the saved provider job

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/resume_provider \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.resumeProvider("CREATIVE_GENERATION_ID")
era creative_generations resume_provider CREATIVE_GENERATION_ID
tools/call
{
  "name": "era__creative__resume_provider",
  "arguments": {
    "id": "CREATIVE_GENERATION_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found · 429 slow down

creative.save_ad

Save an ad to the library — Keeps an ad you like (from the Meta Ad Library, a link or a screenshot) so Creative Studio can make one like it for your product.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_ads/actions/save_ad
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.save_ad

Input

FieldTypeRequiredNotes
sourcestringyesFrom · meta_ad_library, url, upload or own · max 20
titlestringyesName · max 200
externalIdstringLibrary id · max 120
advertiserstringAdvertiser · max 200
bodystringAd text · max 4000
linkUrlstringLink · max 2000
snapshotUrlstringAd preview link · max 2000
mediaFileIdsobject / arrayScreenshots
mediaUrlsobject / arrayMedia links
platformsobject / arrayPlatforms
startedOnstringRunning since · max 10
tagsobject / arrayTags
notesstringWhy we like it · max 2000

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
bad_sourceThe source is one the library knows.
empty_titleAn ad needs a name.

What it writes: creative_ad (upsert) — Adds (or refreshes) the ad in the library

curl -X POST https://app.getera.io/api/v1/creative_ads/actions/save_ad \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"source":"From","title":"Name"}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeAds.saveAd({
  source: "From",
  title: "Name"
})
era creative_ads save_ad \
  --source "From" \
  --title "Name"
tools/call
{
  "name": "era__creative__save_ad",
  "arguments": {
    "source": "From",
    "title": "Name"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 bad_source, empty_title · 429 slow down

creative.save_brand_kit

Save the brand kit — Name, colours, fonts, logo and tone of voice — Creative Studio adds them to every generation unless you switch it off for one.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_brand_kits/actions/save_brand_kit
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.save_brand_kit

Input

FieldTypeRequiredNotes
namestringyesBrand name · max 120
taglinestringTagline · max 200
voicestringTone of voice · max 600
audiencestringWho it is for · max 300
coloursobject / arrayColours · Up to 8 hex colours, e.g. ["#1F2937", "#7C83FD"].
fontsobject / arrayFonts · Up to 4 font names.
logoFileIduuidLogo · id of file
referenceFileIdsobject / arrayReference images · File ids of photos that show the look.
wordsUsestringWords we use · max 600
wordsAvoidstringWords and looks to avoid · max 600
applyByDefaultbooleanUse in every generation
sectorstringSector · food, cafe, bakery, beauty, barber, fashion, jewellery, cosmetics, home, health, realestate, ecommerce. · max 40
syncedFromobject / arrayTaken from the workspace

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
empty_nameThe brand kit needs a name.
bad_colourColours are hex values like #1A2B3C.
unknown_sectorThe sector must be one Creative Studio knows.

What it writes: creative_brand_kit (upsert) — Writes the one brand kit of the workspace

curl -X POST https://app.getera.io/api/v1/creative_brand_kits/actions/save_brand_kit \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name":"Brand name"}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeBrandKits.saveBrandKit({
  name: "Brand name"
})
era creative_brand_kits save_brand_kit \
  --name "Brand name"
tools/call
{
  "name": "era__creative__save_brand_kit",
  "arguments": {
    "name": "Brand name"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 empty_name, bad_colour, unknown_sector · 429 slow down

creative.save_caption

Save the post text — Keeps the caption and hashtags that go with a result, for posting and sharing.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/save_caption
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.save_caption

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Result · id of creative_generation
textstringyesText · max 2200
hashtagsobject / arrayHashtags · Up to 30, with or without #.
channelstringChannel · max 40

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
empty_captionA caption has words.
not_foundThe result must exist in this workspace.

What it writes: creative_generation (update) — Sets the caption

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/save_caption \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"text":"Text"}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.saveCaption("CREATIVE_GENERATION_ID", {
  text: "Text"
})
era creative_generations save_caption CREATIVE_GENERATION_ID \
  --text "Text"
tools/call
{
  "name": "era__creative__save_caption",
  "arguments": {
    "id": "CREATIVE_GENERATION_ID",
    "text": "Text"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 empty_caption, not_found · 429 slow down

creative.schedule_post

Post to social media — Posts a Creative Studio result (or files) to an Instagram, Facebook, TikTok or YouTube account now or at a time. Always asks before posting.

Needs creative:write · reaches outside (sends, publishes or charges) · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/creative_posts/actions/schedule_post
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.schedule_post

Input

FieldTypeRequiredNotes
generationIduuidResult · id of creative_generation
fileIdsobject / arrayFiles · File ids to post, when not a whole result.
channelstringyesWhere · instagram, facebook, tiktok or youtube · max 20
connectionIduuidyesAccount · The connected account (Settings → Apps).
captionstringCaption · max 2200
titlestringTitle (YouTube) · max 100
scheduledAtstringWhen · ISO date-time; empty = now. · max 40

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
bad_channelThe channel must be Instagram, Facebook, TikTok or YouTube.
not_readyOnly a finished result can be posted.
nothing_to_postThere must be a picture or video to post.
wrong_mediaTikTok and YouTube take a video; YouTube needs a title.
no_connectionThe account must be connected and usable by the person posting.
bad_timeThe time must be a real date at most six months ahead.

Events it publishes: creative.post_scheduled

What it writes: creative_post (insert) — A scheduled post; the studio posts it when it is due

curl -X POST https://app.getera.io/api/v1/creative_posts/actions/schedule_post \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"channel":"Where","connectionId":"CONNECTION_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.post_scheduled"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativePosts.schedulePost({
  channel: "Where",
  connectionId: "CONNECTION_ID"
})
era creative_posts schedule_post \
  --channel "Where" \
  --connection-id "CONNECTION_ID"
tools/call
{
  "name": "era__creative__schedule_post",
  "arguments": {
    "channel": "Where",
    "connectionId": "CONNECTION_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 bad_channel, not_ready, nothing_to_post, wrong_media, no_connection, bad_time · 429 slow down

creative.set_favourite

Favourite — Stars a generation so it is easy to find again.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/set_favourite
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.set_favourite

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation
favouritebooleanyesFavourite

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_foundThe generation must exist in this workspace.

What it writes: creative_generation (update) — Sets the star

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/set_favourite \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"favourite":true}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.setFavourite("CREATIVE_GENERATION_ID", {
  favourite: true
})
era creative_generations set_favourite CREATIVE_GENERATION_ID \
  --favourite true
tools/call
{
  "name": "era__creative__set_favourite",
  "arguments": {
    "id": "CREATIVE_GENERATION_ID",
    "favourite": true
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found · 429 slow down

creative.start_generation

Start a generation — Claims a queued generation for the worker that will make it. Machine-only.

Needs creative:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/start_generation
API key or OAuth token · creative:handle
  • Canonical address: POST /api/v1/actions/creative.start_generation

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Generation · id of creative_generation

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_queuedOnly a queued generation can start, and only once.

What it writes: creative_generation (update) — queued → running

Errors: 401 no or expired credential · 403 the credential does not hold creative:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_queued · 429 slow down

creative.vary

More like this — New takes on a finished picture: the same subject and product, a fresh composition, angle and light. 1–4 at a time.

Needs creative:write · changes data

POSThttps://app.getera.io/api/v1/creative_generations/{id}/actions/vary
API key or OAuth token · creative:write
  • Canonical address: POST /api/v1/actions/creative.vary

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Picture · id of creative_generation
countnumberHow many · min 1 · max 4
notestringWhat to change · max 600

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_foundOnly a finished picture can be varied.
no_sourceYour own plan or key must be able to make it.
budget_exceededThe workspace AI budget must have room.

Events it publishes: creative.requested

What it writes: creative_generation (insert) — Queues the variations

curl -X POST https://app.getera.io/api/v1/creative_generations/CREATIVE_GENERATION_ID/actions/vary \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"count":1}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "creative.requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.creativeGenerations.vary("CREATIVE_GENERATION_ID", {
  count: 1
})
era creative_generations vary CREATIVE_GENERATION_ID \
  --count 1
tools/call
{
  "name": "era__creative__vary",
  "arguments": {
    "id": "CREATIVE_GENERATION_ID",
    "count": 1
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold creative:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found, no_source, budget_exceeded · 429 slow down

Data models

CreativeAd

Table creative_ad · Resource creative_ads

  • GET /api/v1/creative_ads
  • GET /api/v1/creative_ads/{id}
ColumnTypeNullableAllowed valuesReferences
idstring (uuid) · uuid
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
created_bystring (uuid) · uuidyesapp_user
sourcestring · textmeta_ad_library, url, upload, own
external_idstring · textyes
titlestring · text
advertiserstring · textyes
bodystring · textyes
link_urlstring · textyes
snapshot_urlstring · textyes
media_file_idsstring[] · uuid[]
media_urlsstring[] · text[]
platformsstring[] · text[]
started_onstring (date) · dateyes
tagsstring[] · text[]
notesstring · textyes
created_atstring (date-time) · timestamptz
updated_atstring (date-time) · timestamptz

Primary key: id

CreativeBrandKit

Table creative_brand_kit · Resource creative_brand_kits

  • GET /api/v1/creative_brand_kits
  • GET /api/v1/creative_brand_kits/{id}
ColumnTypeNullableAllowed valuesReferences
idstring (uuid) · uuid
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
namestring · text
taglinestring · textyes
voicestring · textyes
audiencestring · textyes
coloursstring[] · text[]
fontsstring[] · text[]
logo_file_idstring (uuid) · uuidyes
reference_file_idsstring[] · uuid[]
words_usestring · textyes
words_avoidstring · textyes
apply_by_defaultboolean · bool
updated_bystring (uuid) · uuidyesapp_user
created_atstring (date-time) · timestamptz
updated_atstring (date-time) · timestamptz
sectorstring · textyes
synced_fromobject · jsonbyes
synced_atstring (date-time) · timestamptzyes

Primary key: id

Checks:

  • CHECK (((array_length(colours, 1) IS NULL) OR (array_length(colours, 1) <= 8)))

CreativeGeneration

Table creative_generation · Resource creative_generations

  • GET /api/v1/creative_generations
  • GET /api/v1/creative_generations/{id}
ColumnTypeNullableAllowed valuesReferences
idstring (uuid) · uuid
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
created_bystring (uuid) · uuidyesapp_user
kindstring · textimage, video, tts, audio
promptstring · text
presetstring · textyes
modelstring · text
used_modelstring · textyes
providerstring · textyes
source_kindstring · textyes
aspectstring · textyes
duration_secstring (decimal) · numericyes
countinteger · int4
voicestring · textyes
input_file_idsstring[] · uuid[]
statusstring · textqueued, running, waiting, succeeded, failed, cancelled
cost_usdstring (decimal) · numeric
refundedboolean · bool
outputsobject · jsonb
errorstring · textyes
favouriteboolean · bool
usesobject · jsonb
surfacestring · text
started_atstring (date-time) · timestamptzyes
finished_atstring (date-time) · timestamptzyes
created_atstring (date-time) · timestamptz
updated_atstring (date-time) · timestamptz
connectionobject · jsonbyes
input_urlsstring[] · text[]
waitingobject · jsonbyes
input_video_idsstring[] · uuid[]
resolutionstring · textyes
toolstring · textyes
input_audio_idsstring[] · uuid[]
brandobject · jsonbyes
harnessstring · textyes
upscaleinteger · int2yes
voice_idstring (uuid) · uuidyes
parent_idstring (uuid) · uuidyescreative_generation
root_idstring (uuid) · uuidyescreative_generation
versioninteger · int2
edit_notestring · textyes
edit_checkobject · jsonbyes
batch_idstring (uuid) · uuidyes
batch_kindstring · textyes
batch_labelstring · textyes
shotstring · textyes
channelstring · textyes
product_idstring (uuid) · uuidyes
source_generation_idstring (uuid) · uuidyescreative_generation
captionobject · jsonbyes
layoutobject · jsonbyes
higgsfieldobject · jsonbyes
studiostring · textyes

Primary key: id

Checks:

  • CHECK (((batch_kind IS NULL) OR (batch_kind = ANY (ARRAY['set'::text, 'batch'::text, 'variations'::text]))))
  • CHECK (((batch_label IS NULL) OR (length(batch_label) <= 120)))
  • CHECK (((count >= 1) AND (count <= 4)))
  • CHECK (((edit_note IS NULL) OR (length(edit_note) <= 2000)))
  • CHECK (((resolution IS NULL) OR (resolution = ANY (ARRAY['480p'::text, '720p'::text, '1080p'::text]))))
  • CHECK (((source_kind IS NULL) OR (source_kind = ANY (ARRAY['native'::text, 'byos'::text, 'byok'::text])))) NOT VALID
  • CHECK (((studio IS NULL) OR (studio = ANY (ARRAY['image'::text, 'video'::text, 'cinema'::text, 'character'::text, 'lipsync'::text, 'motion'::text, 'recast'::text, 'clip'::text, 'layers'::text, 'audio'::text, 'marketing'::text, 'product'::text]))))
  • CHECK (((tool IS NULL) OR (tool = ANY (ARRAY['lip_sync'::text, 'talking_photo'::text, 'face_swap'::text, 'upscale'::text, 'video_edit'::text, 'layout'::text, 'photo_reel'::text, 'higgsfield'::text, 'image_grade'::text]))))
  • CHECK (((upscale IS NULL) OR (upscale = ANY (ARRAY[2, 4]))))
  • CHECK (((version >= 1) AND (version <= 999)))

CreativePost

Table creative_post · Resource creative_posts

  • GET /api/v1/creative_posts
  • GET /api/v1/creative_posts/{id}
ColumnTypeNullableAllowed valuesReferences
idstring (uuid) · uuid
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
created_bystring (uuid) · uuidyesapp_user
generation_idstring (uuid) · uuidyescreative_generation
file_idsstring[] · uuid[]
channelstring · textinstagram, facebook, tiktok, youtube
connection_idstring (uuid) · uuid
connection_labelstring · textyes
captionstring · text
titlestring · textyes
scheduled_atstring (date-time) · timestamptz
statusstring · textscheduled, posting, posted, failed, cancelled
external_idstring · textyes
external_urlstring · textyes
errorstring · textyes
attemptsinteger · int4
posted_atstring (date-time) · timestamptzyes
created_atstring (date-time) · timestamptz
updated_atstring (date-time) · timestamptz

Primary key: id

CreativeVoice

Table creative_voice · Resource creative_voices

  • GET /api/v1/creative_voices
  • GET /api/v1/creative_voices/{id}
ColumnTypeNullableAllowed valuesReferences
idstring (uuid) · uuid
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
created_bystring (uuid) · uuidyesapp_user
namestring · text
providerstring · text
external_voice_idstring · textyes
sample_file_idsstring[] · uuid[]
consent_bystring (uuid) · uuidyesapp_user
consent_atstring (date-time) · timestamptz
source_kindstring · textyes
connection_idstring (uuid) · uuidyes
statusstring · textpending, ready, failed
errorstring · textyes
created_atstring (date-time) · timestamptz
updated_atstring (date-time) · timestamptz

Primary key: id

Checks:

  • CHECK ((provider = 'elevenlabs'::text))
  • CHECK (((source_kind IS NULL) OR (source_kind = 'byok'::text)))

Events

Workflows and webhooks react to these events.

EventWhat happensPayload
creative.failedA generation failed.id, error, recipientUserId
creative.generatedA generation finished; its results are in Files.id, kind, count, recipientUserId
creative.post_failedA social post could not go out.id, channel, error, recipientUserId
creative.post_scheduledA result was scheduled to post on social media.id, channel, generationId, scheduledAt
creative.postedA post went out on Instagram, Facebook, TikTok or YouTube.id, channel, url, recipientUserId
creative.requestedSomebody (or Era, or a workflow) asked for an image, video, voice-over or music.id, kind, preset
creative.usedA result was put on a product, a post, an email or the website.id, target, targetId
creative.voice_requestedSomebody asked to clone a voice (with the speaker’s consent).id, name
Was this page helpful?