Blog · Published 2026-09-29 · AgentiSend team
How loop detection decides a send is a repeat, and what it holds
How the loop guard decides a send is a repeat, what it holds for a person, and the send it still delivers.
Filed under Guardrails
The loop guard reads this key's recent sends before it accepts another. A near-identical send is held when it would be the 4th inside 60 minutes. The held copy stays in the approval queue. A person approves it, which sends it, or rejects it, which closes it.
What counts as a repeat
The window is the last 60 minutes on this key. A prior send counts when it shares the recipient and both the subject and the body are at least 85% similar. The candidate is held when it would be the 4th such send.
A subject below that similarity is a different send. The guard is for a repeat of the same message.
What is held, and what still sends
The refusal code is approval_required. retryable is false, so the body leaves out retry_after_seconds. The response carries action_id, the id of the held row. The fix is the catalogue sentence below. When the loop guard is what held the send, the message is the guard's own sentence, which names the matching sends already in the window. The fix stays the catalogue's.
{
"error": {
"code": "approval_required",
"message": "Blocked: this agent has sent 3 near-identical emails to customer@example.com within 60 minutes, which matches a retry or script loop; review the agent before sending more.",
"fix": "Do not send it again: a person approves or rejects it in the console under Agents → Approvals, and approving sends it — the message then appears in GET /emails. action_id in this error names the held send; the key that asked cannot approve itself, and a retry waits on the same approval.",
"docs_url": "https://agentisend.com/what-does-approval-required-mean#approval_required",
"retryable": false
}
}What approval_required means describes the held row. The approvals guide describes how long the hold lasts and the calls that release it or close it.
A second signal watches recipient collapse. It runs on a key set to watch both signals, and on a marketing send from a key with no setting. A new key watches repetition only. Once the window holds at least 20 sends and the effective number of recipients is below 3, the next send to one of the inboxes that window piled onto is held. Mail to any other recipient still sends. That is the send that shares the window and still goes out.
The modes are on loop detection.
What a budget does here
A budget caps how many sends a key may accept. A loop that stays under the budget is still a loop, so this guard is a separate check. A held send is not accepted, so it does not spend the budget. The budget is spent when a send is accepted. Why every API key is created with a budget states what the budget stops.