Update campaign settings
Use this request to update campaign-wide settings such as assigned email accounts, sending limits, timezone, and more. The endpoint allows for partial updates.
Only campaigns with a status of DRAFT
or EDITED
can be updated. To change the campaign status to EDITED
use the /make_editable endpoint.
Request
Endpoint
PATCH https://api.woodpecker.co/rest/v2/campaigns/{campaign_id}
Headers
x-api-key: {YOUR_API_KEY}
Content-type: application/json
For details on how to authenticate your requests, please see the authentication guide.
Body
The request body uses the campaign configuration payload. You can update each setting individually without impacting others, as the API supports partial updates.
{
"name":"Updated name",
"email_account_ids": [100001, 100002, 100003],
"settings": {
"timezone":"Pacific/Pago_Pago",
"prospect_timezone": true,
"daily_enroll": 150,
"gdpr_unsubscribe": true,
"list_unsubscribe": true,
"open_disabled_list": ["google.com", "OTHER_PROVIDER"],
"auto_pause_prospect_from_domain": true,
"catch_all_verification_mode": "MAXIMUM"
}
}
Body schema
Field | Type | Description |
---|---|---|
name | string | Name of the campaign |
email_account_ids | array[integer] | List of email account SMTP IDs used in this campaign. Use /mailboxes endpoint to review them. Chosen mailboxes must be connected to Woodpecker without issues |
settings | object | Campaign-level settings object |
└─timezone | string | 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 |
└─prospect_timezone | boolean | Whether to adjust sending times to prospect's timezone instead of the campaign timezone |
└─daily_enroll | integer | 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_unsubscribe | boolean | Whether 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_unsubscribe | boolean | Whether to include List-Unsubscribe header. This option will work only if the {{UNSUBSCRIBE}} snippet is included in your email or account signature |
└─open_disabled_list | array[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_domain | boolean | Whether to automatically pause sending to prospects after a response from the same domain (free providers excluded) |
└─catch_all_verification_mode | string | Catch-all email verification mode - how to approach contacting prospects using catch-all emails.
|
Request sample
Edit campaign's daily limit
- cURL
- Java
- Node.js
curl --request PATCH \
--url "https://api.woodpecker.co/rest/v2/campaigns/{campaign_id}" \
--header "x-api-key: {YOUR_API_KEY}" \
--header "Content-Type: application/json" \
--data '{
"settings": {
"daily_enroll": 150
}
}'
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class WoodpeckerApiClient {
public static void updateCampaignDailyEnroll(String apiKey, String campaignId, int dailyEnroll) throws Exception {
String url = "https://api.woodpecker.co/rest/v2/campaigns/" + campaignId;
String jsonBody = "{\"settings\": {\"daily_enroll\": " + dailyEnroll + "}}";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.method("PATCH", HttpRequest.BodyPublishers.ofString(jsonBody))
.header("x-api-key", apiKey)
.header("Content-Type", "application/json")
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response status: " + response.statusCode());
System.out.println("Response body: " + response.body());
}
}
const axios = require("axios");
async function updateCampaignDailyEnroll(apiKey, campaignId, dailyEnroll) {
try {
const url = `https://api.woodpecker.co/rest/v2/campaigns/${campaignId}`;
const response = await axios({
method: "patch",
url: url,
headers: {
"x-api-key": apiKey,
"Content-Type": "application/json",
},
data: {
settings: {
daily_enroll: dailyEnroll,
},
},
});
console.log("Response status:", response.status);
console.log("Response data:", response.data);
return response.data;
} catch (error) {
console.error("Error:", error.response ? error.response.data : error.message);
throw error;
}
}
Response
Response examples
- 200
- 400
- 401
- 404
- 409
- 500
The campaign has been updated. A full campaign payload will be returned.
Invalid request or malformed syntax. Please review the request
{
"code": "INPUT_DATA_VALIDATION_FAILURE",
"message": "Input data validation failure",
"details": {
"errors": [
{
"field": "Field name",
"detail": "Issue description"
}
]
}
}
Body schema
Field | Type | Description |
---|---|---|
code | string | Error code |
message | string | Descriptive error message |
details | object | Additional information |
└─errors | array[object] | An array of error objects. Each parameter with an issue will be listed |
└─[].field | string | Specifies the parameter with an issue |
└─[].detail | string | Description of the issue |
An issue with authorization. Please review the authorization guide
{
"title": "Unauthorized",
"status": 401,
"detail": "Invalid api key",
"timestamp": "2025-03-05 17:57:00"
}
Body schema
Field | Type | Description |
---|---|---|
title | string | A short title describing the error |
status | integer | The HTTP status code |
detail | string | A detailed message explaining the error |
timestamp | string | The timestamp when the error occurred, YYYY-MM-DD HH:MM:SS UTC |
The requested campaign doesn't exist.
{
"code": "CAMPAIGN_NOT_EXIST",
"message": "Campaign not found",
"details": null
}
Body schema
Field | Type | Description |
---|---|---|
code | string | Error code |
message | string | Descriptive error message |
details | string/null | Additional information. Currently always null |
Only campaigns with a status of DRAFT
or EDITED
can be updated. To change the campaign status to EDITED
use the /make_editable endpoint.
{
"code": "NOT_EDITABLE_STATUS",
"message": "The campaign must be in DRAFT or EDITED status to be updated",
"details": null
}
Body schema
Field | Type | Description |
---|---|---|
code | string | Error code |
message | string | Descriptive error message |
details | string/null | Additional information. Currently always null |
Unknown error, please try again later.
{
"type": "UNKNOWN",
"message": "Unknown error during update campaign call",
"details": null
}