Generate a campaign draft from a brief
Authoring a multi-channel campaign means filling a dozen slots by hand: an SMS body under 160 characters, an email subject, preview text and body, a WhatsApp category, a fallback order, a send time. The from-brief composer collapses that into one plain-English sentence or two. You type what the campaign should do,POST /campaigns/from-brief returns a typed campaign draft, and the dashboard composer renders it into editable fields. Nothing is persisted and nothing is sent until you review the draft and commit it through the regular campaign creation flow.
This guide covers the request surface, the typed draft shape and why it is typed, the grounding pass that strips claims your brief never made, the limits and failure modes you can hit, and how this surface differs from the other AI authoring entry points.
1. What the from-brief composer does
Send a short natural-language brief, for example:Win back customers who have not ordered in 90 days. SMS first with email fallback, friendly tone, mention the 15% returning-customer discount.The endpoint reads it and returns a structured draft carrying:
name,description,goal: a short title, a one-to-two sentence summary for review, and the primary KPI the brief aims at (“reactivation”, “CTR”, “conversion”).audience: a natural-language audience description plus the rationale for it. The description is written to feedPOST /contacts/segments/from-prompt, which materialises the actual segment.channels: per-channel copy forsms,rcs,whatsapp,email, andpush. Channels the brief does not need, or that you did not list as available, come backnull.recommended_send_timeandscheduled_at_iso:immediate,optimal_per_recipient, orscheduledwith an RFC 3339 timestamp.fallback_chain: the failover sequence across channels, for example["sms", "email"].ab_test: present only when your brief asks for an A/B test, with the two variants and the winner metric.warnings: anything you should know before launch, such as compliance notes, missing brand information, or a send time the composer could not resolve.
POST /campaigns after review. Review-then-send is the contract on every AI authoring surface; generated output is a starting point, never a one-click launch.
2. Endpoint surface
The response envelope is
data.draft (the typed shape from section 1) plus data.model, the model that served the request, and data.usage, the token accounting for the call, attributed to your tenant like any other AI spend.
3. Why the draft is a typed shape
The draft is a fixed JSON shape on purpose. Asked to “write a campaign”, an open-ended model drifts into free-form prose that no form can render. A narrow, typed contract forces the output into exactly the slots the composer draws: a title, per-channel copy, a send time, a fallback order. Each slot has a type and a bound, so a well-formed response loads into the draft form with no re-typing, and a missing or off-shape slot shows up as a flagged field you edit, not as broken prose:- SMS
bodyis at most 160 characters, with no link tokens unless your brief asked for a link. - RCS carries a
bodyplus up to four quick-replysuggestions. - WhatsApp carries a
template_intent, abody, and acategoryrestricted to Meta’s vocabulary:MARKETING,UTILITY, orAUTHENTICATION. - Email carries
subject,preview_text, and a GitHub-flavored markdownbody_markdown. - Push carries a
titleof at most 50 characters and abodyof at most 120.
warnings as part of the contract, not as noise: it is where the composer reports what it could not resolve, from an unresolvable send time to a compliance caveat for your region.
4. Grounding: what the composer refuses to invent
When the model writes copy it can tack on promotional claims your brief never made: urgency (“Limited time offer”, “act now”), scarcity (“last chance”, “while supplies last”), a discount you did not author (“50% off”), or a guarantee (“risk-free”). Unauthored claims are a carrier and consumer-protection liability you never signed off on, so before the draft reaches you the endpoint runs a deterministic grounding pass over every generated copy field, checked against your own brief:- Any sentence that introduces a claim class your brief does not support is removed; the rest of the copy is kept. “Your order history qualifies you for the returning-customer rate. Limited time offer!” keeps the first sentence and loses the second when the brief never said “limited time”.
- An RCS quick-reply label that is entirely an ungrounded claim is dropped from
suggestionsrather than rendered as an empty chip. - A copy field that collapses to empty was entirely fabricated; the composer shows it as an empty, editable slot instead.
- A body minus one sentence carried a fabricated claim. What remains is yours to edit, and if you genuinely want that claim, add it to the brief and regenerate: a claim present in the brief is grounded by definition and survives the pass.
- An empty slot means every sentence the model wrote for it was ungrounded. Treat it as “the model had nothing authorised to say here” and write the slot yourself.
- Grounding checks claim classes, not facts. It will strip “act now” but it cannot verify a statistic or a price. The review pass before launch is still yours.
5. Limits and failure modes
- Draft-only output. The endpoint never persists a campaign and never sends anything. A draft becomes a send only after you commit it with
POST /campaignsand launch it through the normal lifecycle. The draft also makes no promise about deliverability pre-checks: run it through the same pre-launch checks as any authored content. - Send times are guarded. A
scheduled_at_isoin the past (or unparseable) is downgraded torecommended_send_time: "immediate", the timestamp is dropped, and a warning is appended telling you to set the send time in the schedule step. Relative expressions (“tomorrow at 10:00”, “next Monday”) resolve against your workspace timezone whentimezoneis present, and against UTC when it is not, so direct API callers with local-time briefs should always pass it. - Brief too short. Fewer than 8 characters is rejected with a 422 validation error before any generation runs.
- Parse failure. If the model returns something that is not the typed shape, you get
422 AI_PARSE_FAILEDwith a preview of the raw output. Re-run with a clearer brief, or fall back toPOST /campaignswith explicit fields. - Timeout and provider failure. Generation runs under a time budget: a slow provider returns
504 LLM_TIMEOUT, a transient upstream failure returns502 LLM_UPSTREAM_ERROR. Both are retryable; budget your retries rather than looping. - Spend and rate gates. The endpoint sits on the same AI budget and rate limiting as the other generation surfaces. A spend cap, rate limit, or insufficient balance returns the same structured 402 / 429 / 403 / 503 envelope those surfaces return, with the reason and any retry window, and a
503also covers a workspace with no AI provider configured. - Model routing. Requests are served by your platform’s configured model bucket; no model name is fixed in this flow, and
data.modelon the response names the model that served each request.
6. Worked briefs
Three briefs of increasing specificity, each with the draft shape they produce. Field values are illustrative of the shape; your copy will differ.Product launch, minimal brief
Win-back with an authored offer and a send time
Nurture series with an A/B test
warnings rather than silently flattening the series into one blast.
7. How this differs from the adjacent surfaces
The boundaries in one line: from-brief drafts copy for one campaign, journey-from-prompt drafts the orchestration a series of sends runs on, and agents-from-prompt drafts a conversational agent. A journey whose steps need copy can take a from-brief draft’s channel content into each step after review.
See also
- Create a campaign with the wizard: the commit path every draft, generated or hand-built, goes through.
- Author a campaign journey from a natural-language prompt: the journey-level sibling of this surface.
- Template-variable catalogue: the merge fields available inside generated copy.
- LLM spend and the cost attribution model: how generation calls like this one are metered and attributed.
- Campaigns API reference: full request and response shapes for every endpoint cited here.