Minctrl documentation
Minctrl is the AI-native workflow builder for regulated operations. You design a process once; AI agents run it end-to-end; and a governance layer keeps a human on the risky steps — deciding exactly when a step pauses for sign-off, and sealing every decision into a tamper-evident audit trail.
Everything below is driven by the Minctrl API. Author a process (or import your BPMN 2.0), bind each step's tool to your real HTTP endpoints, then start a run: the runtime executes reversible steps automatically and parks at the first human gate for a decision.
Core concepts
- Governed flows — a process is a typed node graph. Every step is either an agent action or a human gate, and the graph is validated (reachability + gate-removal) before it can run.
- Risk-tiered gates — each gate is scored by blast radius + reversibility. Low-risk reversible steps auto-clear; medium routes to a compliance-judge panel; irreversible always waits for a human.
- Connectors — bind a step's tool-id to a real HTTP API you own. Irreversible tools stay shadowed (no live side effect) unless the connector opts in.
- Durable park/resume runtime — a parked run persists its exact state, survives restarts, and resumes deterministically from the checkpoint on sign-off (idempotent replay — the irreversible step fires once).
Quickstart
The end-to-end path, from account to a completed governed run. Set BASE to your API base URL and export the JWT you get back from step 1 as $TOKEN.
Register (or log in)
Create an account — a company is auto-provisioned for you — and capture the returned token. Registration is open.
BASE=https://api.minctrl.com
TOKEN=$(curl -s -X POST "$BASE/auth/register" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"correct-horse-battery","name":"You"}' \
| jq -r .token)Pick a process template
List the 45 governed flows and choose a vertical to run — here, the AML/KYC compliance autopilot.
curl -s "$BASE/process-templates/" \
-H "Authorization: Bearer $TOKEN" | jq '.[].vertical'Configure a connector
Bind a step's tool-id to your real HTTP API so agents call your systems, not a mock. Reversible tools may go live immediately.
curl -s -X PUT "$BASE/connectors/sanctions-screen" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"base_url": "https://screening.acme.com",
"method": "POST",
"path": "/v1/screen",
"auth_type": "bearer",
"auth_token": "$SCREENING_TOKEN",
"body_map": {"name": "customer.name"},
"reversible": true
}'Start a run — then resume the gate
Start executing the vertical. The run executes reversible steps and parks at the first human gate (status: "awaiting_human"). Record the human verdict to continue.
# Start — returns a run parked at the first gate
RUN=$(curl -s -X POST "$BASE/process-runs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"vertical":"kyc_aml","inputs":{"case_id":"A-4471","amount":82400}}')
RUN_ID=$(echo "$RUN" | jq -r .id)
# Resume — sign off the parked gate and let the run complete
curl -s -X POST "$BASE/process-runs/$RUN_ID/resume" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"gate":"signoff","decision":"approved"}'Authentication
Minctrl uses JWT bearer tokens. Register or log in once to get a token, then send it as Authorization: Bearer <token> on every subsequent call. Registration is open — anyone can create an account, and a company is auto-provisioned on first signup.
POST /auth/register
Body { email, password, name, company_name? }. Returns token, the user (id, email, name) and the auto-created company (id, name, slug).
curl -s -X POST "$BASE/auth/register" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "correct-horse-battery",
"name": "You"
}'
# → { "token": "eyJ…", "user": { "id": "…", "email": "[email protected]", "name": "You" },
# "company": { "id": "…", "name": "You's Company", "slug": "yous-company" } }POST /auth/login
Body { email, password }. Returns the same token / user / company shape.
curl -s -X POST "$BASE/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"correct-horse-battery"}'Every other endpoint requires the header Authorization: Bearer $TOKEN. The company scope is carried inside the JWT — connectors, runs and templates are all resolved against your company automatically.
Process templates
Templates are the read side of the Process Cockpit — 45 governed vertical flows across fintech, telecom, finance, healthcare, legal, insurance and more. Each is a governance-decorated node/edge graph you can inspect, export, or run.
GET /process-templates/ — list flows
Summaries only: vertical, domain, steps, gates, branched. Optionally filter with ?domain=telecom.
curl -s "$BASE/process-templates/?domain=fintech" \
-H "Authorization: Bearer $TOKEN"GET /process-templates/{vertical}/canvas — the graph
The full node/edge graph for a vertical: each node carries its risk tier, its gate/agent kind, the seated domain reviewer, and live validation violations — everything a React Flow canvas needs.
curl -s "$BASE/process-templates/kyc_aml/canvas" \
-H "Authorization: Bearer $TOKEN"GET /process-templates/{vertical}/bpmn — BPMN 2.0 export
Exports the process as BPMN 2.0 XML (agent steps → serviceTask, human gates → userTask) — an interchange artefact for Camunda / Signavio / Bizagi. You can also import a foreign BPMN model with POST /process-templates/import-bpmn ({ xml }), which returns the canvas graph plus governance violations so you immediately see where the imported model is ungoverned.
curl -s "$BASE/process-templates/kyc_aml/bpmn" \
-H "Authorization: Bearer $TOKEN" -o kyc_aml.bpmnConnectors
A connector binds a step's tool-id (e.g. sanctions-screen) to a real HTTP API you own. At run time the connector registry resolves each tool-id to your endpoint, so agents call your systems. The binding is per-company and includes a small state → request mapping.
PUT /connectors/{tool_id} — create / update
The request body is the full connector config:
| Field | Type / default | Purpose |
|---|---|---|
| base_url | string | Origin of your API. |
| method | string · "GET" | HTTP method. |
| path | string · "" | Path appended to base_url. |
| auth_type | string · "none" | none | bearer | header. |
| auth_token | string | null | Token for bearer / header auth. |
| auth_header | string | null | Header name when auth_type = header. |
| query_map | {str: str} | Map run-state paths → query params. |
| body_map | {str: str} | Map run-state paths → JSON body fields. |
| signal_rule | object | null | Rule for extracting a signal from the response. |
| reversible | bool · false | Whether this tool may fire a live side effect. |
curl -s -X PUT "$BASE/connectors/sanctions-screen" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"base_url": "https://screening.acme.com",
"method": "POST",
"path": "/v1/screen",
"auth_type": "bearer",
"auth_token": "$SCREENING_TOKEN",
"query_map": {},
"body_map": {"name": "customer.name", "dob": "customer.dob"},
"reversible": true
}'POST /connectors/{tool_id}/test — dry-run
Fire the configured request once against sample state and return the result — a real call to your endpoint, to confirm the wiring before you rely on it. Body { config, state }.
curl -s -X POST "$BASE/connectors/sanctions-screen/test" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"config": { "base_url": "https://screening.acme.com", "method": "POST",
"path": "/v1/screen", "auth_type": "bearer",
"auth_token": "$SCREENING_TOKEN",
"body_map": {"name": "customer.name"} },
"state": { "customer": { "name": "Jane Roe" } }
}'List & delete
GET /connectors lists every connector configured for your company; DELETE /connectors/{tool_id} removes one (returns { deleted: true }).
Irreversible tools stay shadowed — no live side effect fires — unless the connector config sets reversible: true. This is enforced at run time by the connector registry, so a process can execute end-to-end and demonstrate the autopilot loop without ever touching a live system it hasn't been explicitly cleared to touch.
Runs — execute a process
A run executes a template's governed graph. Reversible steps the resolver clears auto-execute (through your connectors — irreversible tools run in shadow), and the run parks at the first human gate. Resuming records the human's verdict and continues — idempotent replay, so the irreversible step never double-executes.
POST /process-runs — start
Body { vertical, inputs, auto_resolve } (auto_resolve defaults to true). Returns the run — either parked at the first gate (awaiting_human) or completed.
curl -s -X POST "$BASE/process-runs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"vertical": "kyc_aml",
"inputs": { "case_id": "A-4471", "amount": 82400, "currency": "USD" },
"auto_resolve": true
}'
# → { "id": "…", "vertical": "kyc_aml", "status": "awaiting_human",
# "parked_at": "signoff", "trace": { … } }POST /process-runs/{id}/resume — sign off a gate
Body { gate, decision } — the gate step-id being signed and the verdict ("approved", "denied", or a branch label). Only valid while the run is awaiting_human; otherwise the API returns 409. Re-running is safe (idempotent replay).
curl -s -X POST "$BASE/process-runs/$RUN_ID/resume" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"gate":"signoff","decision":"approved"}'
# → { "id": "…", "status": "completed", "parked_at": null, "trace": { … } }Read runs
GET /process-runs/{id} fetches a single run (including its full trace); GET /process-runs lists recent runs for your company.
Start the kyc_aml vertical with a case. Intake and sanctions screening are reversible, so they auto-clear. Risk is assessed as HIGH — and filing a SAR is irreversible.
The run parks at the SAR-filing gate (status: awaiting_human, parked_at: "signoff"). A compliance officer reviews the case and resumes with decision: "approved".
The run resumes deterministically from the checkpoint, files the SAR once, and completes with a sealed audit trail — who signed off, why the gate paused, and which connector fired.
Governance model
Every gate is scored by blast radius + reversibility, and that score decides how the gate routes:
- Low-risk, reversible → auto-clears. The resolver executes the step and moves on — no pause.
- Medium-risk → routed to a compliance-judge panel of the vertical's seated domain reviewers, with calibrated confidence attached to the verdict.
- Irreversible → always waits for human sign-off. The run parks; the side effect stays shadowed until a person approves.
Whatever the path, the outcome is recorded: who decided what, why each gate paused, which connector fired, and the calibrated confidence behind each judgement — sealed into a tamper-evident audit trail your auditor can read. Nothing about a run's history can be silently rewritten after the fact.
API reference
Every endpoint used in these docs. All but registration and login require a bearer token.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /auth/register | public | Register a user; auto-creates a company. Returns a JWT. |
| POST | /auth/login | public | Log in with email + password. Returns a JWT. |
| GET | /process-templates/ | Bearer | List the 45 governed process flows (summaries). |
| GET | /process-templates/{vertical}/canvas | Bearer | Governance-decorated node/edge graph. |
| GET | /process-templates/{vertical}/bpmn | Bearer | Export the process as BPMN 2.0 XML. |
| POST | /process-templates/import-bpmn | public | Import a foreign BPMN model; returns graph + violations. |
| GET | /connectors | Bearer | List connectors configured for your company. |
| PUT | /connectors/{tool_id} | Bearer | Create or update a tool-id → HTTP API binding. |
| POST | /connectors/{tool_id}/test | Bearer | Dry-run the configured request against sample state. |
| DELETE | /connectors/{tool_id} | Bearer | Delete a connector binding. |
| POST | /process-runs | Bearer | Start a run; parks at the first human gate or completes. |
| GET | /process-runs | Bearer | List recent runs for your company. |
| GET | /process-runs/{id} | Bearer | Fetch a single run with its full trace. |
| POST | /process-runs/{id}/resume | Bearer | Record a human verdict on a parked gate; continue. |
The complete, always-current OpenAPI / Swagger reference is served by the API itself at /docs (the FastAPI interactive docs) — with every schema, response code and try-it-out console.