# Automate a workflow

URL: /workflows/automate-a-workflow · Id: `guide:automate-a-workflow`

> Say "thank every customer at one year with a free month" and get a Process, its Workflow and Trigger, a Stripe Coupon and the emails.

Say what should happen and when. Your agent adds a small [Process](/business/nouns/process) with one [Workflow](/business/nouns/workflow) and the [Trigger](/business/nouns/trigger) that starts it.

Needs: [Startup](/business/nouns/startup)

**Before it runs**

- You leave the chat: Never: it all happens in the chat.
- First question at Live: “Ask you first for any customer above $100 a month?”

## What you get
- 1 Process named First-year thanks, owned by the Customer Team (Process)
- 1 Workflow with three steps, each retried up to three times (Workflow)
- 1 trigger on every renewed subscription (Trigger)
- 1 coupon for one free month (Coupon)
- 1 thank-you email from your address, per customer at one year (Message)
- 1 free month on that customer’s next bill (Invoice)
- 1 run record per renewal, with each step’s result (Action)

## Your agent does
**For agents**

- Guide: `guide:automate-a-workflow`, status `beta`. Page: [/workflows/automate-a-workflow.md](/workflows/automate-a-workflow.md).
- Approval: none. Run it when the founder asks.
- Leaves the chat: never.
- Needs first: [Startup](/business/nouns/startup).
- Run: call the steps in order, each through the API, SDK, CLI or MCP tab below; a later step passes the `$id` an earlier one returns. Each value marked example is the sample business’s: pass the founder’s own.

| Step | Verb | Inputs (type, required, this guide’s value) | Returns |
| --- | --- | --- | --- |
| 1 | [`Process.create`](/business/nouns/process/create) (`verb:Process.create`) | `name` string, required: example `"First-year thanks"` | `process` Process |
| 2 | [`Coupon.create`](/business/nouns/coupon/create) (`verb:Coupon.create`) | `percentOff` number: example `100`; `duration` string, required: example `"once"` | `coupon` Coupon |
| 3 | [`Workflow.create`](/business/nouns/workflow/create) (`verb:Workflow.create`) | `steps` json, required: example `{"check":"Stop unless this renewal starts the second year.","thank":"Email the Customer a thank-you from dana@leaseline.app.","credit":"Apply the free-month Coupon to the next Invoice."}`; `retries` integer: example `3` | `workflow` Workflow |
| 4 | [`Trigger.create`](/business/nouns/trigger/create) (`verb:Trigger.create`) | `event` string: example `"Subscription.renewed"` | `trigger` Trigger |

Returns: the last call answers with `trigger` and its `action`, whose `status` is `done`, `pending` (waiting on an Approval or a Worker), `failed`, `canceled` or `refused`:

```json
{
  "api": "https://api.sb/leaseline.app",
  "trigger": {
    "$id": "https://api.sb/leaseline.app/triggers/trigger_1",
    "$type": "Trigger",
    "event": "Subscription.renewed"
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_1",
    "operation": "Trigger.create",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/leaseline.app/actions/action_1"
  }
}
```

Next: offer “Ask me first for anyone paying more than $100 a month”, or “Send it at two years too, with two free months”.

Calls: `Process.create` → `Coupon.create` → `Workflow.create` → `Trigger.create`

Ask:

```text
When a customer reaches one year with us, email them a thank-you from me and give them a free month?
Thank every customer on their first anniversary and take a month off their next bill.
Reward one-year customers with a note from me and a free month.
```

API:

```bash
# 1. Process.create
curl -X POST https://api.sb/leaseline.app/processes \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"First-year thanks"}'

# 2. Coupon.create
curl -X POST https://api.sb/leaseline.app/coupons \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"duration":"once","percentOff":100}'

# 3. Workflow.create
curl -X POST https://api.sb/leaseline.app/workflows \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"steps":{"check":"Stop unless this renewal starts the second year.","thank":"Email the Customer a thank-you from dana@leaseline.app.","credit":"Apply the free-month Coupon to the next Invoice."},"retries":3}'

# 4. Trigger.create
curl -X POST https://api.sb/leaseline.app/triggers \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event":"Subscription.renewed"}'
```

SDK:

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

await $.Process.create({ name: 'First-year thanks' })
await $.Coupon.create({ duration: 'once', percentOff: 100 })
await $.Workflow.create({ steps: { check: 'Stop unless this renewal starts the second year.', thank: 'Email the Customer a thank-you from dana@leaseline.app.', credit: 'Apply the free-month Coupon to the next Invoice.' }, retries: 3 })
await $.Trigger.create({ event: 'Subscription.renewed' })
```

CLI:

```bash
npx startup-builder do Process.create --json '{"name":"First-year thanks"}'
npx startup-builder do Coupon.create --json '{"duration":"once","percentOff":100}'
npx startup-builder do Workflow.create --json '{"steps":{"check":"Stop unless this renewal starts the second year.","thank":"Email the Customer a thank-you from dana@leaseline.app.","credit":"Apply the free-month Coupon to the next Invoice."},"retries":3}'
npx startup-builder do Trigger.create --json '{"event":"Subscription.renewed"}'
```

MCP:

```json
{
  "name": "do",
  "arguments": {
    "code": "await $.Process.create({ name: 'First-year thanks' })\nawait $.Coupon.create({ duration: 'once', percentOff: 100 })\nawait $.Workflow.create({ steps: { check: 'Stop unless this renewal starts the second year.', thank: 'Email the Customer a thank-you from dana@leaseline.app.', credit: 'Apply the free-month Coupon to the next Invoice.' }, retries: 3 })\nreturn await $.Trigger.create({ event: 'Subscription.renewed' })"
  }
}
```

## Change it
- Ask me first for anyone paying more than $100 a month.
- Send it at two years too, with two free months.
- Wait a day after the renewal before sending the email.

## Under the hood
- Systems: [Success](/systems/success), [Billing](/systems/billing), [Mailboxes](/systems/mailboxes)
- Nouns: [Process](/business/nouns/process), [Workflow](/business/nouns/workflow), [Trigger](/business/nouns/trigger), [Coupon](/business/nouns/coupon), [Subscription](/business/nouns/subscription), [Message](/business/nouns/message), [Action](/business/nouns/action)
- Events: `Process.created`, `Coupon.created`, `Workflow.created`, `Trigger.created`, [`Subscription.renewed`](/business/events/Subscription.renewed)
- Stripe objects: `Coupon`, `Discount`, `Subscription`, `Invoice`

An automation is a rule, not judgment: one [Event](/business/nouns/event) starts it and the response is fixed. It makes no model call and costs nothing per [Action](/business/nouns/action). Work that needs judgment, like answering a [Customer](/business/nouns/customer), stays with a [Role](/business/nouns/role)'s [Agent](/business/nouns/agent).

It acts with its accountable Role's authority, never more: each call passes that Role's [Permissions](/business/nouns/permission) and [Limits](/business/nouns/limit). A call over a Limit becomes an [Approval](/business/nouns/approval), and a one-way [Verb](/business/nouns/verb) waits out its delay window.

Each execution is an Action. A failed step retries; an Action that still cannot finish becomes a [Task](/business/nouns/task) for the accountable Role. The file is a [Workflow](/code/file-conventions/workflows) in its Process folder, and removing it stops the automation.