Skip to main content
PATCH
/
api
/
email
/
accounts
/
{id}
/
retry-warmup
Retry warmup for a stalled email account
curl --request PATCH \
  --url https://app.puffle.ai/api/email/accounts/{id}/retry-warmup \
  --header 'Authorization: Bearer <token>'
{
  "account": {
    "id": "aaaa1111-1111-1111-1111-111111111111",
    "user_id": "11111111-1111-1111-1111-111111111111",
    "type": "email",
    "email_address": "[email protected]",
    "status": "warming",
    "warmup_status": "warming",
    "agentmail_inbox_id": "inb_abc123",
    "daily_limit": 50,
    "created_at": "2026-04-20T15:00:00Z",
    "updated_at": "2026-04-22T08:15:00Z",
    "email_domains": {
      "id": "dddd1111-1111-1111-1111-111111111111",
      "domain": "acme.com",
      "status": "verified"
    }
  }
}

Overview

Retry path for email accounts whose initial warmup-enable call to Instantly failed after the DB row was already written. The route:
  1. Loads the account and verifies ownership (plus pulls its linked email_domains row for context).
  2. Gates on status: "pending" AND warmup_status: "not_started" — any other combination returns 409.
  3. Calls Instantly’s POST /accounts/warmup/enable (idempotent — Instantly accepts already-warming emails and returns 200).
  4. Transitions the row to status: "warming" / warmup_status: "warming" via compare-and-swap, so concurrent retries can’t double-apply.

AI agent notes

Warmup is a multi-day process. A successful retry only moves the account into warming — it still has to accrue reputation over ~2–3 weeks before it graduates to active and can send. Track progress via getWarmupAnalytics.Idempotent. If Instantly was already warming the inbox from a prior partial attempt, the retry still returns 200 and transitions the DB row forward. Safe to call until success.Gate carefully. Retry is only valid when status === "pending" AND warmup_status === "not_started". If the account already warmed up, banned out, or graduated to active, this endpoint returns 409 — use getWarmupAnalytics to read current state instead.Status-vs-502 split.
  • 502 means Instantly rejected the call — try again after a short backoff.
  • 500 with the message “Warmup was enabled but failed to update account status” means Instantly accepted but our DB write failed. Safe to retry immediately; a second Instantly call is a no-op.
Chains with: getWarmupAnalytics to watch reputation climb; launchCampaign once status === "active".

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

id
string<uuid>
required

Supabase UUID of the email account. Must be owned by the caller and currently in status: pending + warmup_status: not_started.

Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$

Response

Warmup re-enabled. Returns the refreshed account row.

account
object
required

Account row after the retry. On success, status is warming and warmup_status is warming.