Warmup
Warmup endpoints report on the health of your mailboxes and the automated inbox-placement emails Warmerly sends and receives between accounts. Use them to build dashboards, alert on score drops, or list the individual warmup emails sent for an account.
Get warmup stats
GET /warmup/stats
Returns a point-in-time summary across your accounts: how many are active, aging, or paused, how many warmup emails have gone out today, and the average health score.
X-Project-Id is optional here — omit it to get stats across every project in your
current workspace, or pass it to scope the numbers to a single project.
curl https://app.warmerly.com/api/v1/warmup/stats \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "X-Project-Id: 8f14e45f-ceea-4c6a-8c8d-6b1a5b5c9c1a"
{
"activeAccounts": 12,
"agingAccounts": 3,
"pausedAccounts": 1,
"todaySent": 84,
"todayScheduled": 96,
"avgHealthScore": 87
}
| Field | Type | Description |
|---|---|---|
activeAccounts | integer | Accounts with status = active (past the ramp period). |
agingAccounts | integer | Accounts still ramping up (status = aging). |
pausedAccounts | integer | Accounts with warmup paused. |
todaySent | integer | Warmup emails sent or processed today (UTC). |
todayScheduled | integer | Warmup emails still pending for today (UTC). |
avgHealthScore | integer | null | Average last_health_score across accounts that have one. |
Get warmup trends
GET /warmup/trends
Returns a daily time series plus a current-vs-previous-window summary, suitable for
charting score and inbox-placement rate over time. Backed by daily health_snapshots
rows, aggregated across the accounts you have access to.
X-Project-Id is optional, same as /warmup/stats — pass it to scope to one project.
| Query param | Type | Default | Description |
|---|---|---|---|
days | 7 | 30 | 90 | 30 | Length of the window. Any other value falls back to 30. |
curl "https://app.warmerly.com/api/v1/warmup/trends?days=30" \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "X-Project-Id: 8f14e45f-ceea-4c6a-8c8d-6b1a5b5c9c1a"
{
"range": { "days": 30, "from": "2026-06-03", "to": "2026-07-02" },
"series": [
{ "date": "2026-06-03", "sent": 41, "inbox": 37, "spam": 3, "bounce": 1, "score": 82 },
{ "date": "2026-06-04", "sent": 45, "inbox": 42, "spam": 2, "bounce": 1, "score": 84 }
],
"summary": {
"avgScore": 87,
"avgScorePrev": 81,
"avgScoreDelta": 6,
"inboxRate": 92,
"inboxRatePrev": 88,
"inboxRateDelta": 4,
"sentTotal": 1240,
"sentTotalPrev": 1105
}
}
series is ordered ascending by date and covers the requested window only. summary
compares the requested window (cur) against the equal-length window immediately
before it (prev); any rate is null when there's no data to divide by. inboxRate is
inbox / (inbox + spam + bounce), expressed as a whole-number percentage.
List warmup jobs
GET /warmup/jobs
Returns individual warmup emails (a "job" is one email sent from one warmed mailbox to
another), most recent first. This endpoint doesn't take X-Project-Id — filter by
account_id to scope results to a specific mailbox.
| Query param | Type | Description |
|---|---|---|
status | pending | sending | sent | processed | failed | Filter by job status. |
account_id | uuid | Only jobs where this account is the sender or recipient. |
limit | integer, 1–100 | Default 50. |
curl "https://app.warmerly.com/api/v1/warmup/jobs?account_id=1c2d3e4f-...&status=processed&limit=20" \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{
"jobs": [
{
"id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"senderAccountId": "1c2d3e4f-1111-4a2b-8c3d-4e5f6a7b8c9d",
"recipientAccountId": "2d3e4f5a-2222-4a2b-8c3d-4e5f6a7b8c9d",
"scheduledAt": "2026-07-02T08:00:00.000Z",
"sentAt": "2026-07-02T08:00:42.000Z",
"status": "processed",
"subject": "Re: quick question about the roadmap",
"deliveredFolder": "inbox",
"wasOpened": true,
"wasReplied": false,
"emailType": "reply"
}
]
}
| Field | Type | Description |
|---|---|---|
id | uuid | Job ID. |
senderAccountId / recipientAccountId | uuid | The two mailboxes involved in the exchange. |
scheduledAt | timestamp | When the job was scheduled to send. |
sentAt | timestamp | null | When it actually sent. |
status | string | pending, sending, sent, processed, or failed. |
subject | string | Subject line used. |
deliveredFolder | inbox | spam | promotions | unknown | null | Where the recipient mailbox filed it, once processed. |
wasOpened / wasReplied | boolean | Whether the recipient side opened or replied to it. |
emailType | string | null | Internal template category (e.g. intro, reply). |
Per-account health and job history
Two account-scoped endpoints give you the same data filtered to a single mailbox. Both
take the account ID from the URL, not X-Project-Id.
Get an account's health snapshots
GET /accounts/{id}/health
| Query param | Type | Default | Description |
|---|---|---|---|
days | integer, 1–365 | 90 | How far back to return daily snapshots. |
curl "https://app.warmerly.com/api/v1/accounts/1c2d3e4f-.../health?days=30" \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{
"health": [
{
"id": "b3e1c9a0-....",
"accountId": "1c2d3e4f-....",
"date": "2026-07-02",
"sentCount": 22,
"inboxCount": 20,
"spamCount": 1,
"bounceCount": 1,
"replyCount": 3,
"openCount": 17,
"score": 89,
"trend": "up",
"spamScore": 0,
"computedAt": "2026-07-02T00:15:00.000Z"
}
]
}
health is ordered most recent first. trend is up, flat, or down relative to the
previous day's score.
Get an account's warmup job history
GET /accounts/{id}/warmup-jobs
Returns the last 100 jobs (sent or received) for the account, plus a 30-day daily
summary. Returns 404 if the account doesn't exist.
curl "https://app.warmerly.com/api/v1/accounts/1c2d3e4f-.../warmup-jobs" \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{
"jobs": [
{
"id": "9b1deb4d-....",
"scheduledAt": "2026-07-02T08:00:00.000Z",
"sentAt": "2026-07-02T08:00:42.000Z",
"status": "processed",
"senderAccountId": "1c2d3e4f-....",
"recipientAccountId": "2d3e4f5a-....",
"subject": "Re: quick question about the roadmap",
"deliveredFolder": "inbox",
"wasOpened": true,
"wasReplied": false,
"emailType": "reply"
}
],
"dailySummary": [
{ "day": "2026-07-02", "sent": 22, "received": 19, "inbox": 20, "spam": 1 }
]
}
dailySummary covers the trailing 30 days: sent and received count jobs where the
account was sender/recipient respectively; inbox/spam count only processed jobs the
account sent that landed in each folder.
Pause and resume warmup on an account
Warmup only runs against accounts with status = active or aging. Pausing an account
stops it from being scheduled as a sender or recipient in future warmup jobs.
POST /accounts/{id}/pause
POST /accounts/{id}/resume
Both take no request body and return 404 if the account doesn't exist.
curl -X POST https://app.warmerly.com/api/v1/accounts/1c2d3e4f-.../pause \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{ "ok": true }
resume sets the account back to active, clears needsReconnect and
disconnectReason, and resets consecutiveFailures to 0:
curl -X POST https://app.warmerly.com/api/v1/accounts/1c2d3e4f-.../resume \
-H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{ "ok": true }
Errors
An account ID that doesn't exist returns 404 on any of the endpoints above:
{ "error": { "code": "not_found", "message": "not_found", "details": null } }
Missing or invalid X-Api-Key returns 401, following the same shape described in
Authentication.
