URL: /capabilities/check-ai-answers/agent-ready-offer · Id: `page:/capabilities/check-ai-answers/agent-ready-offer`

# Agent-ready offer

> Make your plan one that ChatGPT, Claude, Gemini and Perplexity can find, price and buy, and prove it with 10 test purchases.

Make your plan one that ChatGPT, Claude, Gemini and Perplexity can find, price and buy, and prove it with 10 test purchases.

```text title="Run it · Ask"
Make Leaseline’s monthly plan buyable by AI assistants, prove it with a finished purchase on each, spend up to $3, and show me the plan first.
```

```ts title="Run it · SDK"
import { $ } from 'startup-builder'

const result = await $.try.Offer.syndicate({ goal: 'Make Leaseline’s monthly plan buyable by AI assistants, prove it with a finished purchase on each, spend up to $3, and show me the plan first.', budget: { amount: 3, currency: 'USD' } })
```

```json title="Run it · Response"
{
  "mode": "try",
  "stored": false,
  "estimate": "About $2.91 per 10 buyer tasks",
  "sample": {
    "assistant": "Perplexity",
    "task": "Find rent tracking for my 60 units under $200 a month, and set it up",
    "finished": "no",
    "stopped at": "pay: asked for a billing phone",
    "fix": "phone made optional, same day"
  }
}
```

- **Kind:** Workflow
- **Price:** $2.91 per 10 tasks
- **Your time:** 15 minutes
- **Approval:** Goes out on its own
- **Deepens:** [`process:launches`](https://startupbuilder.dev/workflows/processes/launches)
- **Default limits:** [What waits for you](/capabilities/agents#what-waits)

## What you get
- **10 buyer tasks**, as [`noun:offer`](https://startupbuilder.dev/business/nouns/offer) records
- `feed` · One catalog row per offer variant, as Stripe’s catalog feed holds it: name, price, limits and the checkout tool.
- `listings[]` · The Stripe Directory and the MCP registry, each `submitted` or `live`, read back daily.
- `runs[]` · Each buyer task: the assistant, the task, `finished` or not, and the step it stopped at.
- `runs[].fix` · What changed so the next run finishes, and when.
- `priceMatches` · Whether every price an assistant stated equals your price file and the Stripe Price.

**Connect once:** [Stripe agentic commerce](/code/integrations/stripe-agentic-commerce). **How long:** About 25 minutes for the 10 buyer tasks, two assistants at a time; the Stripe Directory lists you in days.

## Trigger
It runs once when you publish an offer; then the feed syncs every day and the buyer tasks run every week.

```ts
every.week(($) => $.Offer.syndicate({ offer: 'offers/pro', tasks: 10 }))
```

## Steps
Your agent does these steps, one row per step; each step’s check is part of its row and its price.

| Step | Verb | Returns | Price | Approval |
| --- | --- | --- | --- | --- |
| 1. Build the price file from your Stripe Prices | `Collection.query` | Every offer variant with its Price, limits and checkout, equal to the Stripe Prices | Free | Runs on its own |
| 2. Write one catalog feed row per offer variant for Stripe’s catalog feed | `Offer.publish` | One row per variant: what it is for, the price, the limits and the checkout tool | About 1.2¢ | Goes out on its own |
| 3. Check the checkout tool with a test payment token in try mode | `Order.pay` | Per assistant: the tool answers, takes the token, and returns the account and its key in one reply | About 32¢ | Runs within your limits |
| 4. Submit to the Stripe Directory and the MCP registry | [`Post.publish`](/code/apps/social/publish) | Both listings submitted from your own accounts, then read back daily until live | Free | Goes out on its own |
| 5. Run 10 buyer tasks across ChatGPT 3 · Claude 3 · Gemini 2 · Perplexity 2, each paid with a 100% eval coupon | `Order.place` | Each task finished, or stopped at a named step: find, pick, price, pay or key | About $2.56 | Runs within your limits |
| 6. Write the readout | `Collection.query` | Per assistant: finished or the step it stopped at, the fix, and each stated price against your price file | About 2¢ | Runs on its own |

Calls: `Collection.query`, then `Offer.publish`, then `Order.pay`, then `Post.publish`, then `Order.place`, then `Collection.query`.

About $2.91 per 10 buyer tasks, each time it runs, capped at $3.00.

## Example: give it a goal
> Make Leaseline’s monthly plan buyable by AI assistants, prove it with a finished purchase on each, spend up to $3, and show me the plan first.

The plan it shows runs 6 steps, priced before it spends anything; Run it above shows the result it returns.

## When something fails

| When | Then |
| --- | --- |
| An assistant stops before it pays | The run records the step and what the assistant asked for, and an Issue names the field or call to change; the next run reads it again. |
| An assistant states a price your price file does not hold | `priceMatches` reads `false`, the feed rows stop, and your agent re-syncs from the Stripe Prices before anything else runs. |
| The Stripe Directory has not listed you yet | The listing stays `submitted`, read back daily; the buyer tasks still run on the four assistants. |
| You call it again the same day | It returns the stored run at $0, keyed on offer, assistants and day. |

Each step retries three times, then falls through to the next route; one item's failure lands in `skipped` with its reason, never failing the call. Before a step would cross `maxCost` it stops and returns what it has, with a `resume` link. Each step's idempotency key is the call's key plus the step and the item: `leaseline-offer-syndicate-1-<step>-<item>`.

## Change it
| Ask | Compiles to |
| --- | --- |
| Add Google’s AI Mode to the assistants. | [`Offer.syndicate`](/capabilities/check-ai-answers/agent-ready-offer) |
| List my pilot too, with its own checkout. | `Offer.publish` |
| Run the buyer tasks every week and tell me what changed. | [`Offer.syndicate`](/capabilities/check-ai-answers/agent-ready-offer) |

```ts
import { $, workflow } from 'startup-builder'

export default workflow({
  name: 'offer-syndicate',
  verb: 'Offer.syndicate',
  input: { offer: 'string', assistants: 'string[]', tasks: 'integer' },
  maxCost: 3,
  execute: async (ctx, { offer, assistants = ['chatgpt', 'claude', 'gemini', 'perplexity'], tasks = 10 }) => {
    const prices = await ctx.step('price-file', () => $.Collection.query({ from: 'price', where: `offer = '${offer}'` }))
    const feed = await ctx.step('feed', () => $.Offer.publish({ offer, to: 'stripe-catalog', rows: prices }))
    const check = await ctx.step('checkout', () => $.Order.pay({ offer, token: 'test', assistants, mode: 'try' }))
    const listed = await ctx.step('listings', () => $.Post.publish({ venues: ['stripe-directory', 'mcp-registry'], offer }))
    const runs = await ctx.step('buyer-tasks', () => $.Order.place({ offer, tasks, assistants, coupon: 'eval-100' }))
    return readoutOf(feed, check, listed, runs)
  },
})
```

Extend it with `extends: 'Offer.syndicate'` and `base()`, or [compose your own](/code/compose) from these steps.

## Works with
**Plays that order it:** [Get bought by agents](/plays/agent-checkout), [Keyless signup](/plays/keyless-signup).

It serves [Check AI answers](/capabilities/check-ai-answers), and runs in [Launch and search](/strategy/launch-and-search). It deepens [`process:launches`](https://startupbuilder.dev/workflows/processes/launches).

## For agents

| Fact | Value |
| --- | --- |
| Guide | `Offer.syndicate` |
| Guide approval | `limits` |
| Goal | Make Leaseline’s monthly plan buyable by AI assistants, prove it with a finished purchase on each, spend up to $3, and show me the plan first. It may change counts, the order of steps, soft filters and the route a read takes, and it stops early when the goal is met. It never relaxes your words, raises its own budget, answers its own approval, calls a Play or acts outside your standing approval. |
| Trigger | `every.week(($) => $.Offer.syndicate({ offer: 'offers/pro', tasks: 10 }))` |
| Retry | Three times with backoff, then the next route; the same idempotency key never charges, sends or posts twice |
| Idempotency key | `leaseline-offer-syndicate-1` |
| Lookups | A `find:` input asks unless exactly one record fits |

| Step | Action class | Seat rule that would hold it |
| --- | --- | --- |
| 1. Build the price file from your Stripe Prices | None | None. |
| 2. Write one catalog feed row per offer variant for Stripe’s catalog feed | `publish` | None. |
| 3. Check the checkout tool with a test payment token in try mode | `spend` | None. |
| 4. Submit to the Stripe Directory and the MCP registry | `publish` | None. |
| 5. Run 10 buyer tasks across ChatGPT 3 · Claude 3 · Gemini 2 · Perplexity 2, each paid with a 100% eval coupon | `spend` | None. |
| 6. Write the readout | None | None. |

Steps 2 and 4 reach people outside your records and go out on their own within your limits.

| Step | Function | Doer | Checker | Assurance | Inputs |
| --- | --- | --- | --- | --- | --- |
| 1. Build the price file from your Stripe Prices | `code` | Code | Code checks each result against its declared type | `measured` | `$0.offer` |
| 2. Write one catalog feed row per offer variant for Stripe’s catalog feed | `agentic` | The `role:integration-engineer` agent | A second model grades the output | `graded` | `$1.variants` |
| 3. Check the checkout tool with a test payment token in try mode | `agentic` | The `role:tester` agent | Code reads the result back from where it landed | `measured` | `$2.feed, $0.assistants` |
| 4. Submit to the Stripe Directory and the MCP registry | `code` | Code | Code reads the result back from where it landed | `measured` | `$2.feed` |
| 5. Run 10 buyer tasks across ChatGPT 3 · Claude 3 · Gemini 2 · Perplexity 2, each paid with a 100% eval coupon | `agentic` | The `role:tester` agent | Code reads the result back from where it landed | `measured` | `$0.tasks, $0.assistants` |
| 6. Write the readout | `agentic` | The `role:analyst` agent | A second model grades the output | `graded` | `$3, $5` |

Code does steps 1 and 4; The `role:integration-engineer` agent does step 2; The `role:tester` agent does steps 3 and 5; and the `role:analyst` agent does step 6. A second model checks the 2 graded steps, never the one that wrote it, so the whole call is `graded`.

## Under the hood

| Kind | What it touches |
| --- | --- |
| Systems | [Social](/code/apps/social) |
| Nouns | [`noun:collection`](https://startupbuilder.dev/business/nouns/collection), [`noun:offer`](https://startupbuilder.dev/business/nouns/offer), [`noun:order`](https://startupbuilder.dev/business/nouns/order), [`noun:post`](https://startupbuilder.dev/business/nouns/post) |
| Events | `Collection.queried`, `Offer.published`, `Order.paid`, `Post.published`, `Order.placed` |

## Reference

| Name | Type | Default | Meaning |
| --- | --- | --- | --- |
| `offer` | `Offer` | Required | The offer to make buyable. Its Prices, variants and limits come from your Stripe Prices. |
| `assistants` | `VenueId[]` | `['chatgpt', 'claude', 'gemini', 'perplexity']` | The AI assistants the buyer tasks run on. |
| `tasks` | `integer` | `10` | Buyer tasks, each written in a buyer’s words, split across the assistants: 3, 3, 2 and 2 at the default. |
| `maxCost` | `number` | `3.00` | The most this call spends each time it runs, in USD. It stops before a step would cross it and returns what it has, with a `resume` link. |

Emits `Offer.syndicated`. Refuses with [`max-cost`](/code/refusals#max-cost) before it spends, and with the Data calls and Accounts groups ([refusals](/code/refusals)).