A site with a lead form or a CRM sends people into an outreach campaign, learns what became of them, and reports how it ended on its side. The key needs May add prospects to campaigns; without it these requests answer 403.
Your campaigns
curl https://mail.example.com/api/v1/campaigns -H "Authorization: Bearer mr_..."
{
"ok": true,
"campaigns": [
{ "id": 3, "name": "Sales", "goal": "sales", "status": "running", "prospects": 13,
"stages": ["Interest", "Meeting", "Proposal", "Deal"] }
]
}
| Field | What it is |
|---|---|
goal | links, sales, partners, press, hiring, reviews, winback or plain |
status | draft, running or paused |
stages | The campaign's pipeline, from first to last |
Add prospects
curl https://mail.example.com/api/v1/prospects \
-H "Authorization: Bearer mr_..." \
-H "Content-Type: application/json" \
-d '{
"campaign": 3,
"prospects": [
{ "email": "carol@example.com", "name": "Carol", "site": "example.com", "fields": { "plan": "pro" } }
]
}'
Each prospect needs an email or a site. name and fields are optional; fields go into the campaign's emails. Up to 100 prospects per request.
{
"ok": true, "campaign": 3,
"added": 1, "updated": 0, "same": 0, "stopped": 0, "invalid": 0,
"prospects": [ { "contact": "carol@example.com", "result": "added", "id": 30 } ]
}
| Result | Meaning |
|---|---|
added | A new prospect |
updated | Already in the campaign; the name and fields were updated |
same | Already in the campaign, nothing new |
stopped | The address is on your stop list and will not be written to |
invalid | Neither a valid address nor a site |
Look up a prospect
curl "https://mail.example.com/api/v1/prospects?campaign=3&email=carol@example.com" \
-H "Authorization: Bearer mr_..."
Pass email or site.
{
"ok": true,
"prospect": {
"id": 30, "email": "carol@example.com", "name": "Carol", "site": "example.com",
"status": "writing", "reason": "", "step": 1,
"stage": 0, "stage_name": "", "value": 0,
"reply": "", "replied_at": null,
"next_at": "2026-10-20T09:00:00Z", "closed_at": null
}
}
| Field | What it is |
|---|---|
status | new, ready, writing (the sequence is under way), hold, later, replied, agreed, placed (the link is up, in link campaigns) or lost |
reason | Why it is in that state, for example why it was lost |
step | How many steps of the sequence went out |
stage, stage_name | Where it is in the pipeline |
value | The deal's value you reported |
reply, replied_at | The kind of reply and when it came |
next_at | When the next step goes out |
closed_at | When it was won or lost |
Times are in UTC.
Report the outcome
When the conversation moved to your side, tell the campaign, so it stops writing and counts the result.
curl https://mail.example.com/api/v1/prospects/state \
-H "Authorization: Bearer mr_..." \
-H "Content-Type: application/json" \
-d '{ "campaign": 3, "email": "carol@example.com", "state": "agreed", "value": 1200 }'
state | What it does |
|---|---|
replied | The person answered on your side: the sequence stops. Only after a step went out |
agreed | Won |
lost | Lost; add reason: declined, price, timing, competitor, no_need, no_budget or other |
stop | Never write to this address again: it goes on your stop list |
value sets the deal's value, with or without state. The answer is the prospect, as in the lookup. A state that does not apply right now, for example replied before anything was sent, answers 409.