Managing Mailboxes with the API

How to create, fetch, update, delete, and restore mailboxes programmatically with the WarmySender REST API — including how a deleted mailbox keeps its warmup history and comes back when you re-add the same email.

Overview

WarmySender is a 4-pillar outreach platform — Cold Emailing, Email Warmup, LinkedIn Outreach, and Multichannel sequences. The public API lets you manage the email mailboxes behind cold emailing and warmup directly from your own systems: provision them, keep their credentials current, retire them, and bring them back.

This page walks through the full mailbox lifecycle endpoint by endpoint, then covers the two behaviors developers ask about most: the async connection check that runs after you create a mailbox, and soft delete plus restore — deleting a mailbox preserves its warmup history, and re-adding the same email address brings the existing mailbox back instead of erroring.

For the complete endpoint catalogue (warmup settings, jobs, webhooks, rate limits, error codes), see the full API reference. For how many mailboxes you can attach on each plan, see Mailbox limits per plan.

Base URL and authentication

All requests go to:

https://warmysender.com/api/v1

Authenticate every request with a Bearer token in the Authorization header. Your API key starts with wsk_ and is created in your workspace settings:

Authorization: Bearer wsk_your_api_key_here

Creating a mailbox is a write that must be safe to retry, so the create endpoint requires an Idempotency-Key header — a unique value you choose per logical create (a UUID works well). If a network blip makes you retry with the same key, you get the original result back instead of a duplicate mailbox.

Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

Create a mailbox

POST /api/v1/mailboxes

Send the SMTP and IMAP credentials for the mailbox you want to connect. external_id (your own reference for the mailbox) and auto_enable_warmup are optional.

curl -X POST https://warmysender.com/api/v1/mailboxes \
  -H "Authorization: Bearer wsk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{
    "email_address": "[email protected]",
    "smtp_host": "smtp.yourcompany.com",
    "smtp_port": 587,
    "smtp_username": "[email protected]",
    "smtp_password": "your-smtp-password",
    "imap_host": "imap.yourcompany.com",
    "imap_port": 993,
    "imap_username": "[email protected]",
    "imap_password": "your-imap-password",
    "external_id": "crm-mailbox-42",
    "auto_enable_warmup": true
  }'

Creating a mailbox does not test the connection inline. Instead it returns immediately and kicks off an async connection check in the background. The mailbox's status moves through:

  1. created — the row exists; the connection check is queued.
  2. testing — we are checking that the SMTP and IMAP credentials work.
  3. connected — the check passed; the mailbox is ready to send and (if you set auto_enable_warmup) warm up.
  4. error — the check failed; last_test_error explains why so you can fix the credentials and update the mailbox.

A successful create returns 201 Created with the new mailbox. (If the email matches a previously deleted mailbox, the same call restores it instead and returns 200 OK — see Re-adding a deleted email.) A sample response:

{
  "data": {
    "id": "mbx_a1b2c3d4",
    "external_id": "crm-mailbox-42",
    "email_address": "[email protected]",
    "status": "created",
    "warmup_enabled": false,
    "sending_enabled": true,
    "daily_send_limit": 50,
    "created_at": "2026-06-08T10:00:00.000Z",
    "updated_at": "2026-06-08T10:00:00.000Z"
  },
  "meta": {
    "request_id": "req_9f8e7d",
    "idempotency_key": "550e8400-e29b-41d4-a716-446655440000"
  }
}

Because the check is asynchronous, poll the mailbox (see below) until status is connected before you rely on it for sending. Warmup always starts disabled on a brand-new mailbox and only turns on once the connection is confirmed.

Fetch a mailbox

GET /api/v1/mailboxes/:id

Retrieve a single mailbox by its id. This is how you poll the async connection check after a create or restore — keep fetching until status is connected (or error).

curl https://warmysender.com/api/v1/mailboxes/mbx_a1b2c3d4 \
  -H "Authorization: Bearer wsk_your_api_key_here"

If the mailbox does not exist in your workspace, you get 404 Not Found.

List mailboxes

GET /api/v1/mailboxes

List the mailboxes in your workspace. Results are paginated with a cursor (next_cursor in the response when there are more). You can filter by status, by external_id, by email_address, and by warmup_enabled.

The status filter accepts created, testing, connected, error, and deleted. By default deleted mailboxes are excluded — pass status=deleted to list them (handy for finding a mailbox to restore):

# Active mailboxes that are fully connected
curl "https://warmysender.com/api/v1/mailboxes?status=connected" \
  -H "Authorization: Bearer wsk_your_api_key_here"

# Previously deleted mailboxes (candidates for restore)
curl "https://warmysender.com/api/v1/mailboxes?status=deleted" \
  -H "Authorization: Bearer wsk_your_api_key_here"

Update a mailbox

PATCH /api/v1/mailboxes/:id

Update an existing mailbox — send only the fields you want to change. The most common use is rotating credentials when a provider password changes, or adjusting daily_send_limit, sending_enabled, display_name, or external_id.

curl -X PATCH https://warmysender.com/api/v1/mailboxes/mbx_a1b2c3d4 \
  -H "Authorization: Bearer wsk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "smtp_password": "new-smtp-password",
    "imap_password": "new-imap-password",
    "daily_send_limit": 80
  }'

Updating a mailbox that does not exist returns 404 Not Found.

Delete a mailbox

DELETE /api/v1/mailboxes/:id

Deleting a mailbox is a soft delete: the mailbox immediately stops sending and warming up and is hidden from your default mailbox list, but its history is preserved behind the scenes. Nothing is permanently erased, which is what makes restore possible.

curl -X DELETE https://warmysender.com/api/v1/mailboxes/mbx_a1b2c3d4 \
  -H "Authorization: Bearer wsk_your_api_key_here"

The response echoes the mailbox with status now deleted. Deleting a mailbox that does not exist (or is already deleted) returns 404 Not Found.

Restore a deleted mailbox

POST /api/v1/mailboxes/:id/restore

Bring a deleted mailbox back. Restore re-runs the same async connection check a fresh create would, so the mailbox returns to connected on its own — and it keeps its warmup history, so it picks up where it left off rather than starting the ramp over.

curl -X POST https://warmysender.com/api/v1/mailboxes/mbx_a1b2c3d4/restore \
  -H "Authorization: Bearer wsk_your_api_key_here"

The mailbox comes back with status created and then progresses created → testing → connected as the check runs. A sample response:

{
  "data": {
    "id": "mbx_a1b2c3d4",
    "external_id": "crm-mailbox-42",
    "email_address": "[email protected]",
    "status": "created",
    "warmup_enabled": false,
    "sending_enabled": true,
    "daily_send_limit": 50,
    "created_at": "2026-06-08T10:00:00.000Z",
    "updated_at": "2026-06-08T12:30:00.000Z"
  },
  "meta": {
    "request_id": "req_4c5d6e"
  }
}

Restore returns 404 Not Found if there is no deleted mailbox with that id in your workspace, 409 Conflict if an active mailbox already uses the same email address (you cannot have two active mailboxes on one address), and 403 Forbidden if bringing the mailbox back would exceed your plan's mailbox limit (a restored mailbox counts toward your limit just like a new one — the response includes upgrade details). Poll the mailbox until status is connected to know it is ready.

Re-adding a deleted email restores it

You do not have to remember a deleted mailbox's id to bring it back. If you call create again with the same email_address — and no active mailbox is currently using that address — WarmySender restores the most recently deleted mailbox for that email instead of erroring.

This means an email address is never "stuck" after deletion. Re-adding it through your normal create flow reactivates the existing mailbox with the credentials you send, re-runs the async connection check, and keeps the warmup history. When create restores an existing mailbox this way, it returns 200 OK (rather than the 201 Created you get for a genuinely new mailbox), so you can tell the two apart.

If an active mailbox already uses that email address, create returns 409 Conflict — you cannot connect the same address twice while one is live. Delete or update the existing one first.

Mailbox status reference

created
The mailbox row exists and its connection check is queued. A brand-new create and a just-restored mailbox both start here.
testing
The connection check is running — we are verifying the SMTP and IMAP credentials.
connected
The check passed. The mailbox can send and, if warmup is enabled, warm up. This is the status to wait for after a create or restore.
error
The connection check failed. Read last_test_error for the reason, fix the credentials with a PATCH, and the check re-runs.
deleted
The mailbox was soft-deleted. It is hidden from the default list, no longer sends or warms up, and its history is preserved so it can be restored.

Frequently asked questions

I deleted a mailbox — is the data gone?

No. Delete is a soft delete: the mailbox stops sending and warming up and disappears from your default list, but its history is preserved behind the scenes. Restoring the mailbox (by id via the restore endpoint, or by re-creating with the same email) brings it back with its warmup history intact, so it resumes where it left off instead of starting the ramp over.

Can I reuse an email after deleting it?

Yes. As long as no active mailbox currently uses that address, you can reactivate it two ways: call POST /api/v1/mailboxes/:id/restore with the deleted mailbox's id, or simply call create again with the same email_address — that restores the most recently deleted mailbox for the address rather than erroring. Either way the email is never stuck after deletion.

How do I know when a restored mailbox is ready?

Restore (and create) kick off an async connection check, so the mailbox comes back as created and then moves to testing and connected on its own. Poll GET /api/v1/mailboxes/:id until status is connected (or error, which means the credentials need fixing). There is nothing else to trigger — the check runs automatically.

Why does create need an Idempotency-Key?

Create is a write that should be safe to retry. The Idempotency-Key header lets you retry the same logical create after a network blip without risking a duplicate mailbox — repeat the request with the same key and you get the original result back. Use a unique value (a UUID works well) per mailbox you create.

What happens if I create a mailbox for an email that's already connected?

If an active mailbox already uses that email_address, create returns 409 Conflict — you cannot connect the same address twice while one is live. If the only mailbox on that address was previously deleted, create restores it instead and returns 200 OK.

Building an integration and stuck on something here? Email [email protected] with the request you are sending and the response you got back, and we will help you wire it up.