Warming API
API reference for IP and domain warming management.
Manage IP and domain warming for your sending domains. Warming gradually increases your sending volume over several phases, building sender reputation with mailbox providers and ensuring high deliverability.
Warming Phases
Postscale uses a four-phase warming schedule with automatically enforced rate limits:
| Phase | Duration | Daily Limit | Description |
|---|---|---|---|
phase_1 | Week 1-2 | 50 - 1,500 | Initial low-volume sending to establish reputation |
phase_2 | Week 3-4 | 2,000 - 10,000 | Moderate volume with expanded ISP distribution |
phase_3 | Week 5-6 | 15,000 - 60,000 | High volume with reputation monitoring |
phase_4 | Week 7-8 | 100,000 - 200,000 | Near-production volume before full graduation |
warmed | Ongoing | Unlimited | Fully warmed with no warming restrictions |
Advancement is checked once daily at 01:00 UTC. The minimum days in the current phase must have elapsed, delivery metrics must meet thresholds (delivery rate, bounce rate, complaint rate), and average daily volume must reach at least 50% of the current phase's daily limit (rounded down to a whole recipient). The phase timelines are estimates.
The evaluation window includes the previous seven complete UTC days plus today's sends so far. Average daily volume is metrics.total_sent / metrics.period_days, with period_days set to 7, including days without sends. Counts are accepted recipients, not message submissions. For a Phase 1 daily limit of 1,500, the minimum is 750 recipients/day or 5,250 accepted recipients in the evaluation window. Zero activity does not qualify for advancement.
eligible_for_advancement uses the same requirements as the automatic worker. advancement_blockers includes unmet volume requirements with actual and required recipient counts. Eligibility can change before the next daily check. For normal sending volume below the threshold, see options for low-volume senders.
Skipping the warming process for a new domain or IP can severely damage your sender reputation. Mailbox providers like Gmail, Microsoft, and Yahoo throttle or reject mail from unknown senders that suddenly transmit high volumes. Always complete the full warming schedule before sending at production volume.
Get Warming Status
GET /v1/domains/:id/warming
Retrieve the current warming status, rate limits, sending usage, and delivery metrics for a domain.
Example Request
curl -X GET https://api.postscale.io/v1/domains/d290f1ee-6c54-4b01-90e6-d701748f0851/warming \
-H "Authorization: Bearer ps_live_your_api_key"
Response
{
"domain_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"domain": "example.com",
"phase": "phase_2",
"warming_started_at": "2026-01-10T08:00:00Z",
"phase_started_at": "2026-01-24T00:00:00Z",
"days_in_current_phase": 5,
"current_limits": {
"daily_limit": 5000,
"hourly_limit": 500,
"per_minute_limit": 20
},
"today_sent": 1200,
"this_hour_sent": 85,
"remaining_today": 3800,
"remaining_this_hour": 415,
"metrics": {
"period_days": 7,
"total_sent": 8500,
"total_delivered": 8415,
"total_bounced": 85,
"total_hard_bounce": 12,
"total_complaints": 2,
"delivery_rate": 0.99,
"bounce_rate": 0.01,
"hard_bounce_rate": 0.0014,
"complaint_rate": 0.0002
},
"eligible_for_advancement": false,
"advancement_blockers": [
"only 5 of 7 required days in phase",
"average daily volume 1214.29 below minimum 2500 accepted recipients (8500/17500 in the evaluation window)"
],
"next_phase": "phase_3",
"next_phase_limits": {
"daily_limit": 15000,
"hourly_limit": 1500,
"per_minute_limit": 50
}
}
Get Warming History
GET /v1/domains/:id/warming/history
Retrieve the phase transition history for a domain, including the reason and metrics snapshot for each transition.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Number of results to return (default: 50, max: 100) |
Example Request
curl -X GET "https://api.postscale.io/v1/domains/d290f1ee-6c54-4b01-90e6-d701748f0851/warming/history?limit=10" \
-H "Authorization: Bearer ps_live_your_api_key"
Response
{
"domain_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"history": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"domain_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"from_phase": "phase_1",
"to_phase": "phase_2",
"reason": "metrics_passed",
"metrics_snapshot": {
"bounce_rate": 0.008,
"complaint_rate": 0.0001,
"delivery_rate": 0.992,
"daily_volume": 1500,
"days_in_phase": 14
},
"triggered_by": "system",
"created_at": "2026-01-24T00:00:00Z"
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"domain_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"from_phase": "not_started",
"to_phase": "phase_1",
"reason": "warming_started",
"triggered_by": "api",
"created_at": "2026-01-10T08:00:00Z"
}
]
}
Start Warming
POST /v1/domains/:id/warming/start
Start the warming process for a domain. The domain must have SPF or DKIM verified unless the force flag is set.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
force | boolean | No | Skip DNS verification checks (default: false) |
Example Request
curl -X POST https://api.postscale.io/v1/domains/d290f1ee-6c54-4b01-90e6-d701748f0851/warming/start \
-H "Authorization: Bearer ps_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"force": false
}'
Response
{
"message": "warming started",
"phase": "phase_1"
}
Error: Prerequisites Not Met
If SPF and DKIM are not verified and force is false:
{
"error": "prerequisites_not_met",
"message": "Domain must have SPF or DKIM verified before starting warming",
"spf_verified": false,
"dkim_verified": false
}
Error: Already Warming
If the domain is already in an active warming phase:
{
"error": "already_warming",
"message": "Domain is already in warming phase",
"current_phase": "phase_2"
}
Pause Warming
POST /v1/domains/:id/warming/pause
Pause the warming process for a domain. The domain must be in an active warming phase. While paused, no emails can be sent through the warming pipeline.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Reason for pausing (default: "manual pause") |
Example Request
curl -X POST https://api.postscale.io/v1/domains/d290f1ee-6c54-4b01-90e6-d701748f0851/warming/pause \
-H "Authorization: Bearer ps_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"reason": "Investigating high bounce rate from Yahoo"
}'
Response
{
"message": "warming paused",
"previous_phase": "phase_2",
"reason": "Investigating high bounce rate from Yahoo"
}
Error: Not Warming
If the domain is not in an active warming phase:
{
"error": "not_warming",
"message": "Domain is not currently in an active warming phase",
"current_phase": "not_started"
}
Resume Warming
POST /v1/domains/:id/warming/resume
Resume warming from a paused state. The domain returns to the phase it was in before it was paused.
Example Request
curl -X POST https://api.postscale.io/v1/domains/d290f1ee-6c54-4b01-90e6-d701748f0851/warming/resume \
-H "Authorization: Bearer ps_live_your_api_key"
Response
{
"message": "warming resumed",
"phase": "phase_2"
}
Error: Not Paused
If the domain is not in a paused state:
{
"error": "not_paused",
"message": "Domain is not in paused state",
"current_phase": "phase_2"
}
Warming Phase Values
| Phase | Description |
|---|---|
not_started | Warming has not been initiated |
phase_1 | Initial low-volume phase (week 1-2) |
phase_2 | Moderate volume phase (week 3-4) |
phase_3 | High volume phase (week 5-6) |
phase_4 | Near-production volume phase (week 7-8) |
warmed | Fully warmed, no warming restrictions |
paused | Warming paused manually or due to metric thresholds |
suspended | Warming suspended for policy violation |