curl --request POST \
--url https://api.politicalcomms.com/v1/email/campaigns \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"name": "August appeal",
"sender_identity_id": "3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42",
"list_ids": [
"7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64"
],
"subject": "Can you help before Friday?",
"append_utm": true
}
'import requests
url = "https://api.politicalcomms.com/v1/email/campaigns"
payload = {
"name": "August appeal",
"sender_identity_id": "3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42",
"list_ids": ["7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64"],
"subject": "Can you help before Friday?",
"append_utm": True
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'August appeal',
sender_identity_id: '3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42',
list_ids: ['7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64'],
subject: 'Can you help before Friday?',
append_utm: true
})
};
fetch('https://api.politicalcomms.com/v1/email/campaigns', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.politicalcomms.com/v1/email/campaigns",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'August appeal',
'sender_identity_id' => '3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42',
'list_ids' => [
'7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64'
],
'subject' => 'Can you help before Friday?',
'append_utm' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.politicalcomms.com/v1/email/campaigns"
payload := strings.NewReader("{\n \"name\": \"August appeal\",\n \"sender_identity_id\": \"3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42\",\n \"list_ids\": [\n \"7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64\"\n ],\n \"subject\": \"Can you help before Friday?\",\n \"append_utm\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.politicalcomms.com/v1/email/campaigns")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"August appeal\",\n \"sender_identity_id\": \"3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42\",\n \"list_ids\": [\n \"7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64\"\n ],\n \"subject\": \"Can you help before Friday?\",\n \"append_utm\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.politicalcomms.com/v1/email/campaigns")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"August appeal\",\n \"sender_identity_id\": \"3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42\",\n \"list_ids\": [\n \"7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64\"\n ],\n \"subject\": \"Can you help before Friday?\",\n \"append_utm\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"status": "draft",
"sender_identity_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"list_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"suppression_list_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"tracking_domain_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tracking_domain": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"domain": "<string>",
"status": "<string>"
},
"require_approval": true,
"recipient_policy": "max_reach",
"approval_status": "not_required",
"last_tested_at": "2023-11-07T05:31:56Z",
"refcode": "<string>",
"source_code": "<string>",
"scheduled_at": "2023-11-07T05:31:56Z",
"timezone": "<string>",
"audience_count": 123,
"counts": {
"queued": 123,
"sent": 123,
"delivered": 123,
"bounced": 123,
"complained": 123,
"unsubscribed": 123,
"opened": 123,
"clicked": 123,
"failed": 123
},
"pause_reason": "<string>",
"blocked": [
{
"code": "<string>",
"message": "<string>"
}
],
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
}Create Campaign
Create a draft campaign.
Early access. This endpoint returns 403 EMAIL_EARLY_ACCESS until the email product reaches general availability. The contract below is stable and safe to build against.
curl --request POST \
--url https://api.politicalcomms.com/v1/email/campaigns \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"name": "August appeal",
"sender_identity_id": "3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42",
"list_ids": [
"7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64"
],
"subject": "Can you help before Friday?",
"append_utm": true
}
'import requests
url = "https://api.politicalcomms.com/v1/email/campaigns"
payload = {
"name": "August appeal",
"sender_identity_id": "3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42",
"list_ids": ["7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64"],
"subject": "Can you help before Friday?",
"append_utm": True
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'August appeal',
sender_identity_id: '3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42',
list_ids: ['7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64'],
subject: 'Can you help before Friday?',
append_utm: true
})
};
fetch('https://api.politicalcomms.com/v1/email/campaigns', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.politicalcomms.com/v1/email/campaigns",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'August appeal',
'sender_identity_id' => '3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42',
'list_ids' => [
'7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64'
],
'subject' => 'Can you help before Friday?',
'append_utm' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.politicalcomms.com/v1/email/campaigns"
payload := strings.NewReader("{\n \"name\": \"August appeal\",\n \"sender_identity_id\": \"3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42\",\n \"list_ids\": [\n \"7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64\"\n ],\n \"subject\": \"Can you help before Friday?\",\n \"append_utm\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.politicalcomms.com/v1/email/campaigns")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"August appeal\",\n \"sender_identity_id\": \"3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42\",\n \"list_ids\": [\n \"7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64\"\n ],\n \"subject\": \"Can you help before Friday?\",\n \"append_utm\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.politicalcomms.com/v1/email/campaigns")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"August appeal\",\n \"sender_identity_id\": \"3f7a9c1e-8b24-4d6f-a2e5-9c7b3f1a8d42\",\n \"list_ids\": [\n \"7c1de5f0-9a42-4b6d-8e33-2f5a9c7b1e64\"\n ],\n \"subject\": \"Can you help before Friday?\",\n \"append_utm\": true\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"status": "draft",
"sender_identity_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"list_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"suppression_list_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"tracking_domain_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tracking_domain": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"domain": "<string>",
"status": "<string>"
},
"require_approval": true,
"recipient_policy": "max_reach",
"approval_status": "not_required",
"last_tested_at": "2023-11-07T05:31:56Z",
"refcode": "<string>",
"source_code": "<string>",
"scheduled_at": "2023-11-07T05:31:56Z",
"timezone": "<string>",
"audience_count": 123,
"counts": {
"queued": 123,
"sent": 123,
"delivered": 123,
"bounced": 123,
"complained": 123,
"unsubscribed": 123,
"opened": 123,
"clicked": 123,
"failed": 123
},
"pause_reason": "<string>",
"blocked": [
{
"code": "<string>",
"message": "<string>"
}
],
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
}Authorizations
Authenticate every request by passing your API key in the X-API-Key header. Keys are scoped to your organization hierarchy.
Headers
Optional idempotency key: a unique string of 16-200 printable ASCII characters (a UUID is recommended). Retrying the write with the same key within 24 hours returns the stored response of the first call with an X-Idempotent-Replayed: true response header instead of executing it again. Reusing a key with a different request body returns 422 (IDEMPOTENCY_MISMATCH); a duplicate sent while the first call is still running returns 409 with a Retry-After header. Keys are scoped per endpoint and organization.
16 - 200Body
2551 - 50 elements502552551000000255255Append UTM parameters to outbound links for attribution.
Mark the send as a re-permission (re-consent) message.
Tracking domain serving this campaign's tracked links, open pixel, unsubscribe page and browser view, so recipients see your own links. host instead of the platform one. Must be an active tracking domain your organization owns or inherits from a parent. Omit to let the platform pick the obvious default (the tracking domain matching your sending domain's root, or your only one); send null to force the platform link host.
Require an approval after the test send before this campaign can schedule or send. Off by default; every campaign still requires a successful test send regardless of this setting.
Which subscribed contacts on the campaign's lists actually receive it. max_reach (default) sends to every subscribed contact. max_deliverability sends only to contacts whose current validation verdict is deliverable; contacts that have never been validated are skipped.
max_reach, max_deliverability 