Concepts
Concepts
Generate a concept image in a campaign, refine it, and build ads from it or keep it in your swipe file.
A concept is an image generated from your prompt inside a campaign, for when no existing reference fits the idea. Use a ready concept as an ad's reference, refine it into a new version, or save it to your swipe file for later. ID prefix: concept_. Scopes: concepts:read / concepts:write.
Fields
| Field | Type | Notes |
|---|---|---|
id | string | concept_… |
campaign_id | string | |
status | string | generating → ready or failed |
prompt | string | |
aspect_ratio | string | 1:1, 4:5 or 9:16 |
image_url | string or null | Set once ready |
version_number | integer | Refinements count up from the parent |
kept | boolean | Saved to the swipe file |
swipe_file_id | string or null | The swipe file it was saved as |
failure | object or null | { message } |
created_at, updated_at | string |
Endpoints
| Method | Path | What it does |
|---|---|---|
POST | /v1/concepts | Generate (campaign_id, prompt, aspect_ratio, optional parent_concept_id to refine). 202 |
GET | /v1/concepts | List, newest first. Filters: campaign_id, ids, kept |
GET | /v1/concepts/{id} | Get |
POST | /v1/concepts/{id}/swipe-file | Save a ready concept as a swipe file. Free. Also needs swipe_files:write |
DELETE | /v1/concepts/{id}/swipe-file | Un-save it (the swipe file is archived, and can be restored) |
Generate and build from it
const { data: concept } = await sal("/v1/concepts", {
method: "POST",
idempotencyKey: crypto.randomUUID(),
body: {
campaign_id: "cmp_4e8a2c6f1b9d3057",
prompt: "Overhead flat lay of a folded oat hoodie on a wool blanket, morning light, lots of empty space at the top for a headline",
aspect_ratio: "4:5",
},
});
// Poll GET /v1/concepts/{id} until status is "ready", then:
await sal(`/v1/campaigns/${concept.campaign_id}/ads`, {
method: "POST",
idempotencyKey: crypto.randomUUID(),
body: { ads: [{ product_id: productId, audience_id: audienceId, reference: { concept_id: concept.id } }] },
});A concept is charged only when its image lands: the image model's cost plus 30%, rounded up to the cent. A failed concept is free. Building from a concept that isn't ready fails validation.