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

GET https://api.dessert.dev/v1/brands Try it →

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

FieldDescription
brand_idstringPass to brand_id on POST /v1/ads/generate.
namestringDisplay name.
statusstringOne of Active, Pending Onboarding, Suspended.
onboarding_statusstringMore granular pipeline state during onboarding.
product_countintegerNumber of active products on the brand.
onboarded_atstringISO 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)

POST https://api.dessert.dev/v1/brands Try it →

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

FieldDescription
websitestringrequiredPublic 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

StatusCodeCause
400invalid_websiteMissing or malformed URL.
502scraper_failedThe brand scraper upstream rejected the request. Safe to retry.