Definitions API — Mimeo docs
Definitions API
Everything you author, as files, and the safety-railed way to apply an edited copy of it back. The three endpoints the CLI is a thin client of.
| Method & path | What it does |
|---|---|
GET /api/v1/definitions |
The whole surface as { files: { path: contents } }. |
POST /api/v1/definitions/diff |
What applying these files would change. Changes nothing. |
POST /api/v1/definitions/apply |
Diff, validate, rehearse, apply — all or nothing. |
The file formats are documented at definition files reference. Authoring artifacts only: people, events, runs, sends and money are runtime and never appear, and neither do credentials.
Pull
GET /api/v1/definitions
{ "files": {
"flows/trial_journey.json": "{ … }",
"emails/0042-welcome-aboard.md": "---\nid: 42\n…",
"settings.yml": "tunables:\n …" } }
Canonically formatted — one key order, one indent, one trailing newline — so a pull straight after a pull is byte-identical, and an unrelated push doesn't churn every file in the repo with reordered keys.
Diff and apply
POST /api/v1/definitions/apply
{ "files": { "flows/trial_journey.json": "…", … },
"prune": false,
"force": false }
Send the whole managed tree, not a subset — absences are how removals are expressed, and a partial tree would read as a mass deletion. (With prune: false, the default, absences are only reported.)
The response
{ "changes": [\
{ "path": "flows/trial_journey.json", "kind": "update", "type": "flow",\
"label": "trial_journey",\
"summary": ["added 12-send-recap (id 12 minted)"],\
"errors": [], "warnings": [] } ],
"changed": 1,
"dry_runs": [ { "flow": "trial_journey", "triggered": true, "steps": 6, "problems": [] } ],
"notices": [],
"parse_errors": [],
"blocked": false,
"ok": true,
"applied": 1 }
| Field | Meaning |
|---|---|
kind |
create, update, unchanged, or absent (on your Mimeo, no file in the tree). |
summary |
Human-readable lines. Steps are named by handle; an email re-point is described in the chooser's terms. |
dry_runs |
One per changed flow, rehearsed against a real person with details that satisfy that flow's own trigger. |
notices |
Definitions already on your Mimeo that don't validate. Not caused by this push, and not blocking it. |
parse_errors |
Files that couldn't be read at all. Always blocking, never forcible. |
blocked |
Whether apply would refuse. |
Matching, not filenames
Records match by identity — a key, or the id in a file's frontmatter — never by filename. Renaming an email changes its filename, and a rename is not a delete.
What blocks
- Any error in something this push changes. Never forcible.
- A file that can't be parsed. Never forcible.
node_id_freedornode_id_repurposed— a step wearing an id that belonged to a different step. Warnings in the validator, blocking here, because the failure is silent: whoever is parked on that id moves with it.force: trueoverrides these and only these.
A definition already broken on your Mimeo appears in notices and doesn't block — you can't fix it by not pushing, and one broken record shouldn't wall off every unrelated change from then on.
Order of operations
Templates, fields and products first; then emails; then segments, guards and sequences; then flows; then settings. So a commit that adds an email and the step using it lands in one push. Everything happens in one transaction — a push that half-landed would leave your Mimeo in a state no file describes.
Pruning
prune: true also removes what's on your Mimeo but not in the tree. Emails are archived rather than destroyed — an email that has been sent is part of the record of what went out — and a flow people have run through refuses regardless, because their history is theirs.
Live updates
A successful apply pings every surface an admin page watches, so changes appear on an open page without a refresh.