Get prospects in campaign
This is a v1 legacy endpoint. It uses a different path /rest/v1
and may return different error codes and response formats compared to v2. While it remains functional, consider handling errors accordingly.
Retrieve a paginated list of prospects enrolled in given campaigns.
Each prospect is returned together with their snippet data, campaign status, campaign information like campaign name, status, as well as prospect's interest level in this campaign. You can sort the prospects or filter them by specific fields and values.
If you are looking for:
- prospects in your whole account - visit this guide
- searching for prospects - visit this guide
Request
Endpoint
GET https://api.woodpecker.co/rest/v1/prospects?campaigns_id={campaign_ids}
Headers
x-api-key: {YOUR_API_KEY}
For details on how to authenticate your requests, please see the authentication guide.
Parameters
Sorting and pagination
Parameter | Required | Type | Description |
---|---|---|---|
page | No | integer | Requested results page (1-based) |
per_page | No | integer | Number of records per page. Default: 100, maximum: 1000 |
sort | No | string | Order the results based on the specified column. Default: order by ID ascending |
For sorting, use +
before the field name for ascending order and -
for descending order. To sort by multiple fields, separate them with a comma.
To sort prospects by company
name ascending and last_contacted
date descending use: sort=+company,-last_contacted
Fields available for sorting
- id
- status
- updated
- last_contacted
- last_replied
- first_name
- last_name
- company
- organization_id
- industry
- website
- tags
- title
- phone
- address
- city
- state
- country
- snipet1 - snipet4
- snippet5 - snippet15
- last_opened - available only with
OPENED
activity paramater - last_clicked - available only with
CLICKED
activity paramater - sent_mails - available only with
OPENED
orCLICKED
activity paramater
Filtering
You can filter results by using one or more of the following parameters:
Parameter | Required | Type | Description |
---|---|---|---|
campaigns_id | Yes | integer | Comma-separated list of campaign IDs that prospects are enrolled in |
id | No | integer | Comma-separated list of prospects to retrieve |
status | No | string | Prospect's campaign status: ACTIVE , BOUNCED , TO-CHECK , TO-REVIEW , REPLIED , AUTOREPLIED , BLACKLIST , PAUSED , INVALID |
contacted | No | boolean | Whether a prospect has been contacted in the requested campaigns |
interested | No | string | Returns prospects only if they have a specific interest level set in any of the campaigns they are enrolled in. Available values: INTERESTED , MAYBE-LATER , NOT-INTERESTED , NOT-MARKED . Please mind _ instead of - in the response |
activity | No | string | Returns prospects based on their click and open activity. Available values: OPENED , NOT-OPENED , CLICKED , NOT-CLICKED |
diff | No | string | Return prospects whose activity timestamp is greater than the provided date. Uses ISO 8601-like format: 2025-01-15T00:00:00%2B0200 . Available timestamps: updated , last_opened (only with OPENED activity paramater), last_clicked (only with CLICKED activity paramater) |
Request sample
Get prospects in specific campaigns
The example below showcases how to fetch last 50 most recently updated prospects, in two given campaigns, with campaign status REPLIED
.
- cURL
- Java
- Node.js
curl --request GET \
--url "https://api.woodpecker.co/rest/v1/prospects?sort=-updated&status=REPLIED&campaigns_id=321654,987654&per_page=50" \
--header "x-api-key: {YOUR_API_KEY}"
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 main(String[] args) {
try {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.woodpecker.co/rest/v1/prospects?sort=-updated&status=REPLIED&campaigns_id=321654,987654&per_page=50"))
.header("x-api-key", "{YOUR_API_KEY}")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Response Code: " + response.statusCode());
System.out.println("Response: " + response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
const axios = require("axios");
const API_URL = "https://api.woodpecker.co/rest/v1/prospects?sort=-updated&status=REPLIED&campaigns_id=321654,987654&per_page=50";
const API_KEY = "{YOUR_API_KEY}";
async function getCampaignProspects() {
try {
const response = await axios.get(API_URL, {
headers: {
"x-api-key": API_KEY,
},
});
console.log("Response Status:", response.status);
console.log("Response Data:", response.data);
} catch (error) {
console.error("Error:", error.response ? error.response.data : error.message);
}
}
getCampaignProspects();
Response
Response headers
Parameter | Type | Description |
---|---|---|
X-Total-Count | integer | Total number of prospects that match the criteria. |
Response examples
- 200
- 200 (no prospects)
- 400
- 401
- 403
- 404
- 409
- 500
An array of prospect objects. If a prospect exists in multiple requested campaigns, they will be returned as separate, per-campaign, objectes. Some fields will be returned only when the request uses specific paramaters. Such properties are not available in the example below and have a note in the body schema
[
{
"id": 1234567890,
"email": "erlich@bachmanity.com",
"first_name": "Erlich",
"last_name": "Bachman",
"company": "Bachmanity",
"organization_id": 654321789,
"industry": "IT",
"website": "https://bachmanity.com",
"linkedin_url": "https://linkedin.com/erlich-bachman",
"tags": "#VISIONARY",
"title": "CEO",
"phone": "+1 987-654-321",
"address": "700 Welch Road",
"city": "Palo Alto",
"state": "California",
"country": "United States",
"last_contacted": "2025-03-20T14:32:34+0100",
"last replied": "2025-03-21T08:11:35+0100",
"updated": "2025-03-21T08:11:35+0100",
"encrypted": false,
"snipet1": "You are running a successful startup incubator Bachmanity",
"snipet2": "",
"snipet3": "",
"snipet4": "",
"snippet1": "",
"snippet2": "",
"snippet3": "",
"snippet4": "",
"snippet5": "",
"snippet6": "",
"snippet7": "",
"snippet8": "",
"snippet9": "",
"snippet10": "",
"snippet11": "",
"snippet12": "",
"snippet13": "",
"snippet14": "",
"snippet15": "",
"snippet_labels": { "custom_snippet": "You are running a successful startup incubator Bachmanity" },
"interested": "MAYBE_LATER",
"campaign_id": 654321,
"campaign_name": "SaaS in America",
"campaign_email": "jared.dunn@piedpiper.com",
"campaign_emails": [
"jared.dunn@piedpiper.com",
"richard.hendricks@piedpiper.com",
"jian@bachmanity.com"
],
"followup_after": "2025-03-22T00:00:00+0100",
"campaign_status": "RUNNING",
"sent_mails": 1,
"status": "REPLIED"
}
]
Body schema
Field | Type | Description |
---|---|---|
[].prospect | object | Contains prospect data |
└─ id | integer | Unique identifier of a prospect |
└─ email | string | Prospect's email address |
└─ first_name | string | Prospect's first name |
└─ last_name | string | Prospect's last name |
└─ company | string | Prospect's company name |
└─ organization_id | integer | Unique identifier of a prospect's company |
└─ industry | string | Prospect's industry |
└─ website | string | Prospect's website URL |
└─ linkedin_url | string | Prospect's LinkedIn profile URL |
└─ tags | string | Tags associated with the prospect. Tags start with a # and are separated with a space |
└─ title | string | Prospect's job title |
└─ phone | string | Prospect's phone number |
└─ address | string | Prospect's address |
└─ city | string | Prospect's city |
└─ state | string | Prospect's state or region |
└─ country | string | Prospect's country |
└─ snippet_labels | object | Custom snippet labels |
└─└─ label_name | string | Key - value pairs representing a snippet label and its value |
└─ last_contacted | string | Date when the prospect was last contacted in any of the campaigns (ISO 8601 format) |
└─ last replied | string | Date when the prospect last replied to any of the campaigns (ISO 8601 format). Note the missing _ |
└─ updated | string | Date when the prospect was last updated (ISO 8601 format) |
└─ encrypted | boolean | Whether a prospect is encrypted |
└─ snipet | string | Legacy. Always equal to the corresponding snippetX values. There are 4 snipet fields (snipet1 to snipet4 ) |
└─ snippet | string | Prospect custom snippets. There are 15 snippet fields (snippet1 to snippet15 ) |
└─ status | string | Prospect's campaign status |
└─ interested | string/null | Available only if the prospect has an assigned interest level in a given campaign. Available values: INTERESTED , MAYBE_LATER , NOT_INTERESTED |
└─ campaign_id | integer | Unique identifier of the campaign |
└─ campaign_name | string | Name of the campaign |
└─ campaign_email | string | One of the campaign sending email addresses. If multiple are used, refer to campaign_emails instead |
└─ campaign_emails | array[string] | List of campaign sending email addresses |
└─ followup_after | string/null | Available only if its value is set. The earliest date after which a prospect can be contacted. Primarily used for follow-ups after an autoresponse. |
└─ campaign_status | string | Current status of the campaign. Available values: RUNNING , DRAFT , STOPPED , PAUSED , EDITED , COMPLETED |
└─ sent_mails | integer/null | Available only if a prospect has been contacted. Number of emails sent from the specific campaign the webhook comes from |
└─ last_open | string/null | Available only with OPENED activity parameter. Timestamp when the prospect has last opened an email |
└─ last_clicked | string/null | Available only with CLICKED activity parameter. Timestamp when the prospect has last clicked a link in an email |
└─ click_url | string/null | Available only with CLICKED activity parameter. URL of the clicked link. Each clicked link will result in a separate prospect object |
There are no prospects matching your criteria. Please review the request parameters and your prospect database.
{
"message": "There are no prospects matching the given criteria."
}
Body schema
Field | Data Type | Description |
---|---|---|
message | string | Descriptive response message |
Invalid request or malformed request syntax.
{
"status": {
"status": "ERROR",
"code": "E_WRONG_PARAM",
"msg": "Wrong param [param_name]=requested_param" | "Unknown param:madeUpParam" | "Wrong param, required activity=OPENED|NOT-OPENED" | "Wrong param, required activity=CLICKED|NOT-CLICKED"
}
}
Body schema
A list of all available status.code
values is available here
Field | Data Type | Description |
---|---|---|
status | object | Contains error details |
└─status | string | Overall status, set to ERROR for non-2xx responses |
└─code | string | Code indicating the error category |
└─msg | string | Descriptive error message |
An issue with authorization. Please review the authorization guide
{
"status": {
"status": "ERROR",
"code": "E_SESSION",
"msg": "The API key you've entered is incorrect or no longer valid. Check if you pasted the key correctly. You can generate a new key in Woodpecker: Settings -> API Keys."
}
}
Body schema
A list of all available status.code
values is available here
Field | Data Type | Description |
---|---|---|
status | object | Contains error details |
└─status | string | Overall status, set to ERROR for non-2xx responses |
└─code | string | Code indicating the error category |
└─msg | string | Descriptive error message |
API access denied. You subscription might not be active, lack the API add-on, or the key belongs to an inactive client company.
{
"status": {
"status": "ERROR",
"code": "E_NO_PERMISSION",
"msg": "Api access denied." | "You need to have an API keys addon to access our API."
}
}
Body schema
A list of all available status.code
values is available here
Field | Data Type | Description |
---|---|---|
status | object | Contains error details |
└─status | string | Overall status, set to ERROR for non-2xx responses |
└─code | string | Code indicating the error category |
└─msg | string | Descriptive error message |
Please review the request URL
{
"status": {
"status": "ERROR",
"code": "E_URL_NOT_FOUND",
"msg": "URL not found: /Woodpecker/rest/v1/webhooks/someMadeUpURL"
}
}
Body schema
A list of all available status.code
values is available here
Field | Data Type | Description |
---|---|---|
status | object | Contains error details |
└─status | string | Overall status, set to ERROR for non-2xx responses |
└─code | string | Code indicating the error category |
└─msg | string | Descriptive error message |
Please review the rate limits. API v1 is subject to the same rate limits as v2, however the response code is 409
instead of 429
.
{
"status": {
"status": "ERROR",
"code": "E_TOO_MANY_REQUESTS",
"msg": "Too many requests in one time"
}
}
Body schema
A list of all available status.code
values is available here
Field | Data Type | Description |
---|---|---|
status | object | Contains error details |
└─status | string | Overall status, set to ERROR for non-2xx responses |
└─code | string | Code indicating the error category |
└─msg | string | Descriptive error message |
An unknown error. Please try again later.
{
"status": {
"status": "ERROR",
"code": "E_UNNOWN",
"msg": "Unknown error."
}
}
Body schema
A list of all available status.code
values is available here
Field | Data Type | Description |
---|---|---|
status | object | Contains error details |
└─status | string | Overall status, set to ERROR for non-2xx responses |
└─code | string | Code indicating the error category |
└─msg | string | Descriptive error message |