Skip to content

Routine YAML reference โ€‹

A custom routine is a saved, multi-step procedure one of your agents runs on your behalf. There are two ways to build one:

  • Describe it in chat โ€” tell your Personal Assistant what you want and it writes the routine for you. That's the Custom routines page, and it's the easiest path.
  • Write the YAML yourself โ€” open a custom routine in the built-in editor and edit its spec directly as text. That's this page: the full schema, every field, and worked examples for power users who'd rather type than talk.

Both paths produce the exact same thing. Anything you can describe in chat you can also write as YAML, and a routine the assistant wrote is just YAML you can open and tweak.

This is the power-user reference

YAML, cron expressions, and {input}/{previous} tokens all show up here โ€” that's the point. If that's not your thing, the conversational path gets you the same routine without touching a single field.

Opening the editor โ€‹

The editor is a real YAML text editor (syntax highlighting, inline errors) that lives on an agent's Tasks tab.

Toโ€ฆDo this
Edit an existing custom routineClick the Edit button on the routine's card. It loads the routine's current spec as YAML. (On the global Tasks page and the lobby, where there's no per-agent editor, the same thing lives in the card's โ‹ฎ "Manage routine" menu โ†’ Edit as text.)
Create one from scratchOn an agent's Tasks tab, click + New routine. It seeds a starter template already homed on that agent โ€” overwrite the fields and Save.

A custom routine card with a Run button, an Edit button that opens the YAML editor, and an Open button โ€” built-in routines have no Edit button

The editor scrolls top to bottom: your YAML first, then the Automations panel (schedules + triggers โ€” see Scheduling and Triggering), and the Save and Cancel buttons at the very bottom, after the Automations section โ€” so a long routine and its automations read as one page.

The inline routine editor: the spec YAML with syntax highlighting up top, and the start of the Automations panel below it

When you press Save, MyChatBot validates the spec:

  • Valid โ†’ the routine is saved (or created) and the card refreshes.
  • Invalid โ†’ a red "This routine has problems:" box lists every problem at once, and the editor stays open with your text intact so you can fix them and Save again. Nothing is saved until it's valid.

Only your own routines

The Edit button appears only on custom (account-owned) routines. Built-in routines that ship with an agent have no Edit button โ€” that's how you know they're read-only; you can't rewrite their steps. The editor header even reminds you: "Advanced editing โ€” you can also just ask your assistant to change this routine."

Your first routine โ€‹

Here is a complete, valid one-step routine. Every line is explained below.

yaml
name: daily-standup-notes
display_name: Daily standup notes
description: Summarize what happened on the account yesterday in three bullets.
archetype: personal-assistant
steps:
  - title: Write the summary
    prompt: |
      Summarize what happened on my account yesterday in exactly three
      short bullets: what customers asked, what went unanswered, and the
      one thing worth doing today. If I named a focus area, weight it: {input}
FieldWhat it is
nameA slug โ€” lowercase letters, digits, and hyphens (daily-standup-notes). It's the routine's id, unique within your account. Can't collide with a built-in routine's name.
display_nameThe friendly name shown on the card. Optional โ€” if you leave it out, it's derived from name.
descriptionOne or two sentences, in your own words, describing what the routine does. Required.
archetypeThe routine's home agent โ€” which agent owns it and whose Tasks tab it appears on. Name it by slug (personal-assistant) or by display name (Personal Assistant).
stepsThe list of steps, run top to bottom. 1 to 8 steps.
steps[].titleA short label for the step, shown in the live progress list. Required.
steps[].promptWhat the step should do, written like an instruction you'd type into that agent's chat. Required.

The run flow: press Run on the card, and MyChatBot starts the routine in its own conversation. Step 1's prompt runs on the home agent, its result lands in the thread, and โ€” since there's only one step โ€” the routine finishes. Each step is a full, billed agent run and shows up on your Usage page.

Two tokens you can drop into any prompt

  • {input} โ€” the run message (whatever you type in the Run box, or the routine's run_message default, or a schedule's message). Empty if you didn't give one.
  • {previous} โ€” the previous step's output. On step 1 it's empty (there's no previous step). See the next section.

Multiple steps: passing data with {previous} โ€‹

Steps run in order, and each one can read the one before it through {previous}. That's how you chain work: gather in step 1, transform in step 2, report in step 3.

yaml
name: competitor-price-check
display_name: Weekly competitor price check
description: Pull our prices, compare them against competitors, and flag where we're beaten.
archetype: platform-assistant
run_message: Focus on our three best-selling products.
steps:
  - title: Collect our prices
    archetype: platform-assistant
    prompt: |
      List our current products and prices from the connected catalog.
      Focus on: {input}
  - title: Compare with competitors
    archetype: personal-assistant
    prompt: |
      Here are our prices:
      {previous}

      Search the web for the same products at our main competitors and
      build a short table: product, our price, their price, and the gap.

Two things worth calling out:

  • run_message is an optional default for {input}. If someone runs this routine without typing anything, {input} becomes "Focus on our three best-selling products." โ€” so a scheduled or triggered run still has direction.
  • Each step can run on a different agent. Step 1 runs on the Sales Platform Wizard (platform-assistant, good with your catalog); step 2 runs on the Personal Assistant (personal-assistant, good at web research). A step's own archetype overrides the routine-level one; omit it and the step falls back to the home agent. Each step bills on its own agent's model โ€” see Usage & billing.

Home agent vs. step agent

The top-level archetype is the routine's home โ€” where the routine lives in the app, and the default agent for any step that doesn't name its own. Each step's archetype is who actually runs that step. If you omit the top-level one entirely, it defaults to step 1's agent.

You can name an agent by its slug or its display name โ€” use whichever you know. The visible agents on a typical account:

SlugDisplay name
personal-assistantPersonal Assistant
platform-assistantSales Platform Wizard
assistantChief of Staff
bulk-text-workerBulk Text Worker
content-directorContent Director
content-factoryContent Factory
site-builderSite Builder

Any agent you've added from the library or built yourself can run a step too. If you name an agent your account can't see, Save tells you which agents are available.

Picking the model a step runs on โ€‹

By default, each step runs on its agent's usual model โ€” the one that agent was set up with. You don't have to think about it. But when you want a specific model โ€” a heavier one for a tricky reasoning step, a cheaper and faster one for a bulk step โ€” pin it with model.

model works at two levels:

  • Routine-level model sets the default for every step.
  • Step-level model overrides it for that one step.
yaml
name: research-and-summarize
description: Research a topic in depth, then write a tight summary.
archetype: personal-assistant
model: claude-sonnet             # every step runs on Claude Sonnet by default
steps:
  - title: Research
    prompt: Research {input} thoroughly and gather the key facts.
  - title: Summarize
    model: gemini-flash          # โ€ฆbut run the quick summary on a cheaper, faster model
    prompt: |
      Summarize the research below into five bullets:
      {previous}

How a step's model is chosen โ€” first match wins:

  1. the step's own model, if it has one;
  2. otherwise the routine's model;
  3. otherwise the step agent's default model (the original behavior โ€” a routine with no model anywhere behaves exactly as before).

Two rules the editor enforces on Save:

  • It must be a real model from the catalog. Name it by its alias โ€” e.g. claude-sonnet, gpt-5, or gemini-flash. A misspelled or unknown name is rejected, and the error lists valid ones.
  • It must be able to use tools. Routine steps call tools โ€” search, browsing, your connected data โ€” so a model that can't reliably use tools is rejected (it might claim it did something without actually doing it). The general-purpose models are all fine; the ones aimed only at reading images or bulk text aren't.

The card shows what it really runs on

The routine card's "Runs on โ€ฆ" line reflects the model each step actually uses โ€” so when you pin one, that's what shows, not the agent's default.

Billing follows the model you pick

A heavier model costs more per step; a lighter one costs less. Each step bills on whatever model it runs on โ€” see Usage & billing.

Human approval gates โ€‹

A step can pause and wait for your OK before it runs. Put an approval on it:

yaml
  - title: Publish the page
    archetype: site-builder
    approval: true
    prompt: |
      Publish the assembled draft as a live page and give me the link.

approval: true gives the pause a standard message. To say exactly what the person is approving, use the object form:

yaml
  - title: Send the follow-ups
    archetype: platform-assistant
    approval:
      message: Review the follow-ups above. Approve to send them, or reject to stop.
    prompt: |
      Send each approved follow-up to its lead through the channel where
      we last spoke, and confirm what was sent to whom.

When the routine reaches a gated step, it stops and shows an "Your approval is needed" card in the conversation (with your message). Approve runs the step; Reject stops the whole run there. Approvals live in the routine's own conversation, not on the account-wide Approvals page โ€” see Routines โ†’ Approvals.

The safety rule: anything irreversible needs a gate

A step without an approval gate physically cannot send messages, place or schedule calls, start outreach, publish or change live pages, or write knowledge entries โ€” even if its prompt tells it to, and even if the prompt claims you already approved. Ungated steps are held to read-and-draft work so a routine can run unattended (on a schedule or trigger) without doing something irreversible while you're away.

If a step must take a real, outside-world action, it needs approval. That's not a suggestion the prompt can talk its way around โ€” it's enforced. This is also the answer to "why did my step refuse to send?" (see the FAQ).

Early exits: stop when there's nothing to do โ€‹

Sometimes a routine should bail out gracefully โ€” "no quiet leads this week, so there's nothing to follow up on." That's early_exit. You give it a sentinel (a distinctive token) and a friendly message:

yaml
steps:
  - title: Find quiet leads
    archetype: platform-assistant
    prompt: |
      List my leads that went quiet in the last 14 days, one per line.
      If there are none at all, reply with exactly NO_LEADS and nothing else.
  - title: Draft a follow-up for each
    archetype: bulk-text-worker
    early_exit:
      sentinel: NO_LEADS
      message: No quiet leads this week โ€” nothing to follow up on.
    prompt: |
      Here are the quiet leads:
      {previous}

      Write a short, friendly follow-up for each, under 400 characters.

How it works: early_exit is checked against the previous step's output, before this step runs. So the pattern is always two steps:

  1. The step that might find nothing is told to emit the sentinel (here, step 1 answers NO_LEADS when there are no quiet leads).
  2. The next step carries the early_exit. If the previous step's output contains the sentinel, the routine stops early and shows your message โ€” step 2 (and everything after) never runs, and never bills.

early_exit can't sit on the first step

The sentinel is matched against the previous step's output, and step 1 has no previous step. Put the early_exit on the step after the one that emits the sentinel. Save will reject it on step 1.

Scheduling it โ€‹

A routine doesn't have to wait for you to press Run. Add an optional top-level schedules: block and it runs on a clock. Each entry is a standard 5-field cron expression plus an optional timezone and run message:

yaml
schedules:
  - cron: "0 9 * * 1"           # every Monday at 09:00
    timezone: Europe/Kyiv
    run_message: Look at leads from the last 14 days.
KeyWhat it is
cronA 5-field cron expression: minute hour day month weekday. Quote it โ€” the leading digits and * aren't valid unquoted YAML.
timezoneAn IANA timezone name (UTC, Europe/Kyiv, America/New_York). Optional; defaults to UTC.
run_messageWhat {input} becomes for scheduled runs. Optional; falls back to the routine's own run_message.

Common cron cadences:

text
0 9 * * *         # 09:00 every day
0 9 * * 1         # 09:00 every Monday
*/30 * * * *      # every 30 minutes
0 8 1 * *         # 08:00 on the 1st of each month
30 6 * * 1-5      # 06:30 Mondayโ€“Friday

Schedules are reconciled when you Save. Adding an entry creates a schedule; editing one (change the cron or timezone) updates it; removing an entry deletes that schedule. Deleting a schedule is safe โ€” nothing outside MyChatBot depends on it. You can have up to 5 schedules per routine.

No schedule yet? The editor shows you the shape

When a routine has no schedules, the editor drops in a commented-out example so you can see the exact syntax โ€” uncomment it, edit the cron, and Save.

The same schedules also appear in the Automations panel below the editor, and you can create them there or by asking your assistant. See Tasks & schedules for how scheduled runs behave.

Triggering it โ€‹

A trigger starts your routine when something happens โ€” an outside service calling a secret link (a form submission), or an event in a connected app like a Stripe payment or a new Gmail email (app-event triggers) โ€” rather than on a clock.

In the YAML, triggers are view-only. Any that exist appear as a read-only comment so you can see, at a glance, what starts this routine:

text
# โ”€โ”€ Triggers (view-only โ€” add or remove in the Automations panel) โ”€โ”€
# โšก new-lead-form โ†’ https://api.mychatbot.app/hooks/<id>/<secret>

You add and remove triggers in the Automations panel below the editor (not in the YAML), for two reasons:

  • The link carries a secret. A trigger's URL is effectively a password โ€” anyone who has it can fire your routine. It lives in the panel with a Copy button (viewable there any time), where it doesn't belong pasted into an editable text field you might share.
  • Deleting it breaks whatever calls it. An outside form or tool is posting to that URL. Removing a trigger should be a deliberate action in the panel, not a side effect of tidying up your YAML.

To wire one up, open the Automations panel โ†’ Triggers โ†’ Add secret link, copy the URL it reveals, and paste it into your outside tool. (App-event triggers have no URL โ€” create those by chatting: "when a payment comes in on Stripe, run this routine.") Full details โ€” queuing, duplicate handling, limits โ€” are on the Triggers page.

The Automations panel below the editor: a Schedules section, a Triggers section with a secret link's full webhook URL and a Copy button, and Save / Cancel at the very bottom

A complete worked example โ€‹

Here's a realistic weekly lead-nurture routine that uses everything above: five steps across three agents, an early exit when there's nothing to do, a single approval gate on the one step that messages customers, and a weekly schedule. This is the capstone โ€” every line is valid and commented.

yaml
# โ”€โ”€ Weekly lead nurture โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
name: weekly-lead-nurture
display_name: Weekly lead nurture
description: Find leads that went quiet, draft a follow-up for each, send after I approve, then log a summary.
archetype: personal-assistant          # home agent โ€” where this routine lives
run_message: Look at leads from the last 14 days.

steps:
  # 1 ยท Gather the leads (read-only). Told to emit a sentinel when there's
  #     nothing to do, so step 2 can bail out cleanly.
  - title: Find quiet leads
    archetype: platform-assistant
    prompt: |
      Look through my leads and chats for people who went quiet or were
      never answered in this window: {input}
      List each one with a note on where the conversation stalled.
      If there are no quiet leads at all, reply with exactly NO_LEADS
      and nothing else.

  # 2 ยท Stop early if step 1 found nothing โ€” checked against step 1's output.
  - title: Draft a follow-up for each
    archetype: bulk-text-worker
    early_exit:
      sentinel: NO_LEADS
      message: No quiet leads this week โ€” nothing to follow up on.
    prompt: |
      Here are the quiet leads:
      {previous}

      Write a short, friendly follow-up for each lead, matched to where
      their conversation left off. Keep each under 400 characters.

  # 3 ยท Review the drafts (read-only) before anyone approves sending.
  - title: Sanity-check the drafts
    archetype: personal-assistant
    prompt: |
      Review these drafts:
      {previous}

      Flag anything off-tone, duplicated, or missing a clear next step,
      then produce the cleaned-up final list, ready to send.

  # 4 ยท The ONLY step that touches the outside world โ€” behind a gate.
  - title: Send the approved follow-ups
    archetype: platform-assistant
    approval:
      message: Review the follow-ups above. Approve to send them, or reject to stop.
    prompt: |
      Send each approved follow-up to its lead through the channel where
      we last spoke, and confirm what was sent to whom.

  # 5 ยท Log what happened (read-only).
  - title: Write a short summary
    archetype: personal-assistant
    prompt: |
      Based on what was sent:
      {previous}

      Write a two-line summary for my records: how many follow-ups went
      out, and anything that needs a human touch next week.

schedules:
  - cron: "0 9 * * 1"                   # every Monday at 09:00
    timezone: Europe/Kyiv
    run_message: Look at leads from the last 14 days.

Read it top to bottom: it collects leads, exits early if there are none, drafts and sanity-checks (both read-only, so they run unattended safely), pauses for your approval before the one step that actually messages people, then logs a summary โ€” and it does all of this every Monday at 9am on its own.

Field reference โ€‹

Top-level โ€‹

FieldTypeRequiredDefaultNotes
namestring (slug)Yesโ€”^[a-z0-9][a-z0-9-]*$, โ‰ค 64 chars. Unique per account; can't be a built-in routine's name.
display_namestringNoderived from nameโ‰ค 80 chars.
descriptionstringYesโ€”โ‰ค 300 chars. One or two sentences.
archetypestringNostep 1's agentThe home agent โ€” slug or display name of a visible agent.
modelstringNoeach step's agent defaultPins the model every step runs on. A catalog alias (e.g. claude-sonnet, gpt-5, gemini-flash); must be able to use tools. A step's own model overrides it. See Picking the model.
run_messagestringNoโ€”Default value for {input} when a run gives none. โ‰ค 2000 chars.
stepslistYesโ€”1 to 8 steps, run in order.
scheduleslistNoโ€”Up to 5 entries; reconciled on Save (see Scheduling).

Per step โ€‹

FieldTypeRequiredDefaultNotes
titlestringYesโ€”โ‰ค 80 chars. Shown in the live progress list.
promptstringYesโ€”โ‰ค 4000 chars. Supports {input} and {previous}.
archetypestringNothe routine's home agentThe agent that runs this step โ€” slug or display name.
modelstringNoroutine model, else the step agent's defaultPins the model this step runs on. A catalog alias (e.g. claude-sonnet, gpt-5); must be able to use tools. Overrides the routine-level model. See Picking the model.
approvaltrue / false / { message }NofalseA human approval gate before the step runs. message โ‰ค 500 chars. Required for any step that sends/publishes/mutates.
early_exit{ sentinel, message }Noโ€”Stops the routine if the previous step's output contains sentinel. sentinel โ‰ค 64 chars, message โ‰ค 500 chars. Not allowed on step 1.

Schedule entry โ€‹

FieldTypeRequiredDefaultNotes
cronstringYesโ€”5-field cron: minute hour day month weekday. Quote it.
timezonestringNoUTCIANA name, e.g. Europe/Kyiv.
run_messagestringNoroutine's run_messageWhat {input} becomes for this schedule's runs.
namestringNoauto-generatedOptional label for the schedule, unique within the routine (โ‰ค 128 chars). Handy if you keep several โ€” otherwise leave it out.

Caps โ€‹

LimitValue
Steps per routine8
Custom routines per account10
Schedules per routine5
Prompt length4000 characters
Whole-spec size64 KB

Reserved / auto-computed fields โ€‹

  • tag โ€” each step gets an internal tag, derived from its title, used to track the step. It's computed for you; if you include one it's ignored. You never need to set it.
  • Any unknown key โ€” at the top level or on a step โ€” is a validation error, so a typo (prompts: instead of prompt:) is caught on Save rather than silently ignored.

When Save finds problems โ€‹

Validation reports every problem at once, so you can fix them in one pass rather than one-Save-per-error. Typical messages:

text
This routine has problems:
- 'description' is required (one or two sentences).
- steps[2]: archetype 'growth-hacker' is not available on this account โ€ฆ
- steps[1]: 'early_exit' is not allowed on the first step โ€ฆ
- too many steps: 9 > 8 โ€ฆ

The editor keeps your text exactly as you left it while you fix them.

Tips & FAQ โ€‹

Why did my step refuse to send / publish / message anyone? Because it has no approval gate. Ungated steps are locked to read-and-draft work so a routine is safe to run unattended. Add approval: true (or an approval with a message) to that step, and it'll be allowed to act once you approve it. See the safety rule.

Can I edit a routine while a run is paused at an approval gate? Yes โ€” you can Save changes any time. But a run that's already in flight (including one paused on an approval card) keeps the version of the spec it started with. Your edits take effect on the next run.

Where does the routine "live"? On its home agent โ€” the top-level archetype. That's whose Tasks tab shows the card. Change archetype and Save to move the routine to a different agent. (Each step still runs on its own step-level agent regardless.)

Do I have to use slugs for agents? No โ€” a display name works too (Sales Platform Wizard, Personal Assistant), and it's case-insensitive. Slugs are just the canonical form. If you name an agent your account can't see, Save lists the ones you can.

I edited schedules in the YAML and in the Automations panel โ€” which wins? The last Save wins. The schedules: block and the Automations panel (and the assistant) all edit the same schedules. If you change them in two places around the same time, whichever you Save last is the final state โ€” so pick one surface per editing session to avoid surprising yourself.

Can I add a trigger by typing it into the YAML? No โ€” triggers are view-only in the YAML. Add and remove them in the Automations panel, because the link is a secret and deleting one breaks whatever outside tool is calling it. See Triggers.

See also โ€‹