Start a Studio make in the background
- Credentials
- OAuth access token
- Scopes
ai:spend- Subscription
- Needs an active plan. Otherwise
403 subscription_locked. - Daily limit
- AI generations, 300 a day per store. Over the limit is
429 rate_limited. - Idempotency
- Send an
Idempotency-Keyheader. A retry with the same key does the work once.
Answers at once with a running job; follow it with getStudioJob. Credits are charged only when the make comes out (a video or promo is charged at the start and given back if it fails). kind picks the make: adset, listing and translate and week write words (the job's result); logo, edit, voice and music add a file to the Library. A photo is a Library id, or the URL of one of the business's own stored photos. video (8 seconds from one photo) and promo (a storyboard written from the shop's listings and reviews, with voice and music) take a few minutes: follow them with getStudioJob. Owner or admin.
Storage: refused with 403 plan_limit when it would take the Library over the plan's storage. What is already stored stays.
Access: OAuth scope ai:spend; write-gated by the subscription.
merchantOAuth ai:spendAuthorizationBearer <token>OAuth 2.1 (authorization code + PKCE S256, public clients, dynamic registration) for connected AI apps. Effective power is scopes granted AND the person's role today AND the plan. orders:refund, billing:write and team:write are opt-in on the consent screen. Write implies read for marketing:read and messages:read, so a grant holding marketing:write passes a marketing:read check, and messages:send passes messages:read.
Scope: ai:spend
storeId*stringA store the person can reach. Any other id answers 404, never 403.
Idempotency-Key*stringRequired on every write. Minted on the device when the person taps, reused on every retry. A write without one, or with one that does not match the pattern, is refused with 422 validation_error. Scoped to the token's subject, remembered 24 hours. A replay returns the first 2xx response with Idempotent-Replay: true; a request still running answers 409 in_flight; the same key with a different method, path or body answers 409 idempotency_key_reused; non-2xx results are not remembered. If the key store cannot be read nothing is processed and the answer is 503 idempotency_unavailable: retry with the same key.
^[A-Za-z0-9_-]{8,128}$application/json- body
kind*string"adset""listing""translate""week""logo""edit""voice""music""video""promo"photo?stringFor adset, listing, edit and video. A Library id, or the URL of a stored photo of the business.
goal?stringFor adset.
"sales""new""visit""whatsapp"brief?stringFor adset and week. The merchant's own words.
length <= 300listingId?stringFor translate.
to?stringFor translate.
"af""zu""xh""st""tn""nso"style?stringFor logo.
"icon""wordmark""playful""minimal""elegant"idea?stringFor logo.
length <= 200change?stringFor edit.
"cutout""enhance""expand""edit""scene"scene?stringFor edit with scene. A preset id or the merchant's words.
length <= 300instruction?stringFor edit with edit. The change in words.
length <= 300text?stringFor voice.
length <= 600voice?stringFor voice. Defaults to Kore.
description?stringFor music.
length <= 300shot?stringFor video. A shot id (e.g. spin), or the motion in the merchant's words. Defaults to spin.
length <= 300about?stringFor promo. What the promo is about, in the merchant's words.
3 <= length <= 600seconds?integerFor promo. Length in seconds. Defaults to 15.
152030listingIds?array<string>For promo. Listings to show. Leave out to let it pick.
items <= 6tone?stringFor promo.
"auto""bold""cinematic""playful""clean"music?stringFor promo. ai makes music for this promo.
"ai""upbeat""chill""warm""none"Created
application/json- response
data*curl -X POST 'https://api.shopeazy.co/v1/merchant/stores/<storeId>/studio/makes' \ -H 'Authorization: Bearer <access_token>' \ -H 'Idempotency-Key: <unique_key>' \ -H 'Content-Type: application/json' \ -d '{ "kind": "adset"}'{ "data": { "id": "string", "kind": "string", "status": "running", "label": "string", "result": null, "files": [ { "id": "string", "kind": "string", "media": "image", "category": "string", "url": "string", "posterUrl": "string", "about": "string", "versionOf": "string", "usedIn": [ { "kind": "string", "id": "string" } ], "uses": 0, "createdAt": 0 } ], "error": "string", "createdAt": 0 }}What is making now GET
The Making tray: every make that is running, and the ones that finished in the last few minutes, so a client that was closed can find them again. `getStudioJob` follows one job by id. Paged: `{ items, nextCursor }`, `limit` (default 30, at most 100) and an opaque `cursor`. Access: OAuth scope `store:read`; not write-gated.
Shoot a product: N takes of one brief POST
Takes of the same brief, one after another (the image model rate-limits, and four good takes beat three rejected at once), each metered and saved on its own: a failure half way leaves the takes that came out in the Library and charges only for those (`creditsSpent`, `failed`). Running out of credits after the first take stops the rest; before the first it is 403 `insufficient_credits`. A `strict` fidelity cuts the product out once first (`studio.removeBg`), charged with the first take that comes out; a shoot that gives nothing costs nothing. If none came out: 422 `validation_error`. It answers when all takes are done, which can be a few minutes at `variants: 4`; clients use a long timeout. The `Idempotency-Key` keeps a retry from shooting, and paying for, the brief again. Make the follow-ups with `refineShot` and put a take on a listing with `addLibraryAssetToProduct`. Costs are in `getStudioCosts`. Access: OAuth scope `ai:spend`; write-gated by the subscription.