Skip to content
ContactForms

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 202 with approval: id (the token, shown to you once), status: "pending", expiresAt, a url for the person and a summary of 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 argsHash of the card the person was shown (read it from GET /api/approvals/:id as a signed-in person). A missing hash is 422 validation_failed; a hash that is not the approval's is 409 approval_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 404 approval_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_changed and nothing runs. An approval is used once (409 approval_used) and expires in minutes (410 approval_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.