# Account Health API

Source: https://wraps.dev/docs/guides/account-health

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.

## Org-wide rollup

Returns every AWS account connected to your organization, plus a top-level rollup: the worst status across all of them wins.

terminal.sh

```
curl https://api.wraps.dev/v1/account/health \  -H "Authorization: Bearer wraps_your_api_key"
```

response.json

```
{  "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"]    }  ]}
```

## Single account

`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`.

terminal.sh

```
curl https://api.wraps.dev/v1/account/health/aws-acc-123 \  -H "Authorization: Bearer wraps_your_api_key"
```

## Reading the status field

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. |

## Why unknown is not healthy

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 and headroom

`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`.

## Freshness: checkedAt

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.

-   Poll this endpoint before a send, not instead of watching for in-band send failures — the verdict is at most an hour stale.
-   An account that has never connected, or whose console-access role cannot be assumed, reports `unknown` — check `/docs/guides/production-access` if that persists.

## Next steps

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.

[Bounce & complaint handling](https://wraps.dev/docs/guides/bounce-handling)[Production access](https://wraps.dev/docs/guides/production-access)[API Reference](https://wraps.dev/docs/reference/api)
