Questions · Updated 2026-09-28

Why are my emails going to spam?

Emails go to spam when the receiving mailbox accepts them and then files them, and the causes are content, authentication and complaint history. POST /emails/lint scores the content before a send, GET /deliverability/dmarc shows every source sending as your domain, and GET /trust/standing shows where your bounce and complaint rates sit.

Emails go to spam when the receiving mailbox accepts the message and then files it, so the API records delivered and the recipient reads nothing. Three things you control feed that decision: the content, the authentication on the sending domain, and the complaint history behind it. POST /emails/lint checks the first without sending. GET /domains/{id} and GET /deliverability/dmarc check the second. GET /trust/standing reads the third. This page is diagnosis, not a placement rate.

Lint the content first

POST /emails/lint takes from, to, subject, html, text and headers. Its summary is "Deliverability lint without sending: a 0-100 placement score plus every finding with its fix." Each finding carries rule, severity (error, warning or info), message and fix. The empty_subject rule says "No subject line — the single fastest way into the spam folder." and its fix is "Add a subject of 2-60 characters." The single_link_only rule says "One link in a long email is a classic phishing shape." and its fix is "Add context around the link or a second, related link." The all_caps_subject rule says "ALL-CAPS subject lines read as spam." Fix every error before sending, then run the same body through the lint again and read the new score.

curl -sS -X POST https://api.agentisend.com/emails/lint \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"from":"billing@yourdomain.com","to":["customer@example.com"]}'
201
{
  "findings": [],
  "score": 1
}
Response

A separate scanner runs inside every send and inside POST /emails/preflight. It refuses a message shaped like credential harvesting, and it refuses wording about a purchased or scraped list; the send then fails with invalid_parameter and a message that begins "This content was refused by the abuse scanner". It warns, without refusing, on shortened URLs, punycode lookalike domains, and urgency-plus-money language. POST /emails/preflight reports the verdict and its findings under checks.content.

Check who is sending as your domain

Deliverability says to publish SPF, DKIM and DMARC and keep them published. GET /domains/{id} returns each record with status and observed, so a record that dropped out of DNS shows as failed with the fix beside it. GET /deliverability/dmarc reads the aggregate reports and its summary promises "every address sending as you, flagged when it is not one of ours": a row in sources with ours: false is another system using your domain, and its failing volume lands on your reputation. Sending application mail from a subdomain keeps that damage contained; the reasoning is on Should I send email from a subdomain or the root domain?

Read the complaints

A recipient who presses the spam button produces an email.complained event on GET /emails/{id}/events, and GET /emails/{id}/explain then says "The recipient marked this message as spam. The address is now suppressed automatically." Enough of those and the trust ladder acts: complaints warn at 0.05% and pause at 0.08%, bounces warn at 2% and pause at 4%, and no step happens until the window holds 100 sends. GET /trust/thresholds returns those figures and GET /trust/standing returns your reading against them. GET /deliverability/domains lists every sending domain "worst first", so the domain pulling the account down is the first row.

Every call above is a fact about one message or one domain. None of them is an inbox rate.

Next