Skip to main content

political-comms

Python SDK for the Political Comms REST API. Direct-to-carrier political texting for campaigns, PACs, advocacy organizations, fundraisers, and elected officials.

Synchronous client built on httpx. Python 3.10 or later.

The full API reference lives at docs.politicalcomms.com and the OpenAPI 3.1 specification at politicalcomms.com/openapi.json.

Install

pip install political-comms

Authentication

Requests authenticate with an API key in the X-API-Key header. Keys are created in the dashboard under Admin > API Keys and are prefixed pc_live_.

Set the key in the environment:

export POLITICAL_COMMS_API_KEY=pc_live_...
from political_comms import PoliticalCommsClient

client = PoliticalCommsClient()

Or pass it to the constructor:

client = PoliticalCommsClient(api_key="pc_live_...")

Quickstart

Verify the credential, then run the standard send workflow: create a project, send yourself a test, and schedule it.

from political_comms import PoliticalCommsClient

client = PoliticalCommsClient()

# 1. Verify the credential.
orgs = client.list_organizations()
print([org.get("display_name") for org in orgs["data"]])

# 2. Create a project.
created = client.create_project(
    organization_id="org_...",
    name="GOTV reminder",
    protocol="sms",
    message_text="Polls are open until 8pm. Find your polling place: {link}",
    phone_number_ids=["pn_..."],
    contact_list_ids=["cl_..."],
    brand_id="brand_...",
    campaign_id="camp_...",
)
project_id = created["data"]["id"]

# 3. Send a test to yourself.
client.test_project(project_id, [{"phone": "+15555550100"}])

# 4. Schedule the send.
client.schedule_project(project_id, "2026-11-03T09:00:00", "America/New_York")

One method exists per API operation, in snake_case: list_organizations, get_hierarchy, list_brands, list_campaigns, list_tracking_domains, list_phone_numbers, list_toll_free_verifications, get_toll_free_verification, list_contact_lists, get_contact_list, import_contact_list, analyze_contact_list, delete_contact_list, list_media, import_media, get_media, delete_media, list_projects, create_project, get_all_project_stats, get_project, update_project, get_project_stats, test_project, schedule_project, unschedule_project, copy_project, archive_project, get_message_stats, get_ledger_usage, get_ledger_usage_by_initiator.

Every method returns the parsed JSON response, a dict of the form {"success": True, "data": ...}.

Error handling

Non-success responses raise PoliticalCommsError with the API's machine readable code, the HTTP status_code, and the raw response body.

from political_comms import PoliticalCommsClient, PoliticalCommsError

client = PoliticalCommsClient()
try:
    client.get_project("proj_unknown")
except PoliticalCommsError as err:
    print(err.code, err.status_code, err)

Network failures raise PoliticalCommsError with code == "NETWORK_ERROR" and status_code == 0.

Retries

The client retries automatically with these rules:

  • 400, 401, 403, 404 are never retried.
  • 429 is retried after waiting until the X-RateLimit-Reset timestamp.
  • 500, 502, 503, 504 are retried with exponential backoff and jitter: 1 second base, 60 second cap, at most 5 attempts total.

Configure the retry budget with max_retries (retries after the first attempt, default 4):

client = PoliticalCommsClient(max_retries=2)

Every POST and PATCH request carries an Idempotency-Key header (a random UUID) so retries are safe; the API returns the cached first response when a key is replayed. DELETE requests send the header only when you supply a key. Supply your own key per call when you need cross-process deduplication:

client.create_project(..., idempotency_key="send-2026-11-03-wave-1")

Rate limits

The API allows, per key over a 60-second sliding window, 100 requests/minute for reads, 60/minute for writes, and 30/minute for deletes. The client exposes the most recent rate limit headers:

client.list_organizations()
print(client.last_rate_limit)
# RateLimitState(limit=100, remaining=97, reset=1767225600)  (reset is Unix seconds)

License

MIT. Questions: support@politicalcomms.com

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

political_comms-0.2.2.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

political_comms-0.2.2-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file political_comms-0.2.2.tar.gz.

File metadata

  • Download URL: political_comms-0.2.2.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.4

File hashes

Hashes for political_comms-0.2.2.tar.gz
Algorithm Hash digest
SHA256 751579c56b81dcec158635c0ab4c6f43707de21fef0ad053dc2d43f2f78e087b
MD5 593d42b5cf92e258f2616a5079fd3253
BLAKE2b-256 a3da7c1d46cddd5329e862ca0535805a19fe1d2cefa3c36c17fa5744edd59d95

See more details on using hashes here.

File details

Details for the file political_comms-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for political_comms-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c9550e49e4230d6c7c4524d066d0199dde54e61aa437e940089abcd97c5c5176
MD5 b011627e352dded77817c0cbd140b5dc
BLAKE2b-256 e9506b121d965cea1673334c58042d9321f3ef95e9de996ae3ffb5eef8056cb1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page