> ## Documentation Index
> Fetch the complete documentation index at: https://docs.politicalcomms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> Public REST API for integrating messaging data, project statistics, and billing into your stack.

The Political Comms API is a RESTful interface for integrating messaging data, project statistics, contact and media management, and billing into your application. It's the same API that powers our own dashboard, so anything you can do in the UI you can also do programmatically.

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/api-reference/authentication">
    Authenticate with an API key passed in the `X-API-Key` header.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/api-reference/webhooks/overview">
    Stream real-time events into your CRM, warehouse, or alerting stack.
  </Card>

  <Card title="Rate limits" icon="gauge-high" href="/api-reference/rate-limits">
    600 requests per minute per API key. Headers tell you where you stand.
  </Card>

  <Card title="Errors" icon="circle-exclamation" href="/api-reference/errors">
    Conventional HTTP status codes with structured error responses.
  </Card>
</CardGroup>

## Base URL

```
https://api.politicalcomms.com/v1
```

Custom domains are supported for white-labeled deployments. If your organization has a custom API domain configured, use that as the base URL - the API surface is identical.

## Quickstart

<Steps>
  <Step title="Get an API key">
    From the dashboard, go to **Admin → API → Create API Key**. Copy the key (it's only shown once) and store it in a secret manager - never in source control.
  </Step>

  <Step title="Make your first call">
    List your accessible organizations:

    <CodeGroup>
      ```bash curl theme={null}
      curl https://api.politicalcomms.com/v1/organizations \
        -H "X-API-Key: pc_live_1234567890abcdef"
      ```

      ```javascript Node.js theme={null}
      const response = await fetch(
        'https://api.politicalcomms.com/v1/organizations',
        { headers: { 'X-API-Key': process.env.POLCOMMS_API_KEY } }
      );
      const { data } = await response.json();
      ```

      ```python Python theme={null}
      import os, requests

      response = requests.get(
          'https://api.politicalcomms.com/v1/organizations',
          headers={'X-API-Key': os.environ['POLCOMMS_API_KEY']}
      )
      data = response.json()['data']
      ```
    </CodeGroup>
  </Step>

  <Step title="Subscribe to webhooks">
    Configure an HTTPS endpoint that receives [real-time events](/api-reference/webhooks/overview) for messages, replies, and link clicks. Always [validate the HMAC signature](/api-reference/webhooks/signature-validation) before trusting any payload.
  </Step>
</Steps>

## What you can do

<AccordionGroup>
  <Accordion title="Read your hierarchy" icon="sitemap">
    List organizations, brands, campaigns, phone numbers, and tracking domains across your full org tree. Filter by org / brand / campaign at every level.
  </Accordion>

  <Accordion title="Manage contacts and media" icon="address-book">
    Import contact lists from S3 presigned URLs, trigger LRN analysis (mobile / landline / VoIP / invalid; billed per lookup), download the original or analyzed CSV, upload and reuse media files. Both contacts and media use async import + polling for "ready" status.
  </Accordion>

  <Accordion title="Create, edit, and schedule projects" icon="message">
    Build broadcast projects programmatically: select contact list and phone number, compose the message with merge fields, add media, enable link tracking, send tests, and schedule for a specific time + timezone.
  </Accordion>

  <Accordion title="Pull analytics and billing" icon="chart-line">
    Query message stats by date range with org/brand/campaign filters. Pull usage and billing data per organization or grouped by initiating org.
  </Accordion>

  <Accordion title="Stream events via webhooks" icon="webhook">
    Real-time notifications for `message.sent`, `message.delivered`, `message.failed`, `message.replied`, and `link.clicked`, plus `contact_list.analyzed` when a list finishes analysis - with HMAC-signed payloads and automatic retry.
  </Accordion>

  <Accordion title="Send email" icon="envelope">
    Read sending domains and From addresses (both are set up in the dashboard), manage lists and suppressions, and build, schedule, and report on email campaigns under `/v1/email`. Five email webhook events (`email.delivered`, `email.bounced`, `email.complained`, `email.unsubscribed`, `email.clicked`) subscribe alongside the message events.

    Write endpoints require the email entitlement on your organization and return `403 ENTITLEMENT_REQUIRED` without it. Reads are open. There is no inbound or inbox surface.
  </Accordion>
</AccordionGroup>

## SDKs and tooling

Official SDKs are available for TypeScript ([`@political-comms/sdk`](https://www.npmjs.com/package/@political-comms/sdk), zero runtime dependencies) and Python ([`political-comms`](https://pypi.org/project/political-comms/)), alongside a CLI ([`@political-comms/cli`](https://www.npmjs.com/package/@political-comms/cli)) and an MCP server ([`@political-comms/mcp`](https://www.npmjs.com/package/@political-comms/mcp)) for agent clients — all from [Political-Comms/political-comms-sdk](https://github.com/Political-Comms/political-comms-sdk). The API is also small and stable enough that direct HTTP calls from your language of choice work just as well. The dashboard's **Export to Postman** button generates a fully-configured Postman collection (Collection v2.1) you can import into Postman or [Bruno](https://www.usebruno.com/) for interactive testing.

Format your code samples in curl, Node, Python, Go, or any other language - the API is plain JSON over HTTPS.

## Versioning and deprecation

The API is versioned in the URL path; `v1` is the current and only version. Breaking changes ship as a new version path, never inside `v1`. When an endpoint or field is deprecated, it is marked `deprecated` in the [OpenAPI specification](https://politicalcomms.com/openapi.json), announced in the [changelog](/changelog), and kept working alongside its replacement before any removal. Additive changes (new endpoints, new optional fields) land in `v1` without notice. The full policy, including the `Deprecation`/`Sunset` header commitment and the 90-day sunset window, lives at [Versioning & Deprecation](/api-reference/versioning).

## Idempotency and consistency

* All `GET` endpoints are safe to retry - they have no side effects.
* All `POST` and `PATCH` endpoints that mutate state are designed to be safe to retry; duplicate calls during a network blip will not create duplicate resources. If you need stronger guarantees, send a unique `Idempotency-Key` header on every write - repeated calls with the same key replay the original response.
* Aurora Serverless v2 + RDS Proxy backs every read with **p99 \< 100ms** at the database layer.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.