App ad from a store link: sume-mobile-app-ugc and the 30-file budget
Calling the sume-mobile-app-ugc Format with an app page URL and screenshots: what counts toward the 30-file budget, what does not, and the idempotency key.

To make a UGC-style app ad from your store listing, call the catalog Format sume-mobile-app-ugc at POST /v1/formats/sume/sume-mobile-app-ugc/runs. Put the listing address in input as a plain page URL, and send the screenshots as attachments or as image URLs inside input. A page URL does not count toward the run's media budget. The screenshots do: a run carries at most 30 files, split as at most 30 images, 10 videos and 10 audio files, and Sume counts by file type and not by field name.
Read what the Format takes
The catalog page lists the slug but does not describe the Format. GET /v1/formats/sume/sume-mobile-app-ugc returns its description and io profile. The docs say input is a free-form JSON object of up to 64 top-level keys and 2 MiB, that two callers can send fully different shapes, and that the Format reads the keys it recognizes. So treat any key name in a blog post, including the ones below, as an example, and confirm it against the description.
curl -sS -X POST "https://api.sume.com/v1/formats/sume/sume-mobile-app-ugc/runs" \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: app-1042-ugc-v1" \
-d '{
"instruction": "Vertical 9:16 UGC ad. Hook in the first two seconds, show the three screens, end on the app name.",
"input": {
"app_name": "Trailmix",
"store_url": "https://example.com/apps/trailmix"
},
"attachments": [
{"type": "input_image", "image_url": "https://example.com/shots/home.png"},
{"type": "input_image", "image_url": "https://example.com/shots/map.png"}
],
"generation_spend_cap_usd": 40
}'What counts toward the budget
The rule for input is mechanical. An HTTPS URL at any depth counts if its filename ends in a media extension. A product page URL does not. The same URL counts once, even if it appears twice. Media the agent finds by itself during the run is not yours and does not count. If you go over a limit, the create fails with 400 invalid_attachment, before any generation spend.
| Item you send | Counts? | Why |
|---|---|---|
| Store page URL in input | No | No media extension in the filename |
| Screenshot PNG in attachments | Yes, one image | Attachments are images |
| Same screenshot URL in input and attachments | Yes, once | The same URL counts one time |
| Voiceover .mp3 URL in input | Yes, one audio | Counted by file type |
| Clip the agent finds during the run | No | Not provided by you |
Spend cap and idempotency
A run without generation_spend_cap_usd inherits the Format's cap, and a Format that names none reports the platform default of $400. A number up to 500 is accepted as written, null means the platform maximum of $500, and 0 is rejected. For a short app ad, set a cap that matches the budget you approved for that one ad, not the default.
Derive the Idempotency-Key from the app id and a version you bump when you want a re-run. The same key with the same body returns the original receipt with idempotency_hit: true and no second charge. The same key with a different instruction or a different attachment list is 409 idempotency_conflict. The scope of a key is one Format.
Get the video
The create returns 202 with a receipt. Store data.id. Either send communication.webhook_url and take one signed terminal POST, or poll GET /v1/format-runs/{run_id} with growing gaps. The docs warn that long video is 15 to 30 minutes of work, and that a 429 or 503 during polling is temporary because the run continues. Read the file from the receipt's primary_output_url, or bind an output_schema if your code needs a typed object. A failed run still keeps the media it made in artifacts[], so look there before you pay for a rerun. The receipt is also where you read usage.billable_amount_usd_micros, which is the number to compare with the cap you set.
Sources
Related posts
More in Formats
- Audit who can run your Format: list grants, pending versus accepted
GET .../grants lists pending and accepted workspace grants on a Format, newest first, without revoked ones. Script a weekly audit and revoke what is stale.
- Back-in-stock video for one SKU: send the facts as input, not prose
One restock clip is one Format run: put SKU, stock count and ship date in an input object, add a short instruction, and key the run by SKU and date.
- Black Friday ad copy and video in one call: an output_schema example
Bind an output_schema with headline, caption and a SumeMediaFile video so one Format run returns typed copy and the clip together, with primary_output_key set.
- Bulk queue concurrency 16 but fewer runs start: workspace concurrency
Concurrency 16 is a ceiling on the queue, not a promise. Workspace generation concurrency still applies to every child, so some start late or fail to start.
Written by Sume