Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/politicalcomms-com:politicalcomms-com-sending-domains-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Political Comms Sending Domains API
summary: Direct-to-carrier political texting API for campaigns, PACs, advocacy organizations, fundraisers, and elected officials.
description: 'Public REST API for the Political Comms platform. Surfaces include Projects (compose, test, schedule, send), Conversations (read inbound threads and reply inside them), Contact Lists (S3 import and analysis), Media Files, Organizations and hierarchy, Brands, Campaigns, Tracking Domains, Phone Numbers, Analytics, and Billing.
Authentication is an API key passed in the `X-API-Key` header. Keys are generated from the dashboard at Admin → API and are prefixed `pc_live_`. All POST and PATCH endpoints that mutate state are designed to be safe to retry, with optional `Idempotency-Key` headers for stronger guarantees. Rate limit is 600 requests per minute per key (bursts up to 600, refilling at 10 per second, the same for every scope; the `X-RateLimit-Limit` header reports your key''s exact limit, and `Retry-After` on a 429 is the seconds until your next request is allowed).
Webhooks emit `message.sent`, `message.delivered`, `message.failed`, `message.replied`, and `link.clicked` events. Payloads are HMAC-signed; validate the signature before trusting any payload.
A Model Context Protocol (MCP) server is available at https://docs.politicalcomms.com/mcp for AI agents that need to search the documentation programmatically. The developer hub at https://politicalcomms.com/developers/ has quickstart examples in cURL, raw HTTP, and Python.'
version: 1.4.1
termsOfService: https://politicalcomms.com/terms/
contact:
name: Political Comms Support
email: support@politicalcomms.com
url: https://docs.politicalcomms.com
license:
name: Proprietary
url: https://politicalcomms.com/terms/
x-logo:
url: https://politicalcomms.com/images/brand/pcomms-logo-left-of-text.png
altText: Political Comms
backgroundColor: '#ffffff'
href: https://politicalcomms.com/
x-mcp:
url: https://docs.politicalcomms.com/mcp
discovery_url: https://docs.politicalcomms.com/.well-known/mcp
transport: http
auth: none
tools:
- search_political_comms
- query_docs_filesystem_political_comms
- submit_feedback
servers:
- url: https://api.politicalcomms.com/v1
description: Production
security:
- ApiKeyAuth: []
tags:
- name: Sending Domains
description: 'Read the sending domains in your organization and the DNS records to publish. Domains are added in the dashboard: DNS is published by hand, so creation is not part of the API.'
paths:
/email/domains:
get:
tags:
- Sending Domains
summary: List Sending Domains
description: List the organization's email sending domains, newest first.
operationId: listEmailDomains
parameters:
- $ref: '#/components/parameters/EmailLimit'
- $ref: '#/components/parameters/EmailCursor'
- $ref: '#/components/parameters/EmailSearch'
responses:
'200':
description: A page of sending domains.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/EmailDomain'
has_more:
type: boolean
next_cursor:
type:
- string
- 'null'
required:
- data
- has_more
- next_cursor
additionalProperties: true
required:
- success
- data
additionalProperties: true
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/InternalError'
/email/domains/{id}:
get:
tags:
- Sending Domains
summary: Get Sending Domain
description: Fetch one sending domain, including the DNS records to publish and the per-signal verification state.
operationId: getEmailDomain
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The sending domain.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
$ref: '#/components/schemas/EmailDomain'
required:
- success
- data
additionalProperties: true
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/InternalError'
components:
responses:
Forbidden:
description: The API key lacks the required permission scope, or the requested resource belongs to an organization outside the key's hierarchy.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/AuthErrorResponse'
- $ref: '#/components/schemas/ErrorResponse'
examples:
missingScope:
summary: Key lacks the required permission scope
value:
error: Insufficient permissions
message: 'This API key does not have the required permissions: public:read'
orgAccessDenied:
summary: Resource outside the key's organization hierarchy
value:
error: 'Access denied: You do not have permission to access this organization''s data'
code: ORG_ACCESS_DENIED
correlationId: de038205-7c9c-4d4a-99bc-d7275a52f07e
Unauthorized:
description: Missing, malformed, revoked, or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthErrorResponse'
example:
error: API key required
message: Please provide an API key in the X-API-Key header
InternalError:
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: An unexpected error occurred. Please try again later.
code: INTERNAL_ERROR
correlationId: de038205-7c9c-4d4a-99bc-d7275a52f07e
RateLimited:
description: Rate limit exceeded. Check the Retry-After header.
headers:
Retry-After:
description: Seconds until the window resets.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitErrorResponse'
example:
success: false
error: Rate limit exceeded
message: Maximum 600 requests per 60 seconds
code: RATE_LIMIT_EXCEEDED
statusCode: 429
retryAfter: 3
NotFound:
description: Resource not found or not visible to this API key.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: Project not found
code: PROJECT_NOT_FOUND
correlationId: de038205-7c9c-4d4a-99bc-d7275a52f07e
parameters:
IdPath:
name: id
in: path
required: true
description: Resource ID
schema:
type: string
EmailCursor:
name: cursor
in: query
required: false
description: Opaque cursor from the previous page's `next_cursor`.
schema:
type: string
maxLength: 4096
EmailSearch:
name: search
in: query
required: false
description: Case-insensitive substring match.
schema:
type: string
maxLength: 255
EmailLimit:
name: limit
in: query
required: false
description: Rows per page, 1-200.
schema:
type: integer
minimum: 1
maximum: 200
default: 50
schemas:
RateLimitErrorResponse:
type: object
properties:
success:
type: boolean
enum:
- false
error:
type: string
message:
type: string
code:
type: string
enum:
- RATE_LIMIT_EXCEEDED
statusCode:
type: integer
enum:
- 429
retryAfter:
type: integer
description: Seconds until the rate-limit window resets. Also sent as the Retry-After header.
required:
- success
- error
- code
- statusCode
- retryAfter
additionalProperties: true
DnsRecord:
type: object
properties:
type:
type: string
enum:
- CNAME
- TXT
- MX
name:
type: string
description: Host name to create, as published in your zone.
value:
type: string
description: Record value.
purpose:
type:
- string
- 'null'
description: 'What the record proves: `dkim`, `mail_from`, or `dmarc`.'
required:
- type
- name
- value
description: 'One DNS record to publish. We never write DNS on your behalf: you publish these in your own zone.'
additionalProperties: true
EmailDomain:
type: object
properties:
id:
type: string
format: uuid
domain:
type: string
example: mail.example.org
status:
type: string
enum:
- pending
- active
- failed
description: '`pending` until every record is observed, then `active`. `failed` means verification was abandoned; delete and re-add to retry.'
dns_records:
description: DNS records to publish. Besides the DKIM, bounce, and DMARC records, a new domain carries a per-organization domain verification TXT record (`key` `ownership_txt`, host `_sender-verification.<domain>`). Publish it even if the other records already show verified; the domain stays pending until it is seen. Domains added before this record existed, and the platform organization's own domain, do not have one.
type: array
items:
$ref: '#/components/schemas/DnsRecord'
verification:
type: object
properties:
dkim:
type:
- string
- 'null'
mail_from:
type:
- string
- 'null'
dmarc:
type:
- string
- 'null'
description: Per-signal verification state.
additionalProperties: true
error_message:
type:
- string
- 'null'
last_checked_at:
type:
- string
- 'null'
format: date-time
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
required:
- id
- domain
- status
additionalProperties: true
AuthErrorResponse:
type: object
properties:
error:
type: string
description: Short error summary.
message:
type: string
description: Human-readable detail.
required:
- error
- message
additionalProperties: true
description: Error body returned by the API-key authentication layer (401 and permission 403s).
ErrorResponse:
type: object
properties:
error:
type: string
description: Human-readable error message.
code:
type: string
description: Machine-readable error code, e.g. VALIDATION_ERROR, ORG_ACCESS_DENIED, PROJECT_NOT_FOUND.
correlationId:
type: string
description: Request correlation ID; include it in support requests.
details:
type:
- array
- object
description: Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).
required:
- error
- code
additionalProperties: true
description: Standard error body produced by the API error handler for 4xx/5xx responses.
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: Authenticate every request by passing your API key in the X-API-Key header. Keys are scoped to your organization hierarchy.