Approvals
Draft. This page describes approvals as implemented. The production host names are not live yet.
What waits for a person
Reading, creating a draft form and sending a test lead to the owner need no approval. Anything that changes who is notified, archives a form, deletes a lead or emails a customer waits for the site's owner or an editor to click. A key can ask, never decide.
Ask, wait, decide
Ask to change who is notified
PATCH /api/forms/f_8Kq2xLm9
Authorization: Bearer <your agent key>
Content-Type: application/json
{
"recipients": [
"owner@example.com"
]
}
-> 202: a pending approval: nothing has changed yet
Ask to delete a lead
DELETE /api/submissions/kg2c4q1h7b9r3n5v8x0z6m2w4t1e
Authorization: Bearer <your agent key>
-> 202: a pending approval for the owner
Check an approval
GET /api/approvals/apv_Hq3rT8vXz1LkP9mNc2WsD7yB4eFa0uJg
Authorization: Bearer <your agent key>
-> 200: pending, used, declined or expired
Approve (a signed-in person; a key is refused with 403)
POST /api/approvals/apv_Hq3rT8vXz1LkP9mNc2WsD7yB4eFa0uJg/approve
Authorization: Bearer <a signed-in person's token>
Content-Type: application/json
{
"argsHash": "9f2c7a41d83b0e65a1c4f7d20b96e83a5d17c04be2f68a93d0715bc4e8a2f6d1"
}
-> 200: executed: the exact action ran once
- Asking answers
202withapproval:id(the token, shown to you once),status: "pending",expiresAt, aurlfor the person and asummaryof the exact action. Nothing has changed. - The Agents page shows a card with the same summary, the complete list of addresses, who asked and the minutes left. Approve runs the action exactly once; Decline ends it.
- Over REST, approving sends the
argsHashof the card the person was shown (read it fromGET /api/approvals/:idas a signed-in person). A missing hash is 422validation_failed; a hash that is not the approval's is 409approval_changed. - Addresses are trimmed, lowercased and de-duplicated before the approval is stored, so the same request written two ways is one approval.
- Only the key that asked can read the status (
pending,used,declined,expired); anyone else gets 404approval_not_found. - The approval is bound to the exact arguments. If they no longer match what the person was shown, or the form or lead changed, approving answers 409
approval_changedand nothing runs. An approval is used once (409approval_used) and expires in minutes (410approval_expired). - Asking again with the same arguments returns the same approval (
duplicate: true); it does not pile up.
Who can decide
A signed-in owner or editor of the site, checked again at the moment of the click (a person removed or demoted in between cannot approve). Archiving a form and deleting a lead need an owner. An API key, whatever its scope, is refused with 403 role_not_allowed on approve and decline.
Limits
At most 20 approvals wait per account (the 21st is 429 approval_limit with a fix). Decided and expired approvals are deleted after 30 days.
Not available yet
- Replying to a lead (needs email sending): refused up front with 503
approval_unavailable, nothing waits.Soon - Routing rules and auto-replies: refused up front with 503
approval_unavailable.Soon
No MCP tool is gated: the five tools only read, create drafts or send a test to the owner. Gated changes are the REST routes above.