Skip to content

Changesets

Steps never write to your CRM. They propose changes, and a changeset step gathers those proposals into one package that a person approves before anything is written. This is the one rule Motions doesn’t bend: nothing reaches the CRM unapproved, unless the motion explicitly says approval: auto.

A step calls the CRM through ctx.crm. Reads return records. Writes return a reference to the proposed operation, and nothing else happens yet:

const contact = await ctx.crm.contacts.create({ first_name: "Ana", last_name: "Lima", email: person.email });
await ctx.crm.associate(contact, company.core.crm.id);
await ctx.crm.notes.create({ on: contact, body: "Found on the company's site, team page." });

contact here is a reference to a contact that doesn’t exist yet. The later operations use it, and the writer fills in the real id once the contact is created.

Each step lists the CRM actions it may propose in motion.yaml, under crm.propose. A proposal for an action that isn’t listed fails the step. When a proposal is made, Motions checks it against the CRM and records what it would overwrite:

Action Proposes Checked
companies.update new values for the company’s custom fields the company exists; only fields marked writable
contacts.create a new contact it has an e-mail or a LinkedIn URL, which identifies it
contacts.update new values for a contact the contact exists
associate linking a contact to a company both exist, or are proposed
notes.create a note on a company or a contact it has a body; the record exists
notes.pin pinning a note

A changeset step is a barrier. Companies collect at it with their proposals. When no company is still on its way to it, active or waiting on a question, the changeset seals: every proposal made since the previous changeset, for every company waiting there, becomes one immutable package with an id.

Companies that arrive later, after a retry for instance, go into a new changeset at the same step. A batch can have several.

Once a company is sealed, its proposals can’t change: answering one of its questions again, or upgrading the batch, leaves the sealed part alone.

The batch shows each changeset with every operation, grouped by company, and the before and after of each field. Only the motion’s approvers can decide:

  • Approve, then confirm with Approve and write. Motions writes the operations in order.
  • Reject, then Reject changeset. Nothing is written, and its companies move to the held lane with the reason “changeset rejected”.

With approval: auto on the changeset step, it’s approved as soon as it seals. Use that only for writes you’d approve without looking.

Each operation gets a receipt:

Receipt Means
written The CRM has it, with the id it got.
skipped Nothing needed writing, or nothing could be. The detail says why: “already up to date”, “contact with email … already exists”, or “the CRM connection is read-only”.
failed The CRM refused it. The detail has the CRM’s error.

When every operation has a receipt, the changeset’s cells turn passed and the companies carry on to any steps after 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