Deliverd Flow · human-in-the-loop workflows
Your agent can act.
It still has to ask.
Flow is how an agent involves a person: it asks, a human answers on a page that works on a phone, and the result comes back so the agent can continue. One call is a complete flow; a named flow threads several together into one record.
Everything on this page ships today · MCP, REST, CLI and SDKs for TypeScript and Python
- Agentasks: refund £1,240 to Acme?
- Deliverdroutes it to Finance — email, notification, a page
- Personreads it on a phone and taps Approve
- Deliverdreturns { approved: true, decidedBy: "Sarah Chen" }
- Agentcarries on
import { deliverd } from "@deliverd/sdk";
const decision = await deliverd.approve({
title: "Refund £1,240 to Acme",
description: "Duplicate charge on invoice 4821.",
approvers: ["Finance"],
});
if (decision.approved) await refund();The whole integration. No report, no workflow to draw, no page to build — the approver gets one that works on a phone, and the agent gets a decision it can branch on.
Seven shapes, three calls
Every way an agent needs a person, and the line that asks.
Approval, a decision, a figure it is missing, an exception, a review, sign-off, and the finished thing in front of readers. Each is one call, and each comes back as something the agent can branch on.
approve()decision.approvedcollect()a question of kind: "choice"collect()answers[prompt]approve()approvers: ["Underwriting"]review()reportId, so they read the work itselfapprove()risk: "high" — or a publishing rule that holds itreports.publish()audience, by nameThe situation
Agents got capable faster than they got accountable
The agent cannot ask
It can call an API and it can write a file. What it cannot do is put a question to the partner who has to sign it off and wait for the answer — so either a person babysits every run, or the agent acts alone and somebody finds out afterwards.
The person cannot answer
Whatever the agent needed reaches them as a message in a channel, if at all. There is no page that says what is being asked, what it costs, what to read first, and gives them a button — least of all one that works on a phone between meetings.
Nobody can reconstruct it
A year later the question is who approved this, on what basis, and when. The answer is scattered across chat history, an inbox and somebody's memory, which is the same as not having it when a client or a regulator asks.
What it does
Ask, review, authorise, deliver, and a record of all of it
Seven pieces on one substrate — one audit trail, one notification system, one permission model, one agent identity. Each is reachable from the SDK, from any tool that speaks MCP, from the REST API or the CLI — and none of the first three needs a report to exist first.
Collect
An agent that is missing something asks the people who have it. Typed questions — text, numbers, dates, single and multiple choice, yes or no — with required fields, a due date and reminders for whoever has not replied. Answers come back to the agent as one object.
- They see
- A page that reads like replying to a colleague rather than filling in a form, with a draft saved as they go.
- It calls
request_informationget_collection
Review
Work goes in front of named readers before it goes anywhere else. Each reviewer approves it or asks for changes, with a note, and the agent reads the verdicts back. Distinct from a comment thread: a review records who was asked, what they were told to check, and what they decided.
- They see
- The work, the brief, and two buttons — on a phone, and without a Deliverd account if they are a guest.
- It calls
request_reviewget_review
Approve
Before a consequential action, the agent asks named people to authorise it: what it wants to do, why, what it costs, how risky it is, and what to read first. A request nobody answers escalates to more people and then expires. A person can ask the agent a question from the page and the answer arrives from the agent and appears there.
- They see
- Approve, reject with a reason, or ask a question — from a phone, signed in through your own identity provider.
- It calls
request_approvalget_approvalanswer_approval_question
Publish
The finished thing lands on a secure versioned URL, behind the reader's own sign-in, looking like your firm. This is the product as it was, unchanged — it is one module of the platform rather than the whole of it, and none of the others needs it.
- They see
- A link that opens for the people it was addressed to, and nobody else.
- It calls
publish_reportupdate_report
Evidence
One pack assembling every step of a piece of work: who was asked, what they said, what was decided and when, as a single timeline. JSON and CSV over the API, PDF from the download control. Each export is itself audited, with a digest, so the trail records which copy was handed over.
- They see
- A download an auditor can read a year later without a Deliverd account.
- It calls
get_evidence
Flows
The thread tying one job's requests together — its approvals, reviews, requests for information and publishes — under a name and your own reference. The timeline is derived from what actually happened rather than from a plan drawn in advance. No visual builder, and nothing to maintain.
- They see
- One page showing everything in that job and the order it happened in.
- It calls
create_flowget_flow
Agent policy
Per agent, which of these it may ask for at all. Then standing rules by agent, action and risk: send it to two people rather than one, route it to a named set, or refuse it outright. A rule can only make a request harder — there is no rule that approves one.
- They see
- Four switches on the agent's page and a rule builder in the admin console.
- It calls
- Nothing — an agent cannot reach its own policy
Before it acts
The agent says what it is about to do. Your policy answers.
The requests above all end at a person. This one starts earlier: the agent declares the action and the arguments before performing it, and the answer comes from rules the organisation wrote — not from a branch in the agent's code. Most calls are settled by a rule and never reach anybody.
allowedallowed: trueA rule permitted it.
The agent carries on. Nobody was interrupted, and the decision is still written down.
deniedallowed: falseA rule refused it.
The agent stops, and reads which rule and why. A refusal is an answer, not an error — it arrives as a 200 rather than down the failure path.
pendingallowed: falseNo rule settled it.
It became an ordinary approval: a named person decides on the page they already use, and the call can wait for them.
An action nobody has written a rule about goes to a person
Not because it is suspect — because nobody has decided about it yet, and those are different things. Most permission systems default the other way and quietly allow whatever no rule mentions. This is new enough that nothing breaks by asking, and an unwritten rule is the one most likely to be the rule you meant to write.
One call, before the action rather than after it
The rules are written against actions the organisation has named — so a policy is about the refund, not about whichever function your agent happens to call it from.
curl -X POST https://deliverd.dev/api/v1/gates \
-H "Authorization: Bearer $DELIVERD_API_KEY" \
-d '{
"actionId": "finance.refund",
"externalId": "refund:ord_8812",
"input": { "amount": 1240, "currency": "GBP" }
}'
{
"status": "pending",
"allowed": false,
"basis": "human",
"rule": "Refunds over £1,000",
"approvalUrl": "https://acme.deliverd.dev/approve/appr_8f2c"
}Act on the input that comes back, not the object you sent. It is what the action's schema validated and what the approver saw — and if they corrected a figure before agreeing, the corrected one is the one they agreed to.
What this does not do yet
The agent declares what it intends to do and acts on the answer. Nothing currently re-checks that what ran matches what was agreed — an agent that misreports to the policy engine is an agent misreporting to its own runtime, which is the trust boundary every SDK already has. Closing it means a signed decision token binding the approved input, re-checked at the point of execution. Nothing does that today.
The API, and what an agent may callThe two rules
What holds all of it together
Both are enforced where they cannot be configured away — in the services and in the database, not in the interface.
An agent never decides
Agents ask. People approve, review and answer. An agent may not approve its own request, may not be an approver of anything, and may not grant itself scope. That is refused in the service rather than hidden in the interface — and an agent cannot read or change its own permissions at all, because nothing about them is reachable from the API it calls.
Every step is a row somebody can read
Each request, question, answer, verdict and decision is written to an audit trail with the agent or the person as the actor. The table rejects updates and deletions at the database level, so the history is tamper-evident. That is the honest claim: tamper-evident history, not cryptographic immutability.
Questions
Agents, people and Deliverd.
Can an agent approve its own request?
No. The requester is removed from the approvers, an agent may not be an approver of anything, and the refusal lives in the service rather than the interface. A standing rule can raise the bar further — two people rather than one — but no rule can lower it, and there is no rule that approves a request automatically.
Does every action an agent takes need somebody to approve it?
No, and the whole point is that most do not. An agent can declare an action before performing it and the organisation's policy answers: a rule permits it, a rule refuses it, or nobody has written a rule and a named person decides. Rules are written against thresholds, agents and environments, so the routine case is settled without anybody being interrupted — and the decision is recorded either way, including the ones nobody saw.
Who writes those rules, and can an agent write its own?
An owner or an administrator of your organisation, against actions the organisation has registered. An agent cannot: writing a rule is how authority is granted, so an agent principal is refused at the service rather than hidden in the interface, and so is anybody whose role is not owner or administrator — checked freshly on every call, because a key outlives a role change. Rules are versioned, a version cannot be edited once it is active, and there is a simulator that answers what a request would have got without recording a decision.
What stops an agent from simply not asking?
Nothing yet, and it is better to say so. A decision is advisory today: the agent reports what it intends to do, policy answers, and the agent then performs the action itself — nothing re-checks that what ran matches what was agreed. An agent misreporting to the policy engine is an agent misreporting to its own runtime, which is the trust boundary every SDK already has. Closing it takes a signed decision token binding the approved input, re-checked where the action executes. What you get today is that the question is askable, answered by somebody other than the agent, and written down.
Do the people deciding need a Deliverd account?
Approvers are members of your organisation and sign in through your own identity provider. Reviewers and the people answering a request for information can be external: they get a link that emails them a one-time code, and the page opens once the code is verified.
What happens if nobody responds?
It escalates, then it expires. A standing rule can bring more people in once a request has gone unanswered for as long as you set, and anybody already asked can bring somebody in from the page; escalation only ever widens the circle, so nobody is taken off and no decision gets easier. Whoever is still waiting gets a nudge, and an approval with an expiry closes itself rather than sitting pending forever.
How does the agent find out what was decided?
It polls — get_approval, get_review, get_collection over MCP, or the matching REST endpoints — or it receives a signed webhook when the decision lands, as a Slack or Teams card if you point the endpoint at one.
What do we hand an auditor a year later?
An evidence pack: every step of the work, who was asked, what they said, what was decided and when, as one timeline in JSON, CSV or PDF. It carries a digest so an altered copy can be told apart, and the export itself is audited.
Is there a workflow builder to maintain?
No, and deliberately. A flow is a name and a reference that requests attach themselves to as the agent makes them; the timeline is derived from what actually happened rather than from a diagram drawn in advance. There is nothing to keep in step with the code.
Let the agent do the work. Keep the decision.
Connect whatever tool your team already uses, and the next time it needs a person it will have somewhere to ask. And when it makes something people need to read, that is the other half of the platform: Reports.