---
name: showpilot-launch-an-offer
description: Put a new offer in front of the right visitors on a ShowPilot site — the copy, what converting collects, and who sees it. Use when something has shipped, an event needs registrations, or a campaign needs a landing play.
---

# Launch an offer

An offer is the play the agent delivers: a line of copy, optional quick replies, a button bound to a real action, and a contract for what converting collects. This drafts one, checks it, and puts it live.

## Steps

1. `whoami`. If the workspace was defaulted, ask which one now — a write will refuse otherwise, and that is deliberate.
2. `draft_offer` with a brief in plain language. Say who it is for and what it should say:

   > Invite pricing-page visitors who came from our LinkedIn ads to the June security webinar. Ask for their email and company.

3. Read the three things that come back beside the offer, and show them to the person:
   - `rationale` — what it set and why
   - `confirm` — what they must check: a campaign value it guessed, a date it inferred
   - `unavailable` — anything the brief asked for that this workspace does not have, and was dropped
4. Fix what `confirm` raises. A guessed `utm` value is the usual one, and it is worth getting right — wrong and the offer shows to nobody.
5. `execute create_offer` with the draft's `offer` object.
6. The offer is live for the agent immediately but shows nothing on the site, because a draft always comes back with `deploy.live: false`. When the gates are right, `execute update_offer` with `deploy.live: true`.

## Rules

- `draft_offer` writes nothing. Nothing exists until step 5.
- Never flip `deploy.live` to `true` in the same breath as creating the offer. Show the gates first. Every gate removes people who would have seen it, and the cost of a wrong gate is silence.
- The CRM and industry gates fail closed: a visitor ShowPilot cannot resolve never sees the offer. If the brief said "existing customers", expect a smaller audience than the person imagines, and say so.
- A button needs an action and an action needs a button. The API refuses one without the other, so do not fight it.
- Retire an offer with `isActive: false`. There is no delete, because an offer carries its own lifetime counts.
- Check `stats.acceptRate` a few days later. `null` means nobody has seen it, which usually means a gate is wrong, not that the copy is.
