Replies
A reply is a message from a prospect that arrived in one of the mailboxes of the workspace. anymail classifies each reply. The API returns the fact, the classification and a short snippet. It does not return the full text of a reply.
| Method | Path | Action |
|---|---|---|
GET |
/api/v1/replies |
List classified replies |
PATCH |
/api/v1/replies/{id} |
Correct the classification of a reply |
List replies#
| Parameter | Type | Notes |
|---|---|---|
classification |
string | One of interested, neutral, not_interested, unclassified, autoresponder. |
since |
ISO 8601 | Replies received at or after this time. |
campaign_id |
UUID | Replies to one campaign. |
prospect_id |
UUID | Replies from one prospect. |
limit |
integer | 1 to 100. Default 50. |
cursor |
string | See Pagination. |
Without classification, the list leaves out autoresponders, like the All replies folder in the app. classification=autoresponder returns only autoresponders. unclassified returns replies that are not classified yet, for example when the workspace has no model key.
curl "https://app.anymail.watch/api/v1/replies?classification=interested&since=2026-09-01" \
-H "Authorization: Bearer $ANYMAIL_TOKEN"
Response 200
{
"data": [
{
"id": "20000000-0000-0000-0000-000000000001",
"prospect": { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "email": "ada@example.com", "first_name": "Ada", "last_name": null },
"company": { "id": "1b4e28ba-2fa1-11d2-883f-0016d3cca427", "name": "Example Ltd", "domain": "example.com" },
"campaign": { "id": "3f2b1c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "name": "Q3 outbound" },
"mailbox_id": "b2c3d4e5-0000-4000-8000-000000000001",
"from_email": "ada@example.com",
"subject": "Re: Quick question",
"classification": "interested",
"classification_overridden": false,
"is_autoresponder": false,
"is_read": false,
"received_at": "2026-09-03T10:00:00.000+00:00",
"snippet": "Sounds good, let's talk next week. Does Tuesday 10:00 work?"
}
],
"next_cursor": null
}
snippetis the first 160 characters of the text on one line.prospect.emailcan benullwhen the prospect was deleted.companyisnullfor an address without a company.classification_overriddenistrueafter a human correction.
Errors: 400 for an invalid classification, since, UUID, limit or cursor.
Correct a classification#
PATCH /api/v1/replies/{id} sets the classification by hand. It writes the same fields as the menu in the Inbox: classification, classification_overridden = true, classified_by = "human", a new classified_at and no classification_error. The classifier does not touch the row again, even if a classification is in progress. The call also works on a reply that is not classified yet.
Body (JSON, up to 4 KiB)
| Field | Type | Required | Notes |
|---|---|---|---|
classification |
string | Yes | One of interested, neutral, not_interested. |
curl -X PATCH "https://app.anymail.watch/api/v1/replies/20000000-0000-0000-0000-000000000001" \
-H "Authorization: Bearer $ANYMAIL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"classification":"not_interested"}'
Response 200 returns the reply in the list shape, without the data wrapper, with "classification_overridden": true.
Errors
| Status | Message |
|---|---|
400 |
The body errors listed on Errors, or `classification` must be one of: interested, neutral, not_interested. |
404 |
Reply not found. This includes a reply from another workspace and an id that is not a UUID. |