Skip to content

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.

For developers

Say what should happen and when. Your agent adds a small Process with one Workflow and the Trigger that starts it.

For developers

Needs Startup

What you get

  • 1Process named First-year thanks, owned by the Customer TeamProcess
  • 1Workflow with three steps, each retried up to three timesWorkflow
  • 1trigger on every renewed subscriptionTrigger
  • 1coupon for one free monthCoupon
  • 1thank-you email from your address, per customer at one yearMessage
  • 1free month on that customer’s next billInvoice
  • 1run record per renewal, with each step’s resultAction

Your agent does

Process.create → Coupon.create → Workflow.create → Trigger.create
You, to your agent

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.

# 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"}'
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' })
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"}'
{
  "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, Billing, Mailboxes
Nouns
Process, Workflow, Trigger, Coupon, Subscription, Message, Action
Events
Process.created, Coupon.created, Workflow.created, Trigger.created, Subscription.renewed
Stripe objects
Coupon, Discount, Subscription, Invoice

An automation is a rule, not judgment: one Event starts it and the response is fixed. It makes no model call and costs nothing per Action. Work that needs judgment, like answering a Customer, stays with a Role's Agent.

It acts with its accountable Role's authority, never more: each call passes that Role's Permissions and Limits. A call over a Limit becomes an Approval, and a one-way Verb waits out its delay window.

Each execution is an Action. A failed step retries; an Action that still cannot finish becomes a Task for the accountable Role. The file is a Workflow in its Process folder, and removing it stops the automation.