Skip to main content

Campaigns

The v2/campaigns API allows you to manage your campaigns in Woodpecker. You can:

  • create new campaigns and configure their settings, content, delivery times, follow-ups,
  • fetch campaign statistics,
  • change campaign statuses
  • edit existing campaigns - change the content, update the sending limit, campaign and step settings, add new steps
  • delete campaigns or individual steps

The current implementation focuses on linear EMAIL campaigns. There are some features available in the Woodpecker app that are not supported by the API and will return a 409 error. Here is a list of such features:

Currently unsupported campaign features
  • Campaigns with an IF condition
  • Campaigns with a scheduled start
  • Manual, call, and SMS tasks
  • LinkedIn manual and automated tasks
  • Catch-all validation - won't return an error; this setting is available only via the app
  • Snippet labels - campaigns that use snippet labels in their content won't thrown an error but will return the original snippet value. Eg. {{SNIPPET_10}} instead of {{MY_CUSTOM_NAME}}

Campaign body schema

The campaign payload consists of several objects, all of them are detailed below. An example of a 3-step campaign is also provided for your reference. This example represents a complete payload based on a GET response; please note that not all fields are required for POST or PATCH requests.

Example campaign payload
{
"id": 12345679,
"name": "Three step campaign with custom configuration",
"status": "RUNNING",
"email_account_ids": [100001, 100002, 100003],
"settings": {
"timezone": "Europe/Warsaw",
"prospect_timezone": true,
"daily_enroll": 80,
"gdpr_unsubscribe": true,
"list_unsubscribe": true,
"open_disabled_list": ["google.com", "OTHER_PROVIDER"],
"auto_pause_prospect_from_domain": true,
"catch_all_verification_mode": "MAXIMUM"
},
"steps": {
"id": "e688d52a-b867-4690-acf2-3809286915b1",
"type": "START",
"followup": {
"id": "36c4fb2c-6f4f-45bf-aeae-4903501193hd",
"type": "EMAIL",
"delivery_time": {
"MONDAY": [{ "from": "09:00", "to": "18:00" }],
"TUESDAY": [{ "from": "09:00", "to": "18:00" }],
"WEDNESDAY": [{ "from": "09:00", "to": "18:00" }],
"THURSDAY": [{ "from": "09:00", "to": "18:00" }]
},
"body": {
"versions": [
{
"id": "2af5c021295511bb54acb87b47c59c378a795f67f9a1b73dd34609c193e1664f",
"version": "A",
"subject": "Example subject line - version A",
"message": "<div>Hi {{FIRST_NAME | \"there\"}},</div><div><br /></div><div>This is an example cold email message.&nbsp;</div><div><br /></div><div>Best wishes,&nbsp;</div><div><a href=\"https://woodpecker.co\">Woodpecker</a> team</div>",
"signature": "SENDER",
"track_opens": true
},
{
"id": "c61b5583c7d19fd04d23b2181a17af640c4cf011490acd6f9e4537f62db0e7ba",
"version": "B",
"subject": "Example subject line - version B",
"message": "<div>{{SPINTAX | \"Hi\" | \"Hello\" | \"Good morning\"}} {{FIRST_NAME}},</div><div><br /></div><div>Yet another example of a cold email message.&nbsp;</div><div><br /></div><div>All the best,&nbsp;</div><div><a href=\"https://woodpecker.co\">Woodpecker</a> team</div>",
"signature": "SENDER",
"track_opens": false
}
]
},
"followup_after": { "range": "DAY", "value": 2 },
"followup": {
"id": "a99e297f-8423-4600-8c24-5bc21b936302",
"type": "EMAIL",
"delivery_time": { "FRIDAY": [{ "from": "09:00", "to": "17:00" }] },
"body": {
"versions": [
{
"id": "06cb0a70aba1dedae5a9eb949286fb2326f1e9105851a6be6f187e47c131c7be",
"version": "A",
"subject": null,
"message": "<div>First followup, version A, sender's signature, no open tracking, same subject line</div>",
"signature": "SENDER",
"track_opens": false
},
{
"id": "4d7d78eebd5abe71eee873b5da40d525e16f0f3611a8a543cae274a5a772a54f",
"version": "B",
"subject": null,
"message": "<div>First followup, version B, no signature, no open tracking, same subject line</div>",
"signature": "NO_SIGNATURE",
"track_opens": false
},
{
"id": "4ac2bec5a9082b090aad90eeaa230fe08e7a5ab3a6b968d9328ec437316c9037",
"version": "C",
"subject": null,
"message": "<div>First followup, version C, sender's signature, open tracking, same subject line</div>",
"signature": "SENDER",
"track_opens": true
}
]
},
"followup_after": { "range": "DAY", "value": 6 },
"followup": {
"id": "7371e283-6de9-440a-9eaf-273232b580f7",
"type": "EMAIL",
"delivery_time": {
"WEDNESDAY": [
{
"from": "09:00",
"to": "11:00"
},
{
"from": "14:00",
"to": "16:00"
}
],
"THURSDAY": [
{
"from": "09:00",
"to": "11:00"
},
{
"from": "14:00",
"to": "16:00"
}
]
},
"body": {
"versions": [
{
"id": "f88459226decae0e46c83d8c85b235f90b53097be8bdf7b4ecc7a6d7f4084324",
"version": "A",
"subject": "Subject linie 3A",
"message": "<div>Third followup, sender's signature, no open tracking, different subject line</div>",
"signature": "SENDER",
"track_opens": false
},
{
"id": "740b243fe43ceca7f89f38d940b318e06e3acea404ce551191abe512bf4f4a50",
"version": "B",
"subject": "Subject linie 3B",
"message": "<div>Third followup, sender's signature, no open tracking, different subject line</div>",
"signature": "SENDER",
"track_opens": false
}
]
},
"followup_after": { "range": "DAY", "value": 1 },
"followup": null
}
}
}
}
}

Campaign configuration object

The root level of the campaign payload. It provides general information about the campaign and campaign-wide settings.

FieldTypeDefaultDescription
idinteger-Unique identifier of the campaign
namestring“My campaign #0”Name of the campaign
statusstring-Current campaign status. Possible values: RUNNING, DRAFT, STOPPED, PAUSED, EDITED, COMPLETED
email_account_idsarray[integer]-List of email account SMTP IDs used in this campaign. Use /mailboxes endpoint to review them
settingsobject-Campaign-level settings like timezone, sending limit, unsubscribe settings, etc
└─timezonestring-The default timezone of a campaign. It will be used when setting.prospect_timezone is disabled or when it is enabled but the prospect's timezone is not specified
List of accepted timezones Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Asmara
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
Africa/Brazzaville
Africa/Bujumbura
Africa/Cairo
Africa/Casablanca
Africa/Conakry
Africa/Dakar
Africa/Dar_es_Salaam
Africa/Djibouti
Africa/El_Aaiun
Africa/Freetown
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Kampala
Africa/Khartoum
Africa/Kigali
Africa/Kinshasa
Africa/Lagos
Africa/Libreville
Africa/Lome
Africa/Luanda
Africa/Lusaka
Africa/Malabo
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Mogadishu
Africa/Monrovia
Africa/Nairobi
Africa/Ndjamena
Africa/Niamey
Africa/Nouakchott
Africa/Ouagadougou
Africa/Porto-Novo
Africa/Sao_Tome
Africa/Tripoli
Africa/Tunis
Africa/Windhoek
America/Anchorage
America/Anguilla
America/Antigua
America/Argentina/Buenos_Aires
America/Aruba
America/Asuncion
America/Barbados
America/Belize
America/Bogota
America/Buenos_Aires
America/Caracas
America/Cayenne
America/Cayman
America/Chicago
America/Chihuahua
America/Costa_Rica
America/Denver
America/Dominica
America/Edmonton
America/El_Salvador
America/Godthab
America/Grand_Turk
America/Grenada
America/Guadeloupe
America/Guatemala
America/Guayaquil
America/Guyana
America/Halifax
America/Havana
America/Indianapolis
America/Jamaica
America/La_Paz
America/Lima
America/Los_Angeles
America/Managua
America/Manaus
America/Martinique
America/Mazatlan
America/Mexico_City
America/Miquelon
America/Monterrey
America/Montevideo
America/Montserrat
America/Nassau
America/New_York
America/Panama
America/Paramaribo
America/Phoenix
America/Port-au-Prince
America/Port_of_Spain
America/Puerto_Rico
America/Regina
America/Rio_Branco
America/Santiago
America/Santo_Domingo
America/Sao_Paulo
America/St_Johns
America/St_Kitts
America/St_Lucia
America/St_Thomas
America/St_Vincent
America/Tegucigalpa
America/Tijuana
America/Toronto
America/Tortola
America/Vancouver
America/Whitehorse
America/Winnipeg
Arctic/Longyearbyen
Asia/Aden
Asia/Almaty
Asia/Amman
Asia/Ashgabat
Asia/Baghdad
Asia/Bahrain
Asia/Baku
Asia/Bangkok
Asia/Beirut
Asia/Bishkek
Asia/Brunei
Asia/Calcutta
Asia/Chongqing
Asia/Colombo
Asia/Damascus
Asia/Dhaka
Asia/Dubai
Asia/Dushanbe
Asia/Gaza
Asia/Hong_Kong
Asia/Irkutsk
Asia/Istanbul
Asia/Jakarta
Asia/Jerusalem
Asia/Kamchatka
Asia/Karachi
Asia/Kathmandu
Asia/Kolkata
Asia/Krasnoyarsk
Asia/Kuala_Lumpur
Asia/Kuwait
Asia/Macau
Asia/Magadan
Asia/Manila
Asia/Muscat
Asia/Nicosia
Asia/Novosibirsk
Asia/Omsk
Asia/Phnom_Penh
Asia/Pyongyang
Asia/Qatar
Asia/Rangoon
Asia/Riyadh
Asia/Seoul
Asia/Shanghai
Asia/Singapore
Asia/Taipei
Asia/Tashkent
Asia/Tbilisi
Asia/Tehran
Asia/Thimphu
Asia/Tokyo
Asia/Ulaanbaatar
Asia/Ulan_Bator
Asia/Urumqi
Asia/Vientiane
Asia/Vladivostok
Asia/Yakutsk
Asia/Yerevan
Atlantic/Azores
Atlantic/Bermuda
Atlantic/Cape_Verde
Atlantic/Faroe
Atlantic/Reykjavik
Atlantic/South_Georgia
Atlantic/St_Helena
Atlantic/Stanley
Australia/Adelaide
Australia/Brisbane
Australia/Canberra
Australia/Darwin
Australia/Hobart
Australia/Melbourne
Australia/Perth
Australia/Sydney
Canada/Atlantic
Canada/Eastern
Canada/Mountain
Canada/Newfoundland
Canada/Saskatchewan
Europe/Amsterdam
Europe/Athens
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
Europe/Bucharest
Europe/Budapest
Europe/Chisinau
Europe/Copenhagen
Europe/Dublin
Europe/Gibraltar
Europe/Guernsey
Europe/Helsinki
Europe/Isle_of_Man
Europe/Istanbul
Europe/Jersey
Europe/Kiev
Europe/Lisbon
Europe/Ljubljana
Europe/London
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Minsk
Europe/Monaco
Europe/Moscow
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
Europe/Rome
Europe/San_Marino
Europe/Sarajevo
Europe/Skopje
Europe/Sofia
Europe/Stockholm
Europe/Tallinn
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Vilnius
Europe/Volgograd
Europe/Warsaw
Europe/Zagreb
Europe/Zurich
Hongkong
Indian/Antananarivo
Indian/Chagos
Indian/Christmas
Indian/Cocos
Indian/Comoro
Indian/Kerguelen
Indian/Mahe
Indian/Maldives
Indian/Mauritius
Indian/Mayotte
Indian/Reunion
Pacific/Auckland
Pacific/Efate
Pacific/Fakaofo
Pacific/Fiji
Pacific/Funafuti
Pacific/Guadalcanal
Pacific/Guam
Pacific/Honolulu
Pacific/Kiritimati
Pacific/Midway
Pacific/Nauru
Pacific/Niue
Pacific/Norfolk
Pacific/Noumea
Pacific/Palau
Pacific/Pitcairn
Pacific/Pohnpei
Pacific/Port_Moresby
Pacific/Rarotonga
Pacific/Saipan
Pacific/Tahiti
Pacific/Tarawa
Pacific/Tongatapu
Pacific/Wallis
Singapore
US/Alaska
US/Arizona
US/Central
US/East-Indiana
US/Eastern
US/Hawaii
US/Mountain
US/Samoa
UTC
└─prospect_timezonebooleanfalseWhether to adjust sending times to prospect's timezone instead of the campaign timezone
└─daily_enrollinteger-Maximum number of opening emails that can be sent per day. The limit is shared between all mailboxes. The default maximum value is 500
└─gdpr_unsubscribebooleanfalseWhether the unsubscribe link should provide prospects with an option for GDPR-compliant data removal. This option will work only if the {{UNSUBSCRIBE}} snippet is included in your email or account signature
└─list_unsubscribebooleanfalseWhether to include List-Unsubscribe header. This option will work only if the {{UNSUBSCRIBE}} snippet is included in your email or account signature
└─open_disabled_listarray[string][]List of email service providers (recipient's ESP) for which open tracking is disabled. Available options: google.com, outlook.com, OTHER_PROVIDER
└─auto_pause_prospect_from_domainbooleanfalseWhether to automatically pause sending to prospects after a response from the same domain (free providers excluded)
└─catch_all_verification_modestringBALANCEDCatch-all email verification mode - how to approach contacting prospects using catch-all emails.
  • NONE - contact all catch-all emails, including undeliverable
  • BALANCED - contact deliverable and risky catch-all emails
  • MAXIMUM - contact only deliverable catch-all emails
  • ONLY_VERIFY - do not contact catch-all emails
stepsobject-Campaign steps, including all emails and their delivery times, content, etc

Steps objects

Steps define the structure of a campaign and the actions for each prospect. Every campaign must begin with a START step, followed by 1 to 16 EMAIL steps. Subsequent steps are linked using nested follow-up properties, forming a sequence of steps. Each step includes its own configuration and points to the next step, or null if it is the final step

This type defines an email step of a campaign, including its content, versions, delivery times, and follow-ups.

FieldTypeDefaultDescription
idstring-Unique identifier of the step (UUID)
typestring-Only accepted value is EMAIL to indicate it is an email step
delivery_timeobject-Time intervals during which emails can be sent
bodyobject-Email content configuration including A/B test versions
followup_afterobject1 DAYObject that specifies the time delay before processing a prospect in the next step; if delivery_time allows it. If this object is not provided, a default delay of 1 DAY will be applied
└─rangestringDAYTime unit - DAY, HOUR, MINUTE
└─valueinteger1Value of the time unit (range: 1 - 9999)
followupobject/nullnull (meaning no followup)Next step in the sequence. Should consist of an EMAIL step object as described in this table. Null indicates end of sequence
Example step object

Path: steps.followup

{
"id": "169486a5-e375-48cd-81a1-01a7f2a1895f",
"type": "EMAIL",
"delivery_time": "...", // See delivery_time schema
"body": "...", // See email body schema
"followup_after": {
"range": "DAY",
"value": 1
},
"followup": "..." // the next step of the campaign
}

Delivery time object

The delivery_time object defines the time intervals during which email messages can be sent. The timezone will follow the settings of the timezone and prospect_timezone of the campaign configuration.

Each step must include at least one interval. You can assign one or two time intervals to a single day. Even if there is only one time interval, you must use array brackets. If you provide a list of time intervals, ensure that they do not overlap. If a day is not included in the object, no emails will be sent on that day.

To specify a whole day interval, you can use either "from"="00:00", "to"="00:00" or "from"="00:00", "to"="24:00". The first format is set as the default.

FieldTypeDefaultDescription
MONDAY...SUNDAYarray[object]-Array of time windows for each day. Maximum 2 windows per day. The valid keys are the days of the week: MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
└─[].fromstring-Start time in "HH:mm" format (24-hour)
└─[].tostring-End time in "HH:mm" format (24-hour)
Example delivery_time object

Path: steps.followup.delivery_time

{
"WEDNESDAY": [
{
"from": "09:00",
"to": "17:00"
}
],
"THURSDAY": [
{
"from": "09:00",
"to": "11:00"
},
{
"from": "14:00",
"to": "16:00"
}
]
}

Body object

The body and versions objects define the email content, A/B test versions, open tracking, and signature settings. Each of these can be configured individually for each version, and at least one version must be present.

FieldTypeDefaultDescription
body.versionsarray[object]-Array of email version objects and their definitions. At least one version is required
└─[].idstring-Unique identifier of the email version (hash-based ID, 64 characters)
└─[].versionstringAVersion Identifier: The default version is A. Available versions are A through E. When creating a campaign, the versions are determined by their order in the array, not by explicit declaration
└─[].subjectstring/null-Email subject line. This field is required if the version is part of the first EMAIL step in the sequence. It must be included in all step versions if multiple versions exist. If the step is not the first EMAIL step and the subject field is null, the message will be sent as a follow-up in the same thread. Supports snippets like {{FIRST_NAME}} and spintax
└─[].messagestring-Email body content in HTML format. Supports snippets like {{FIRST_NAME}} and spintax
└─[].signaturestringNO_SIGNATUREWhether to use the sender's email account signature. The available options are: SENDER or NO_SIGNATURE
└─[].track_opensboolean-Whether to track email opens for this email version
Example body object

Path: steps.followup.body

{
"versions": [
{
"id": "06cb0a70aba1dedae5a9eb949286fb2326f1e9105851a6be6f187e47c131c7be",
"version": "A",
"subject": null,
"message": "<div>First followup, version A, sender's signature, no open tracking, same subject line</div>",
"signature": "SENDER",
"track_opens": false
},
{
"id": "4d7d78eebd5abe71eee873b5da40d525e16f0f3611a8a543cae274a5a772a54f",
"version": "B",
"subject": null,
"message": "<div>First followup, version B, no signature, no open tracking, same subject line</div>",
"signature": "NO_SIGNATURE",
"track_opens": false
},
{
"id": "4ac2bec5a9082b090aad90eeaa230fe08e7a5ab3a6b968d9328ec437316c9037",
"version": "C",
"subject": "A new email subject",
"message": "<div>First followup, version C, sender's signature, open tracking, different subject line - sent in the same thread</div>",
"signature": "SENDER",
"track_opens": true
}
]
}