Questions · Updated 2026-09-28
What does a spam complaint do to my account?
A spam complaint suppresses the recipient's address, records an email.complained event on the message, and counts toward your account's complaint rate, which the enforcement ladder in GET /trust/standing judges against GET /trust/thresholds. The suppression row is a person's to lift, in the console.
A spam complaint does three things to your account. The message's status becomes complained and GET /emails/{id}/events records email.complained; GET /emails/{id}/explain then says "The recipient marked this message as spam. The address is now suppressed automatically." The address joins GET /suppressions with origin complaint, so a later POST /emails to it is refused with suppressed_recipient. And the complaint counts toward the account's complaint rate, which the enforcement ladder reads.
The suppression
The row on GET /suppressions carries email, level address and origin complaint. The DELETE /suppressions/{id} summary draws the line: "Remove one suppression row. A hard bounce you have fixed can be cleared with an API key; an unsubscribe or a spam complaint is a person’s to lift, in the console." The suppressed_recipient fix ends the same way: "an unsubscribe or a spam complaint cannot — that address asked not to be contacted." An API key that tries answers human_action_required, with the message "This address asked not to be contacted — it unsubscribed or reported a message as spam. An API key cannot lift that." and the fix "Leave it suppressed. If it was recorded in error, a person signed in to the console can remove it under Suppressions."
GET /emails/{id}/explain on the complained message returns retryable false and two actions. The first: "Do not send to this address again — it is suppressed; sending more mail hurts the whole domain." The second, on GET /emails/{id}/mime: "Check what this message looked like and whether the recipient expected it." That second question is the one to answer before the next send.
The rate
The complaint rate is complaints divided by sends over the last 7 days, and simulated sends are left out of both counts. GET /trust/thresholds returns the lines: metrics.complaint.warn is 0.05%, metrics.complaint.pause is 0.08%, and min_sample is 100. Trust and enforcement states the sample rule: "No step until the window holds 100 delivered-or-bounced sends."
GET /trust/standing returns state (ok, warning, throttled or paused) and reasons, each with metric, value, threshold, window and samples, so the reading that moved the standing is on the response with the messages behind it. The ladder itself is published at /policy/enforcement. The guide describes the two rungs: "Warn. Your standing changes and trust.warning fires. Nothing about your sending changes." and "Pause. Sending stops. trust.paused fires." A send while paused is refused with trust_paused; the catalogue message is "Sending is paused by the trust system." and the fix is "Review reasons via GET /trust/standing, then file an appeal via POST /trust/appeal." GET /usage carries account.complained_30d for a running count.
curl -sS -X GET https://api.agentisend.com/trust/standing \
-H "Authorization: Bearer $AGENTISEND_API_KEY"200
{
"history": [],
"next_review_at": "2026-09-04T09:14:00Z",
"reason_codes": [],
"reasons": [],
"sla_deadline_at": "2026-09-04T09:14:00Z",
"state": "ok"
}Hearing about it
Subscribe to email.complained on POST /webhooks; the payload's data carries email_id and tags like every email.* event. To exercise the handler, send to complaint@simulator.agentisend.com: the message goes email.delivered, then email.complained, and ends complained, with "simulated": true in data. The test page states the limit: "A simulated bounce, complaint or suppression does not add the address to your suppression list and does not count against your sending standing."