Endpoints
Brands
A brand is everything Dessert knows about your products: your hero images,
ingredients, tone of voice, color palette, and product catalog. You need at
least one Active brand before you can generate ads.
One brand per account today
In v1 each account is tied to a single brand. Multi-brand orgs are on the
roadmap. The
brand_id field accepts only your own brand for now.
List brands
Returns the brands attached to your account and their onboarding status.
Request
curl
Python
TypeScript
MCP
curl https://api.dessert.dev/v1/brands \
-H "Authorization: Bearer $DESSERT_API_KEY"
requests.get(
"https://api.dessert.dev/v1/brands",
headers={"Authorization": f"Bearer {os.environ['DESSERT_API_KEY']}"},
).json()
await fetch("https://api.dessert.dev/v1/brands", {
headers: { Authorization: `Bearer ${process.env.DESSERT_API_KEY}` },
}).then(r => r.json());
{ "tool": "dessert.list_brands", "arguments": {} }
Response
| Field | Description |
|---|---|
| brand_idstring | Pass to brand_id on POST /v1/ads/generate. |
| namestring | Display name. |
| statusstring | One of Active, Pending Onboarding, Suspended. |
| onboarding_statusstring | More granular pipeline state during onboarding. |
| product_countinteger | Number of active products on the brand. |
| onboarded_atstring | ISO 8601 timestamp the brand became Active. |
{
"brands": [
{
"brand_id": "recXXXXXXXXXXXXXX",
"name": "Aurelia Skincare",
"status": "Active",
"onboarding_status": "Complete",
"product_count": 7,
"onboarded_at": "2026-05-12T15:08:22.000Z"
}
]
}
Create a brand (cold-start ingest)
Kicks off the brand scrape pipeline against your website. The endpoint returns
202 Accepted immediately; the actual ingest runs in the
background for 15–60 minutes. You'll get a webhook/email when the brand is
Active.
This is a one-time onboarding action
Calling
POST /v1/brands on an account that already has a brand
re-runs the scrape against the new URL — useful after a site relaunch, not
for adding additional brands.
Request body
| Field | Description |
|---|---|
| websitestringrequired | Public homepage URL. Must start with http:// or https://. |
curl
Python
TypeScript
MCP
curl https://api.dessert.dev/v1/brands \
-H "Authorization: Bearer $DESSERT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "website": "https://aureliaskincare.com" }'
requests.post(
"https://api.dessert.dev/v1/brands",
headers={"Authorization": f"Bearer {os.environ['DESSERT_API_KEY']}"},
json={"website": "https://aureliaskincare.com"},
).json()
await fetch("https://api.dessert.dev/v1/brands", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.DESSERT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ website: "https://aureliaskincare.com" }),
});
{
"tool": "dessert.create_brand",
"arguments": { "website": "https://aureliaskincare.com" }
}
Response — 202 Accepted
{
"brand_id": "recXXXXXXXXXXXXXX",
"status": "Pending Onboarding",
"message": "Brand scrape started. You will receive an email when ready (typically 15-60 minutes).",
"estimated_completion_minutes": 60
}
While the brand is Pending Onboarding, calls to
POST /v1/ads/generate return
425 brand_onboarding_in_progress. Poll
GET /v1/brands until status flips to
"Active".
Errors
| Status | Code | Cause |
|---|---|---|
| 400 | invalid_website | Missing or malformed URL. |
| 502 | scraper_failed | The brand scraper upstream rejected the request. Safe to retry. |