Shape a motion
motion.yaml is the motion’s outline. It’s short on purpose: the logic is in the steps, and this file says how they connect and who decides. Here’s the Quickstart’s:
title: Domain checkapprovers: [ana]reasons: [no_domain, unregistered]input: { list: first-batch }
steps: - id: domain title: Look up the domain run: steps/domain.ts sources: [rdap.lookup] - id: note title: Draft a CRM note run: steps/note.ts crm: { propose: [notes.create] } - id: write kind: changeset title: Write the notes approval: required
queues: domain_owner: { title: Who owns this domain?, owner: ana, deadline: 1d, default: hold }This page walks through laying one out. Every key is in the motion.yaml reference.
Start with the steps
Section titled “Start with the steps”List the steps in the order they run. Each has an id, lowercase with underscores, a title people will see on the batch screen, and for steps that run code, run: the file, relative to the motion folder.
steps: - id: identity title: Match the CNPJ run: steps/identity.ts - id: fit title: Check the fit run: steps/fit.tsEach step runs after the one before it. A later step reads what earlier steps found as company.facts.<step id>.
Give each step what it needs
Section titled “Give each step what it needs”A step can’t do anything it wasn’t granted. List, for each:
sources: the operations it may call, such as[cnpj.match, rdap.lookup], or a custom source’sbrasilapi.cnpj.crm.read: the CRM objects it reads:companies,contacts,deals,owners,notes.crm.propose: the changes it may propose:companies.update,contacts.create,contacts.update,associate,notes.create,notes.pin.cap: the most it may spend on sources,per_company_usdandper_batch_usd.
- id: people title: Find people run: steps/people.ts sources: [harvestapi.lead_search, harvestapi.profile] crm: { read: [contacts] } cap: { per_company_usd: 0.40, per_batch_usd: 80 }motions check fails if a step reads or proposes something your CRM can’t do. A call to a source that isn’t listed fails at run time with “add it to the step’s sources”.
End with a changeset
Section titled “End with a changeset”If any step proposes CRM changes, add a changeset step after them. It runs no code: it gathers the proposals of the steps before it into one package for an approver.
- id: write kind: changeset title: Write the contactsA motion can have several changesets, each collecting the proposals made since the previous one: contacts first, then the notes that refer to them.
Name the people
Section titled “Name the people”approvers: [hugo]queues: identity: { title: Which registration is it?, owner: ari, deadline: 4h, default: hold }approvers: the handles who approve changesets, release checkpoints, upgrade batches and make versions live. At least one.queues: one per question type your steps ask, with its owner, deadline and default. See Ask questions.reasons: the reasons steps may give when they hold or drop a company. When you list them, a step that uses any other fails, which keeps the batch’s reasons tidy.
Run steps side by side
Section titled “Run steps side by side”after overrides “the step before”. Two steps that both need only identity can run side by side, and a third can wait for both:
- { id: identity, run: steps/identity.ts } - { id: signals, run: steps/signals.ts, after: [identity] } - { id: people, run: steps/people.ts, after: [identity] } - { id: score, run: steps/score.ts, after: [signals, people] }Skip a step for some companies
Section titled “Skip a step for some companies”when runs a step only for companies where an earlier fact, a core field or a CRM field has one of the listed values. The others show the step as skipped.
- id: cnpj run: steps/cnpj.ts when: { fact: core.country, in: [BR, Brazil] }fact starts with core, fields, or the id of an earlier step: fit.segment.
Wait for the batch
Section titled “Wait for the batch”Some steps need the whole batch: finding duplicates within the list, ranking, or stopping until Monday. Use a batch step or a checkpoint.
Retries
Section titled “Retries”A step that fails for a passing reason, such as a timeout or a provider’s rate limit, runs again, twice by default. Set retries from 0 to 10. Errors in your code aren’t retried: they park the company until someone retries it.
Motions is built by Pruma. These docs describe what the platform does today; Limitations lists what it doesn't do yet. Open the app