Workflows
How the work runs: each Team's Processes, the Workflows that run them, what starts each one, and the Approvals they wait on.
A Process is a job the business does again and again, owned by one Role on one Team. Its Workflows run it, the same way whether an agent or a person holds the seat.
| Layer | What it is | Example |
|---|---|---|
| Team | Owns its Processes and the Metrics that judge them | Finance Team |
| Process | The job: its outcome, accountable Role, Settings and service level | Billing |
| Workflow | The steps that do the job, started by a Trigger | Dunning, every day |
| Step | One Verb called as one Role, under its Permissions and Limits; past a Limit it waits on an Approval | Invoice.collect as the Billing Specialist |
| Action | One execution of a Workflow, kept forever | Dunning on the 3rd, done |
Most Processes are on from the first day for every Product Template. You change one by saying what you want.
| You say | Process | It changes |
|---|---|---|
Retry failed payments four times | Billing | dunning.retries |
Ask me before any charge over $500 | Expense approval | spend.askAbove |
Answer new leads within five minutes | Inbound sales | inbound.answerWithin |
Close the books by the fifth business day | Books | close.businessDay |
Pay suppliers on Fridays | Supplier payouts | payouts.day |
Remind me before the annual report is due | Company filings | turns it on |
Answer our phone | Call routing | turns it on |
Each sentence becomes one call:
Retry failed payments four times| Read next | For |
|---|---|
| Processes | Every Process by Team, with its Workflows |
| How a Workflow runs | Steps, failures, service levels, and turning a Process on or off |
| Triggers | The four ways a Workflow starts |
| Approvals | Where a step waits for a yes |
| Rhythm | Every Workflow by when it starts: the operating week |
Guides.
Processes by Team
The number counts each Process’s Workflows.
One Workflow, end to end
- Trigger
Subscription.renewedthe twelfth renewal - Steps
Coupon.create → Subscription.update → Message.createeach durable, each retried - Approval
Approval.approvea high-stakes, one-way step waits for you
You, to your agent
When a customer reaches one year with us, give them a free month and thank them from me.
Ask me before each free month goes out.
# 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' })"
}
}
---
stakes: high
---
## Thank a customer at one year {#one-year-thanks}
When a Subscription renews for the twelfth month, the customer
gets a free month and a note from Dana.
```ts
on.Subscription.renewed(async ($, { subscription }) => {
if (subscription.renewals < 12) return
const coupon = await $.step('coupon', () =>
$.Coupon.create({ percentOff: 100, duration: 'once' }))
// stakes: high, so this one-way step waits for an Approval.
await $.step('apply', () =>
$.Subscription.update({ id: subscription.$id, coupon: coupon.$id }))
await $.step('thank', () =>
$.Message.create({ to: subscription.customer, template: 'one-year' }))
})
```