Unspam

API

The Unspam platform can be accessed via API. API access is available exclusively on specific subscription plans. Please ensure your current plan supports API usage before integrating.

Base URL

All API requests should be made to: https://api.unspam.email/ext/v2

Authentication

All requests require a Bearer token. You can find your API token on the Subscription page under API Token. Include it in every request as a header:

Authorization: Bearer YOUR_API_TOKEN

API Reference

Browse the interactive API documentation (Swagger UI) for detailed endpoint descriptions, request/response schemas, and the ability to try endpoints directly.

Postman Collection

Import the Postman collection to get started quickly with all available endpoints.

MCP Server

Prefer to drive Unspam from an AI assistant? The same functionality is available through our MCP server for Claude, ChatGPT, Cursor, and other MCP-compatible clients.

Flows

Inbox Placement Test

  1. Optionally, fetch the list of available mailboxes via the Available Mailboxes endpoint to select specific ones for your test.
  2. Start a new test via the Start New Test endpoint. You can pass specific mailbox IDs from the previous step, or omit the parameter to use all available mailboxes. The response contains the test ID and the list of mailboxes used.
  3. Send your email to the mailbox addresses. Include the test ID in the email body.
  4. Wait a few minutes for the system to process the results.
  5. Check the result via the Test Result endpoint using the ID from step 1.

Examples

1. See which mailboxes are available

Fetch the enabled mailboxes you can run a test against. Use the returned id values to target specific mailboxes when starting a test.

curl https://api.unspam.email/ext/v2/inbox-placement/mailboxes \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
[
  { "id": 3, "name": "Mailbox 1", "address": "mailbox1@example.com" },
  { "id": 7, "name": "Mailbox 2", "address": "mailbox2@example.com" }
]
2. Run a test and get results

Step 1. Start a new test. Pass specific mailboxes IDs, or omit the field to use all available mailboxes. The response returns the test id and the mailboxes to send to.

curl -X POST https://api.unspam.email/ext/v2/inbox-placement \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mailboxes": [3, 7]
  }'
{
  "id": "abc123",
  "mailboxes": [
    { "id": 3, "name": "Mailbox 1", "address": "mailbox1@example.com" },
    { "id": 7, "name": "Mailbox 2", "address": "mailbox2@example.com" }
  ]
}

Step 2. Send your email to each mailbox address, including the test id in the email body.

# Send your email to the mailbox addresses above.
# Include the test id ("abc123") somewhere in the email body.
# Wait a few minutes for delivery to be processed.

Step 3. Fetch the result with the test id — it shows the per-mailbox placement.

curl https://api.unspam.email/ext/v2/inbox-placement/abc123 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "id": "abc123",
  "status": "completed",
  "started_at": "2026-05-12T10:21:00Z",
  "completed_at": "2026-05-12T10:24:00Z",
  "results": [
    {
      "mailbox": { "id": 3, "name": "Mailbox 1", "address": "mailbox1@example.com" },
      "status": "inbox",
      "tab": "primary",
      "sender": "news@yourdomain.com",
      "sender_ip": "203.0.113.10",
      "blacklists": 0
    }
  ],
  "report_url": "https://app.unspam.email/inbox-test/abc123",
  "client_preview_id": null
}

The response includes client_preview_id — the id of this test's client preview (email-client renderings), or null if none has been created yet. Pass it to GET /client-previews/{id} to fetch the preview (see the Client Previews flow below).

Spam Check Test

  1. Start a new test via the Start New Test endpoint. The response contains the inbox_address property.
  2. Send your email to the inbox_address.
  3. Wait a few minutes for the system to analyze the email.
  4. Check the results via the Test Result endpoint using the ID from step 1.

Examples

1. Run a spam check

Step 1. Start a new test. The response returns the test id and the inbox_address to send your email to.

curl -X POST https://api.unspam.email/ext/v2/spam-check \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "id": "abc123",
  "inbox_address": "spam-check-abc123@inbox.unspam.email"
}

Step 2. Send the email you want to analyze to the returned inbox_address.

# Send your email to the inbox_address above.
# Wait a few minutes for the system to analyze it.

Step 3. Fetch the result with the test id — it includes the spam score and per-check details.

curl https://api.unspam.email/ext/v2/spam-check/abc123 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "id": "abc123",
  "status": "completed",
  "created_at": "2026-05-12T10:21:00Z",
  "completed_at": "2026-05-12T10:23:00Z",
  "sender": "news@yourdomain.com",
  "score": 9.2,
  "results": [
    {
      "id": "spf",
      "name": "SPF",
      "test_info": "...",
      "value": [ { "id": "spf_pass", "name": "Pass", "status": "ok" } ],
      "meta": null
    }
  ],
  "report_url": "https://app.unspam.email/spam-check/abc123",
  "client_preview_id": null
}

You can also fetch the email Screenshots (/spam-check/{id}/screenshots) and the Heatmap (/spam-check/{id}/heatmap) once the test is completed. To render the email across many email clients/devices, use the universal Client Previews resource (/client-previews) — see the Client Previews flow below.

The response also includes client_preview_id — the id of this test's client preview (email-client renderings), or null if none has been created yet. Pass it to GET /client-previews/{id} to fetch the preview.

Client Previews

Client Previews render an email across real email clients/devices (iOS Mail, Gmail, Outlook, etc.). Create a preview with POST /client-previews, then poll it until every device is rendered. Rendering is asynchronous: devices come back pending, so poll GET /client-previews/{id} until each device is completed (or failed).

  1. Optionally, list the available clients (device device_key + name) via the Available Devices endpoint (GET /client-preview-devices) to render only specific ones.
  2. Create a preview via POST /client-previews. Set email_source to one of spam-check, inbox-placement, raw-data or email (see the four variants below). Optionally pass devices (an array of device_keys) — omit it to render all available devices.
  3. The response returns the preview id, its status, an inbox_address (only for the email source), and the per-device previews array.
  4. Poll GET /client-previews/{id} until status is completed. Each device then exposes its original image, thumbnail, and download URL.

The request body accepts:

The list endpoint (GET /client-previews, paginated, per_page defaults to 15) only returns previews whose email_source is raw-data or email and whose status is pending or completed. Previews created from a spam-check or inbox-placement are reached instead via that source's client_preview_id field.

Examples

1. See which devices are available

Fetch the clients you can render against. Use the returned device_key values to target specific devices via the devices field when creating a preview.

curl https://api.unspam.email/ext/v2/client-preview-devices \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
[
  { "device_key": "ios_mail", "name": "iOS Mail" },
  { "device_key": "gmail_web", "name": "Gmail (Web)" },
  { "device_key": "outlook_chrome", "name": "Outlook (Chrome)" }
]
2. Create a preview from a spam check

Pass the spam check's result id as source_id; the subject and body are pulled from that source. Omit devices to render all available devices.

curl -X POST https://api.unspam.email/ext/v2/client-previews \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_source": "spam-check",
    "source_id": "abc123"
  }'
{
  "id": "def456",
  "email_source": "spam-check",
  "status": "pending",
  "inbox_address": null,
  "previews": [
    {
      "device_key": "ios_mail",
      "device_name": "iOS Mail",
      "status": "pending",
      "original": null,
      "thumbnail": null,
      "download": null
    }
  ]
}
3. Create a preview from an inbox placement test

Same as the spam-check variant, but reference an inbox placement test's result id as source_id.

curl -X POST https://api.unspam.email/ext/v2/client-previews \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_source": "inbox-placement",
    "source_id": "abc123"
  }'
{
  "id": "def456",
  "email_source": "inbox-placement",
  "status": "pending",
  "inbox_address": null,
  "previews": [
    {
      "device_key": "ios_mail",
      "device_name": "iOS Mail",
      "status": "pending",
      "original": null,
      "thumbnail": null,
      "download": null
    }
  ]
}
4. Create a preview from raw data

Supply your own subject and HTML body instead of a source_id. Here we render only two specific devices.

curl -X POST https://api.unspam.email/ext/v2/client-previews \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_source": "raw-data",
    "subject": "Welcome!",
    "body": "<html><body>Hello</body></html>",
    "devices": ["ios_mail", "gmail_web"]
  }'
{
  "id": "def456",
  "email_source": "raw-data",
  "status": "pending",
  "inbox_address": null,
  "previews": [
    {
      "device_key": "ios_mail",
      "device_name": "iOS Mail",
      "status": "pending",
      "original": null,
      "thumbnail": null,
      "download": null
    },
    {
      "device_key": "gmail_web",
      "device_name": "Gmail (Web)",
      "status": "pending",
      "original": null,
      "thumbnail": null,
      "download": null
    }
  ]
}
5. Create a preview by submitting an email

Create a preview with email_source: "email" and no other fields. The response is a draft preview containing an inbox_address. Send the email you want to render to that address — the received message becomes the content, and rendering then proceeds like the other sources.

Step 1. Create the draft preview and read the returned inbox_address.

curl -X POST https://api.unspam.email/ext/v2/client-previews \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_source": "email"
  }'
{
  "id": "def456",
  "email_source": "email",
  "status": "draft",
  "inbox_address": "abc123@preview.unspam.email",
  "previews": [
    {
      "device_key": "ios_mail",
      "device_name": "iOS Mail",
      "status": "pending",
      "original": null,
      "thumbnail": null,
      "download": null
    }
  ]
}

Step 2. Send the email you want to render to the returned inbox_address.

# Send your email (from your mail client / ESP) to the inbox_address above.
# The received message becomes the content that gets rendered.
# Wait a few moments for it to be received before continuing.

Step 3. Poll the preview until status moves from draft to completed (see below).

6. Poll a preview until it is rendered

Fetch the preview with its id until status is completed (values: draft, pending, completed, failed; draft applies only to the email source before its message arrives). Each device's original, thumbnail and download are null until that device finishes rendering.

curl https://api.unspam.email/ext/v2/client-previews/def456 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "id": "def456",
  "email_source": "raw-data",
  "status": "completed",
  "inbox_address": null,
  "previews": [
    {
      "device_key": "ios_mail",
      "device_name": "iOS Mail",
      "status": "completed",
      "original": "https://api.unspam.email/storage/client_previews/2026/07/3f/3f9a2c8e1d4b.jpg",
      "thumbnail": "https://api.unspam.email/storage/client_previews/2026/07/7b/7b1e5da0c62f.jpg",
      "download": "https://api.unspam.email/ext/v2/client-previews/def456/devices/ios_mail/download"
    },
    {
      "device_key": "gmail_web",
      "device_name": "Gmail (Web)",
      "status": "pending",
      "original": null,
      "thumbnail": null,
      "download": null
    }
  ]
}

Automatic Testing

Automatic testing lets you configure a test once and have it run on a recurring schedule (or on demand). Each run submits your email through your own SMTP server to the selected mailboxes and reports inbox placement. Configure the test once, then it runs automatically based on its schedule — or trigger an immediate run with Dispatch Now.

  1. Create a Sender via the senders Create endpoint with your SMTP credentials (from_name, from_email and the smtp host/port/protocol/username/password). The response returns the sender id.
  2. Optionally verify the credentials with the sender Test Connection endpoint before using it.
  3. Create a draft test via the test Create draft test endpoint. The response returns the test id and an inbox_address.
  4. Send the email you want to test to the returned inbox_address. This captures the email template that every run will deliver. Wait a few moments for it to be received before continuing. (Alternatively, set the template directly from content with the Set Email endpoint — see the example below.)
  5. Configure the test via the Configure test (PUT) endpoint: set name, the sender_uuid from step 1, the providers (mailbox IDs from Available Mailboxes), the schedule (start_at, type, and days for specific_days), and the alert_settings.
  6. Set status to active if you want the test to run automatically on its schedule. Keep it disabled if you only intend to trigger runs manually. While active, the next run is generated automatically from the schedule.
  7. To trigger a run immediately, call Dispatch Now. This works regardless of status — both active and disabled tests can be dispatched manually, as long as they have a schedule and a sender. It returns a run_id with status in_queue.
  8. List a test's runs via Runs Index (defaults to the last month; the date range must not exceed 6 months), and fetch a single run's detailed inbox-placement result via Run Results using the run_id.
  9. Use the test Update Status (PATCH) endpoint to enable or disable a configured test at any time.

Examples

1. Create a new sender

Register the SMTP credentials used to deliver the test. The response returns the sender id — keep it for the test configuration step.

curl -X POST https://api.unspam.email/ext/v2/scheduled-test-senders \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Sender",
    "service": "smtp",
    "settings": {
      "from_name": "Admin",
      "from_email": "admin@no-reply.com",
      "smtp": {
        "host": "smtp.example.com",
        "port": 465,
        "protocol": "SSL",
        "username": "user@example.com",
        "password": "password"
      },
      "headers": {}
    }
  }'

Response:

{
  "id": "2ded86a5-b2d9-4f29-921f-1aca66350209",
  "name": "My Sender",
  "service": "smtp",
  "settings": { "...": "..." },
  "error_code": null
}

Optionally verify the credentials with the sender's id. No request body is needed — it tests the stored settings.

curl -X POST https://api.unspam.email/ext/v2/scheduled-test-senders/2ded86a5-b2d9-4f29-921f-1aca66350209/test-connection \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

On success it returns { "status": "ok" }; on failure it returns 422 with { "status": "error", "message": "..." }.

2. Create an automatic test

Create a draft test, send the email you want to test to the returned address, then configure the schedule and activate it.

Step 1. Create a draft test. The response returns the test id and the inbox_address.

curl -X POST https://api.unspam.email/ext/v2/scheduled-tests \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "id": "9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321",
  "status": "draft",
  "inbox_address": "test-9b1c7e84@inbox.unspam.email"
}

Step 2. Send the email you want to test to the returned inbox_address.

# Send your email (from your mail client / ESP) to the inbox_address above.
# This captures the template every run will deliver.
# Wait a few moments for it to be received before continuing.

Step 3. Poll the test with a GET request to check whether the email has arrived. While the test is still in draft and email_subject / email_from are null, the email has not been received yet. Once it is received, those fields are populated — you can then configure the schedule and activate the test.

curl https://api.unspam.email/ext/v2/scheduled-tests/9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "id": "9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321",
  "status": "draft",
  "email_subject": "Welcome to our newsletter",
  "email_from": "news@yourdomain.com",
  "...": "..."
}

Step 4. Configure the test and set status to active so it runs on schedule. Use the sender id from the previous example as sender_uuid and mailbox IDs from Available Mailboxes as providers.

curl -X PUT https://api.unspam.email/ext/v2/scheduled-tests/9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My automatic test",
    "status": "active",
    "sender_uuid": "2ded86a5-b2d9-4f29-921f-1aca66350209",
    "providers": [3, 7, 23],
    "schedule": {
      "start_at": "2026-06-18T10:21:00Z",
      "type": "week",
      "days": []
    },
    "alert_settings": {
      "mode": "all",
      "spam_level": null
    }
  }'
Set the email content directly (alternative to sending one)

Instead of sending an email to the draft's inbox_address and waiting for it to be received, you can set the email template directly with the Set Email endpoint. This builds the email that every run will deliver from the content you provide. Transport and authentication headers (Received, DKIM, SPF/DMARC) are still applied by your sender's SMTP at send time.

Provide subject and html (and optionally text). from is optional — it defaults to the attached sender's from_email, then the test's existing from address. Optional headers let you add content headers such as List-Unsubscribe or Reply-To to better match production mail (structural headers managed by the builder are ignored).

curl -X PUT https://api.unspam.email/ext/v2/scheduled-tests/9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321/email \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Welcome to our newsletter",
    "from": "news@yourdomain.com",
    "html": "<h1>Hello!</h1><p>Thanks for subscribing.</p>",
    "text": "Hello! Thanks for subscribing.",
    "headers": {
      "Reply-To": "support@yourdomain.com",
      "List-Unsubscribe": "<https://yourdomain.com/unsubscribe?id=123>",
      "List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
    }
  }'

On success the test is returned with its content populated and status set to disabled, ready to be configured and activated. After this you do not need to send an email to the inbox address.

3. Run a test on demand

The same setup as a scheduled test, but instead of waiting for the schedule you trigger each run manually with Dispatch Now. The test can stay disabled — manual dispatch works regardless of status, as long as the test has a schedule and a sender.

Step 1. Create a draft test (returns id and inbox_address).

curl -X POST https://api.unspam.email/ext/v2/scheduled-tests \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

Step 2. Send the email you want to test to the returned inbox_address, and poll the test with a GET request until email_subject / email_from are populated (see the previous example).

Step 3. Configure the test. You can leave status as disabled since you will dispatch runs manually; a schedule and a sender_uuid are still required.

curl -X PUT https://api.unspam.email/ext/v2/scheduled-tests/9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My on-demand test",
    "status": "disabled",
    "sender_uuid": "2ded86a5-b2d9-4f29-921f-1aca66350209",
    "providers": [3, 7, 23],
    "schedule": {
      "start_at": "2026-06-18T10:21:00Z",
      "type": "week",
      "days": []
    },
    "alert_settings": {
      "mode": "all",
      "spam_level": null
    }
  }'

Step 4. Trigger a run whenever you need it. The response returns a run_id with status in_queue.

curl -X POST https://api.unspam.email/ext/v2/scheduled-tests/9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321/dispatch-now \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "status": "in_queue",
  "run_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

Step 5. Fetch the run result with the run_id once it completes.

curl https://api.unspam.email/ext/v2/scheduled-tests/9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321/runs/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
4. List a test's runs

Fetch the paginated history of runs for a test. Without a date range it defaults to the last month; you can filter with from / to (the range must not exceed 6 months) and page with page / per_page. Use a run's id to fetch its detailed result (see the previous example).

curl "https://api.unspam.email/ext/v2/scheduled-tests/9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321/runs?from=2026-05-01&to=2026-05-31&page=1" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "data": [
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "status": "completed",
      "inbox_rate": 0.85,
      "tabs_rate": 0.1,
      "spam_rate": 0.05,
      "missing_rate": 0,
      "scheduled_at": "2026-05-12T10:21:00Z",
      "inbox_placements": []
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 10,
  "total": 1
}
5. Fetch a run's results

Fetch the detailed result of a single run using its id (from Dispatch Now or the runs list). It includes the overall rates and the per-mailbox inbox placement.

curl https://api.unspam.email/ext/v2/scheduled-tests/9b1c7e84-2f3a-4d6b-8c11-7a5e0d9f4321/runs/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "status": "completed",
  "inbox_placement_url": "https://app.unspam.email/inbox-test/abc123",
  "inbox_rate": 0.85,
  "tabs_rate": 0.1,
  "spam_rate": 0.05,
  "missing_rate": 0,
  "scheduled_at": "2026-05-12T10:21:00Z",
  "inbox_placements": [
    {
      "service": "<provider>",
      "status": "completed",
      "placement": "inbox",
      "provider_account": {
        "id": 3,
        "name": "Mailbox 1",
        "is_business_account": false
      }
    }
  ]
}

Rate Limits

All public API endpoints are rate-limited to 100 requests per minute per IP address. Authenticated requests are rate-limited per user account instead. Exceeding the limit will result in a 429 Too Many Requests response.