Get inbox messages
Retrieve a paginated list of email messages available in the Woodpecker inbox. You can use the available parameters to narrow down the results by mailbox, campaign, prospect status, or interest level. In standard Woodpecker accounts and agency HQs, the /inbox
endpoint lets you access emails from mailboxes connected by the owner of the API key. In agency client accounts, it provides access to all connected mailboxes.
If you'd like to retrieve responses for a specific prospect, use the v2/prospects endpoint
Request
Endpoint
GET https://api.woodpecker.co/rest/v2/inbox/messages
Headers
x-api-key: {YOUR_API_KEY}
For details on how to authenticate your requests, please see the authentication guide.
Parameters
You can use the query parameters below to filter inbox messages. Each filter is optional - if you omit a parameter, that filter will not be applied. If no parameters are provided, the request will return unfiltered inbox messages based on the default pagination settings.
Parameter | Required | Type | Description |
---|---|---|---|
prospect_status * | No | string | Filters inbox messages by the prospect's current status. Available values: RESPONDED , AUTOREPLIED , BOUNCED , BLACKLISTED , OPT_OUT |
prospect_interest_level * | No | string | Filters inbox messages by the prospect's interest level. Available values: INTERESTED , MAYBE_LATER , NOT_INTERESTED , NOT_MARKED |
mailbox_ids | No | string (comma-separated integers) | Retrieve only responses fetched from the specified mailbox IMAP accounts. Use /mailboxes endpoint to fetch mailbox details |
campaign_ids | No | string (comma-separated integers) | Retrieve only responses associated with given campaigns. Use /campaign endpoints to fetch campaign details |
per_page | No | integer | Number of records per page. Default: 10, maximum: 50 |
next_page_cursor | No | string | Cursor used to retrieve a specific page of results. Use null to start from the first page. Only values returned in the next_page_cursor field of a previous response are accepted. See the pagination section for more details |
*Note: The prospect_status
and prospect_interest_level
parameters are mutually exclusive - you can use only one of them in a request. Providing both will result in an error. If neither parameter is provided, these filters will not be applied.
Request sample
Retrieve 10 latest responses marked as INTERESTED
- cURL
- Python
- Java
- Node.js
curl --request GET \
--url "https://api.woodpecker.co/rest/v2/inbox/messages?per_page=5&prospect_interest_level=INTERESTED" \
--header "x-api-key: {YOUR_API_KEY}"
import requests
def get_interested_messages():
url = "https://api.woodpecker.co/rest/v2/inbox/messages?per_page=5&prospect_interest_level=INTERESTED"
headers = {
"x-api-key": "{YOUR_API_KEY}"
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"GET request failed: {response.status_code}, {response.text}")
if __name__ == "__main__":
try:
data = get_interested_messages()
print("GET response:", data)
except Exception as e:
print("Error:", e)
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 {
String url = "https://api.woodpecker.co/rest/v2/inbox/messages?per_page=5&prospect_interest_level=INTERESTED";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("x-api-key", "{YOUR_API_KEY}")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
System.out.println("GET response: " + response.body());
} else {
throw new Exception("GET request failed: " + response.statusCode() + ", " + response.body());
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
const axios = require('axios');
async function getInterestedMessages() {
const url = 'https://api.woodpecker.co/rest/v2/inbox/messages?per_page=5&prospect_interest_level=INTERESTED';
const headers = {
'x-api-key': '{YOUR_API_KEY}'
};
try {
const response = await axios.get(url, { headers });
console.log('GET response:', response.data);
} catch (error) {
console.error('GET request failed:', error.response ? error.response.status : error.message);
}
}
getInterestedMessages();
Response
Response examples
- 200
- 400
- 401
- 404
- 500
A list of responses retrieved from the Woodpecker inbox. The responses are sorted by the most recently received message
{
"content": [
{
"id": 123456,
"prospect_id": 987654,
"stamp": "2025-03-05 17:57:00",
"subject": "Re: Subject line of the response",
"body": {
"html": "<div>This is a reply in HTML format.</div>"
},
"campaign": {
"id": 456789,
"name": "Associated campaign name"
},
"from_email": "john@prospect.com",
"recipient": "receiving@email.com"
}
],
"next_page_cursor": "Y3VyaW91cywgYXJlbid0IHlvdT8="
}
Body schema
Field | Type | Description |
---|---|---|
content | array[object] | Array of email messages |
└─[].id | integer | Unique ID of the prospect's response |
└─[].prospect_id | integer | Unique ID of the prospect |
└─[].stamp | string | Timestamp of the message in UTC. Format: yyyy-MM-dd HH:mm:ss |
└─[].subject | string | Subject line of the response |
└─[].body | object | Object containing the message content |
└─html | string | Body of the response email in HTML format |
└─[].campaign | object | Object containing the campaign related to the message |
└─id | integer/null | ID of the campaign associated to a response |
└─name | string/null | Name of the campaign |
└─[].from_email | string | Email address of the responder |
└─[].recipient | string | Email address of the recipient (typically, the IMAP of the mailbox that sent the email) |
next_page_cursor | string | Pagination cursor. null means no more results (last page); non-null value indicates the cursor for the next page |
Invalid request parameters or malformed request syntax. Example messages are provided below; other variations are also possible
{
"title": "Bad Request",
"status": 400,
"detail": "Query param 'per_page' value '0' must be greater or equal to 1" | "Query param {param} unsupported value {value}" | "string",
"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 |
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 |
Please review the request URL.
{
"title": "Not Found",
"status": 404,
"detail": "Requested resource does not exist",
"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 |
Unknown error, please try again later
{
"title": "Internal server error",
"status": 500,
"detail": "An unexpected error has occurred. Please try again later.",
"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 |
Pagination
This endpoint uses cursor-based pagination. Results are returned in pages, and each response includes a next_page_cursor
field:
- To start from the first page, omit the
page_cursor
parameter or set it to null. - If
next_page_cursor
isnull
, there are no more pages available, - If
next_page_cursor
contains a value, you can use it in the next request to retrieve the next page of results,
Request first page:
curl --request GET \
--url "https://api.woodpecker.co/rest/v2/inbox/messages?prospect_interest_level=INTERESTED" \
--header "x-api-key: {YOUR_API_KEY}"
Example response:
{
"content": [...],
"next_page_cursor": "T2ggSGkgTWFyayE="
}
Request the next page:
curl --request GET \
--url "https://api.woodpecker.co/rest/v2/inbox/messages?page_cursor=T2ggSGkgTWFyayE=&prospect_interest_level=INTERESTED" \
--header "x-api-key: {YOUR_API_KEY}"