Quickstart
Generate your first batch of skincare ads in five minutes. The Dessert AI API takes a brand reference and a few creative parameters, and returns finished static + video ads sized for paid social.
1. Get an API key
Sign up at app.dessert.dev. Your account starts with 50 welcome credits — enough for ten static ads or three full video ads. Find your key in the dashboard under Settings → API keys. Keys look like:
dsrt_live_1f9c83bd6c4a2e7081ba9d5e4f2c1a30
Treat it like a password — see Authentication for storage and rotation.
2. Onboard your brand
When you sign up we kick off an automated brand scrape: your website, product
pages, hero images, ingredients, and tone of voice. Onboarding typically
finishes in 15–60 minutes. You'll receive an email when the brand is
Active and ready to generate ads.
You can also trigger or re-trigger a scrape via POST /v1/brands.
3. Generate your first ad
Once your brand is Active, call
POST /v1/ads/generate. The default
request below makes one full ad (static + animated video, both
vertical 9:16 and square 4:5 sizes) using your brand's default tone, with
Dessert auto-selecting the copy angle and animation style.
curl https://api.dessert.dev/v1/ads/generate \
-H "Authorization: Bearer $DESSERT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"count": 1,
"format": "full"
}'
import os, requests
r = requests.post(
"https://api.dessert.dev/v1/ads/generate",
headers={"Authorization": f"Bearer {os.environ['DESSERT_API_KEY']}"},
json={"count": 1, "format": "full"},
timeout=30,
)
r.raise_for_status()
delivery = r.json()
print(delivery["delivery_id"], delivery["status_url"])
const res = await fetch("https://api.dessert.dev/v1/ads/generate", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.DESSERT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ count: 1, format: "full" }),
});
const delivery = await res.json();
console.log(delivery.delivery_id, delivery.status_url);
// Inside Claude Desktop or any MCP host, call:
{
"tool": "dessert.generate_ads",
"arguments": {
"count": 1,
"format": "full"
}
}
You'll get back a delivery_id and a status URL:
{
"delivery_id": "recXXXXXXXXXXXXXX",
"status": "queued",
"request_id": "req_a1b2c3d4e5f6...",
"ad_count_expected": 1,
"format": "full",
"credits_charged": 15,
"credits_balance_after": 35,
"status_url": "https://api.dessert.dev/v1/deliveries/recXXXXXXXXXXXXXX",
"eta_seconds": 480
}
4. Poll for results
Full ads render in roughly 6–9 minutes. Poll the status URL every 15–30 seconds, or skip the poll loop and pass a webhook_url on the original request — we'll POST to it when the delivery completes.
curl https://api.dessert.dev/v1/deliveries/recXXXXXXXXXXXXXX \
-H "Authorization: Bearer $DESSERT_API_KEY"
import time, requests, os
while True:
r = requests.get(
f"https://api.dessert.dev/v1/deliveries/{delivery['delivery_id']}",
headers={"Authorization": f"Bearer {os.environ['DESSERT_API_KEY']}"},
)
body = r.json()
if body["status"] in ("completed", "failed"):
break
time.sleep(20)
for ad in body["ads"]:
print(ad["orientation"], ad["static_url"], ad["video_url"])
while (true) {
const res = await fetch(`https://api.dessert.dev/v1/deliveries/${id}`, {
headers: { Authorization: `Bearer ${process.env.DESSERT_API_KEY}` },
});
const body = await res.json();
if (body.status === "completed" || body.status === "failed") {
console.log(body.ads);
break;
}
await new Promise(r => setTimeout(r, 20_000));
}
{
"tool": "dessert.get_delivery",
"arguments": { "delivery_id": "recXXXXXXXXXXXXXX" }
}
When status flips to completed, the
ads[] array contains hosted static_url (PNG/JPG) and
video_url (MP4) for each generated ad, plus a
viewer_url for the human-friendly review page.
What's next
- Generate ads — every knob (count, format, copy angle, animation style, in-situ).
- Style search — find the right animation prompts for your brand.
- MCP setup — call Dessert from Claude Desktop or any agent loop.
- Webhooks — get pinged the moment a delivery finishes.
- Credits & pricing — how billing works.