Approve your agent's email before it goes out
Give the agent a key that can write drafts but can't send them. A person reads each draft in the app and clicks Send.
If an agent sends a customer the wrong refund amount, the email is already in their inbox. Until you trust what an agent writes, have it save its replies as drafts and let a person send them. ACK enforces this through the agent's API key. If the key can't send, the agent can't either, even when an email tells it to.
Make a key that can only draft
Create a key for the agent's inbox and list the permissions it gets. When a request includes permissions, ACK grants the ones set to true and nothing else.
curl https://api.ack.now/v0/inboxes/support-agent@trial.ack.now\
/api-keys \
-H "Authorization: Bearer $ACK_API_KEY" \
--json '{"name": "support-agent, drafts only",
"permissions": {"inbox_read": true, "message_read": true,
"draft_read": true, "draft_create": true,
"draft_update": true}}'
# {"api_key": "ack_live_…", …}POST /v0/inboxes/{inbox_id}/api-keys
{"permissions": {
"message_read": true,
"draft_create": true, …}}The agent can read mail in that one inbox and write drafts there. If it tries to send, reply or forward, the request fails with a 403 that names the missing permission. Over MCP the agent gets the same message back as a tool error.
Save the reply as a draft
When mail arrives, the agent creates a draft with in_reply_to set to the message it's answering. ACK copies the recipient and the subject from that message and puts the draft in the same thread.
curl https://api.ack.now/v0/inboxes/support-agent@trial.ack.now\
/drafts \
-H "Authorization: Bearer $AGENT_KEY" \
--json '{"in_reply_to": "<CAH7f2…@mail.northwind.co>",
"text": "Found the duplicate charge and refunded it."}'
# {"draft_id": "drf_…", …}POST /v0/inboxes/{inbox_id}/drafts
{"in_reply_to": "<CAH7f2…>",
"text": "Found the duplicate…"}Over MCP, the agent calls create_draft with inboxId, inReplyTo and text.
Send it from the app
Drafts appear on the inbox's Drafts page, whether the agent saved them through the API or someone saved them in the app. Open a draft to edit it and send it, or send it straight from the list. Delete it if it shouldn't go out.
If the review happens somewhere else, such as a ticketing system or a chat channel, send the draft from your own code with a key that has draft_send:
curl -X POST https://api.ack.now/v0/inboxes/support-agent@trial.ack.now\
/drafts/$DRAFT_ID/send \
-H "Authorization: Bearer $ACK_API_KEY"POST /v0/inboxes/{inbox_id}
/drafts/{draft_id}/sendSending turns the draft into a sent message in the thread and deletes the draft.
Schedule it for later
A draft can also wait until a set time. Give it a send_at time in ISO 8601 and it sends itself then. Change send_at to move it, or delete the draft to cancel. Scheduling counts as sending, so setting send_at needs draft_send as well, and the drafts-only key above can't do it.