Skip to main content
The API uses conventional HTTP response codes. Error bodies come in three shapes depending on which layer rejects the request.

Error response shapes

Standard errors (validation failures, missing resources, state conflicts, server errors) return a flat body with a machine-readable code and a correlationId you can quote to support. Some codes also include a details object (for example, field-level validation errors):
Authentication and permission errors from the API-key layer (401, and 403 when the key lacks a scope) use a simpler two-field body with no code:
Rate-limit errors (429) include retryAfter in the body and a Retry-After header:

HTTP status codes

Common error codes

Email error codes (early access)

The /v1/email/* surface is in early access. Every endpoint under it returns 403 EMAIL_EARLY_ACCESS until the product reaches general availability, so that is the only code an integration will see today. The rest are the codes those endpoints throw once the surface is open. DMARC_ROOT_DOMAIN_NOT_MANAGED is never resolved by retrying. Surface it to a human. Note that 401 responses and permission-scope 403 responses come from the authentication layer and carry no code field (see the shapes above).

Retrying safely

  • All GET endpoints are safe to retry - they have no side effects.
  • For POST and PATCH, retry only on 429, 500, 502, 503, and 504 responses. Don’t retry on 400, 401, 403, or 404 - those indicate a problem with your request that won’t be fixed by trying again.
  • If you need stronger duplicate-write protection, send a unique Idempotency-Key header (16-200 printable ASCII characters; a UUID is recommended) on every write request. Retried calls with the same key within 24 hours return the cached response from the first call, marked with an X-Idempotent-Replayed: true response header. Reusing a key with a different body returns 422 (IDEMPOTENCY_MISMATCH).

How agents should recover

Unattended integrations and AI agents should encode this recovery matrix rather than treating all failures alike: Before treating repeated 5xx failures as your bug, check status.politicalcomms.com. A standalone machine-readable version of this playbook is published at politicalcomms.com/errors.md.

Reporting bugs

If you see a 500 response or a code that’s not documented here, please email support@politicalcomms.com with:
  • Your request method and path
  • The full response body, including the correlationId field (we use it to look up server-side logs; it is also sent as the X-Correlation-ID response header)
  • Approximate timestamp (UTC is easiest)