Skip to content

API reference/email

List the account's domain monitors

GET/api/v1/email/domain-monitors

authentication
Secret API key as a bearer token
billing
Free.

The saved domain lists this account re-checks on a schedule, newest first, 100 per page. Each monitor carries the summary of its last run: how many domains were ok, flagged (parked, mail hosts on a threat blocklist, a registration ending within 30 days, no SPF, no DMARC, or a provider, SPF, DMARC, DKIM or MTA-STS change since the previous run), dead (no usable mail servers) or invalid (not a hostname), how many changed, how many newly need attention, the credits the run spent, and stopped_reason when it did not finish cleanly: insufficient_credits or key_spend_cap where the run stopped part-way, run_failed where it died outright, and run_failed_retrying where it died and the schedule has been pulled in to check again — retry_at in the same block says when that becomes due, and the hourly sweep picks it up at or after that, so between 45 minutes and about an hour and three quarters later. A summary carrying a stopped_reason of either failure kind has NO counts in it at all: the run produced none, so read a missing count as unknown rather than as zero. The domains and their answers are on the single-monitor endpoint.

Parameters

name in type description
pagequeryintegerThe page to return. Default: 1.

Example request

curl https://spaw.co/api/v1/email/domain-monitors \
  -H "Authorization: Bearer sk_live_…"
const response = await fetch('https://spaw.co/api/v1/email/domain-monitors', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer sk_live_…',
  },
});
const result = await response.json();
import requests

response = requests.get(
    'https://spaw.co/api/v1/email/domain-monitors',
    headers={'Authorization': 'Bearer sk_live_…'},
)
result = response.json()
$ch = curl_init('https://spaw.co/api/v1/email/domain-monitors');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer sk_live_…'],
]);
$result = json_decode(curl_exec($ch), true);
from spaw import Client

client = Client('sk_live_…')
result = client.list_domain_monitors()
import Spaw from 'spaw';

const spaw = new Spaw({ apiKey: 'sk_live_…' });
const result = await spaw.listDomainMonitors();
use Spaw\Client;

$spaw = new Client('sk_live_…');
$result = $spaw->listDomainMonitors();

This endpoint has no console on its page. It answers with records from your own account, often by an id only you have, rather than about a value you can type here. The dashboard lists the same rows.

Responses

200One page of monitors.

{
    "success": true,
    "data": {
        "monitors": [
            {
                "id": 4,
                "name": "Sending domains",
                "cadence": "daily",
                "domain_count": 2,
                "next_run_at": "2026-09-14T08:00:00+00:00",
                "last_run_at": "2026-09-13T08:00:03+00:00",
                "last_summary": {
                    "total": 2,
                    "ok": 1,
                    "flagged": 1,
                    "dead": 0,
                    "invalid": 0,
                    "changed": 1,
                    "newly_flagged": 1,
                    "credits_used": 0,
                    "stopped_reason": null
                },
                "webhook_url": null,
                "webhook_events": "changes",
                "webhook_status": null,
                "webhook_detail": null,
                "prunes_after_days": 365,
                "created_at": "2026-09-01T08:00:00+00:00"
            }
        ]
    },
    "meta": {
        "page": 1,
        "per_page": 100,
        "total": 1,
        "retention_days": 365
    }
}

401The key is missing, malformed, or revoked.

{
    "success": false,
    "error": {
        "code": "UNAUTHENTICATED",
        "message": "Provide a valid API key as a bearer token.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}

429Over 5 requests per second for the key. Retry after the limit resets.

{
    "success": false,
    "error": {
        "code": "RATE_LIMITED",
        "message": "Too many requests. Retry after the limit resets.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}

Error codes

Failures answer { success: false, error: { code, message, request_id } }. Each code has its own page.

markdown version·openapi.json