Payments & transfers
Agent prepares a payout. Human Approves before money moves.
Human-in-the-loop API
AskHuman pauses irreversible agent actions for a human Approve or Deny — magic link email, then a clean Resolution your agent can poll.
Live API at https://api.ask-human.dev
Agent ready to wire $12,400 to Northwind Supplies (new payee).
$12,400.00 USDNorthwind SuppliesNew vendor · first wire{
"summary": "Wire $12,400 to Northwind Supplies?",
"payload": {
"amount": 12400,
"vendor": "Northwind Supplies",
"new_payee": true
},
"principal": {
"connector": "email",
"contact": "cfo@acme.co"
},
"expires_in_seconds": 600
}
An agent is waiting on your decision. This link expires in 10 minutes.
Magic link · no login
{
"id": "req_nw_12400",
"status": "pending",
"decision": null
}
Agent polls until a terminal Decision arrives.
How it works
AskHuman routes gated intent to a human and returns a terminal Decision your agent can trust.
Gated intent waiting on a human. One Request, opaque payload, idempotent create.
Reach the principal with a CTA — email first, SMS second. Magic link, no account.
Approve, Deny, or Expire. Humans decide; the timer Expires if nobody acts.
Decision delivered to the caller via poll, optional webhook. Retryable.
Use cases
Gate money movement, write tools, and outbound that shouldn’t auto-run.
Agent prepares a payout. Human Approves before money moves.
Gate delete, deploy, purchase, or any tool you mark consequential — same Request → Notification → Decision → Resolution loop.
Agent is about to email, refund, or change an account. Human confirms before it ships.
Quickstart for humans
No AskHuman account on the decide path. Open the magic link from askhuman@agentmail.to, Approve or Deny, and close the tab. If the timer hits first, the Request Expires — same Resolution path for the agent.
Quickstart for agents
POST /clients is public. After a human Approves registration, poll GET /clients/:id for a one-time ask_live_… key. Then create Requests with Authorization: Bearer + Idempotency-Key. The magic link lives only in the Notification.
curl -sS -X POST https://api.ask-human.dev/clients \
-H 'Content-Type: application/json' \
-d '{
"name": "my-agent",
"principal": { "connector": "email", "contact": "you@example.com" }
}'
# Human Approves the registration email, then:
# curl -sS https://api.ask-human.dev/clients/<client-id>
# → api_key shown once
curl -sS -X POST https://api.ask-human.dev/requests \
-H 'Authorization: Bearer ask_live_…' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: demo-001' \
-d '{
"summary": "Wire $12,400 to Northwind Supplies?",
"payload": { "amount": 12400, "vendor": "Northwind Supplies" },
"principal": { "connector": "email", "contact": "cfo@acme.co" },
"expires_in_seconds": 600
}'
curl -sS https://api.ask-human.dev/requests/<request-id> \
-H 'Authorization: Bearer ask_live_…'
# When terminal, response includes Decision:
# approve | deny | expire
# Optional: set callback_url on create for a webhook.
Prefer trying it live? Open the production API · base URL constant for links only; the homepage demo runs entirely in your browser.
API peek
POST
/clients
Register a client (public). Human Approves → one-time ask_live_… key via GET /clients/:id.
POST
/requests
Create a Request. Requires Bearer + Idempotency-Key. Returns 201 (or 200 on replay).
GET
/requests/:id
Poll until Decision is terminal. Same Bearer client that created it.
GET
/a/:token
Human decide page — Approve / Deny. Token ≠ request id. No Bearer.
POST
/clients/:id/revoke
Revoke your own key (Bearer of that client).
Payload is opaque JSON. AskHuman does not interpret your vertical logic.
Connectors in v1: email, SMS. Pass principal on each Request — no saved profiles.
Register a client against the live API, or replay the demo above offline.
curl -sS -X POST https://api.ask-human.dev/clients \
-H 'Content-Type: application/json' \
-d '{"name":"my-agent","principal":{"connector":"email","contact":"you@example.com"}}'