Account Health API
GET /v1/account/health: query the SES health verdict Wraps already computes every hour, so an agent or CI job can ask 'am I safe to send right now?' before it sends. Zero AWS calls, bounded by the last hourly sweep.
Wraps deploys your email infrastructure into your own AWS account, which means you own its failure modes too: the sandbox, production access, enforcement pauses, reputation review thresholds, the 24-hour quota. GET /v1/account/health is the queryable answer to "am I safe to send right now?" — a fact about infrastructure you own, not a support article.
A hosted ESP has no per-customer SES account to describe, so this endpoint has no equivalent there. It exists because the hourly account-health sweep that watches your connected AWS accounts already computes every number below — this route just answers with what it already knows, reading Postgres only. No AWS call happens while you wait on this request.
Returns every AWS account connected to your organization, plus a top-level rollup: the worst status across all of them wins.
curl https://api.wraps.dev/v1/account/health \ -H "Authorization: Bearer wraps_your_api_key"{ "status": "at_risk", "checkedAt": "2026-09-04T09:00:00.000Z", "accounts": [ { "id": "aws-acc-123", "accountNumber": "123456789012", "region": "us-east-1", "status": "at_risk", "checkedAt": "2026-09-04T09:00:00.000Z", "sandbox": false, "productionAccessEnabled": true, "sendingEnabled": true, "enforcementStatus": "HEALTHY", "quota": { "max24Hour": 50000, "sentLast24Hours": 41230, "usedRatio": 0.8246, "maxSendRate": 14 }, "reputation": { "bounceRate": 0.004, "complaintRate": 0.0001 }, "thresholds": { "bounceReview": 0.05, "bouncePause": 0.10, "complaintReview": 0.001, "complaintPause": 0.005, "quotaWarn": 0.8 }, "reasons": ["quota_high"] } ]}GET /v1/account/health/:awsAccountId returns the same per-account shape for exactly one connected account, org-scoped — a request naming an account that belongs to another organization, or that does not exist, returns 404.
curl https://api.wraps.dev/v1/account/health/aws-acc-123 \ -H "Authorization: Bearer wraps_your_api_key"Every status is one of exactly four values, on both the per-account objects and the top-level rollup:
| Status | Meaning |
|---|---|
healthy | Sending is enabled, enforcement is HEALTHY, and every rate is below AWS's review line. |
at_risk | One or more numbers has crossed AWS's review line — enforcement is PROBATION, or bounce/complaint rate is in the review range, or the 24-hour quota is nearly used up. |
in_danger | Sending is disabled, enforcement has moved past PROBATION, or a rate has crossed AWS's pause line. This covers a paused account — the specific cause is always in reasons. |
unknown | No hourly sweep has ever completed for this account. Not a fifth severity level — the absence of a measurement. |
An account nobody has been able to check is exactly the account most likely to be in trouble — treating it as healthy would be the exact lie this endpoint exists to avoid. The same rule applies to the org-wide rollup: unknown outranks healthy, so an org with one never-swept account and nine healthy ones still rolls up to unknown. The full ranking, worst first: in_danger > at_risk > unknown > healthy.
The same rule holds field by field: a never-swept account reports null for every rate, quota figure, and sandbox — never a measured-looking 0 or false.
thresholds on every account is AWS's own published review and pause lines — the same numbers Wraps compares against when it computes status, not numbers Wraps invented. A caller can compute its own headroom (e.g. thresholds.bouncePause - reputation.bounceRate) rather than waiting for the status to change.
Every rate is a decimal between 0 and 1, never a percentage. A bounce rate of 5% is 0.05, not 5. The same is true of quota.usedRatio and every field under thresholds.
Every number here comes from the last completed hourly account-health sweep, not a live AWS read. checkedAt is the contract that keeps that honest — it is the timestamp of that sweep, per account and, on the rollup, the OLDEST timestamp among the accounts represented, so the freshness claim holds for every account the rollup speaks for. A verdict from over an hour ago usually just means the next sweep hasn't run yet; a verdict from much longer ago is worth investigating on its own.
unknown — check /docs/guides/production-access if that persists.The thresholds this endpoint reports come from AWS's real enforcement lines. The bounce guide covers what moves them and the alarms Wraps deploys per preset.