Resend a message
Resend an email that was never delivered (rejected, failed or soft-bounced) with one API call, and see exactly what happened to it.
Sends again an email that never reached the recipient: one that was rejected, failed, or bounced temporarily (a soft bounce). Delivered emails and permanent (hard) bounces cannot be resent. Use it after you fixed the cause — a verified domain, a lifted suppression, a recipient server that is back — instead of rebuilding the send yourself.
POST /v3/messages/{id}/resend
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Required | The message id (msg_…) returned when the email was sent, or listed in Activity / GET /v3/events. |
What happens
- Accepted, then not delivered (rejected or failed in delivery, or soft-bounced): the same email is delivered again under the same message id, at no extra cost — it was counted once already. New
sent/delivered/bouncedevents land on the same message’s timeline, and suppression and every other delivery check apply again. Outcomequeued. - Refused at submission (it never entered delivery, but its content was kept): it is sent again as a new email, linked to the original, and goes through every send check again (domain, quota, suppression…). It counts once, like any send. Outcome
resubmittedwith thenew_message_id; if it is still refused the outcome isrefusedwith the reason inerror. - Nothing is resent while sending is off: a suspended account or paused sending returns
account_suspended/sending_paused(a suspended account’s key may also be refused with403).
Response
Returns { message_id, outcome, attempt, error?, new_message_id? }. outcome is one of queued, resubmitted, refused, content_expired (the email’s content is no longer stored, so it cannot be rebuilt), in_progress (already being delivered or already resent), sending_paused, account_suspended, not_allowed (delivered or permanently bounced), not_found or failed (an unexpected error on our side — error carries a generic message; retry the call). attempt is this message’s resend number when the outcome is queued or resubmitted, and null otherwise. queued keeps the same message_id and costs nothing extra; resubmitted creates a new email (new_message_id) that counts once, like any send. Test (sandbox) messages follow the same rules. An outcome that is not a success is still answered with 200 — branch on outcome.
{
"message_id": "msg_01HBYE7K9Z4PMQDR3W",
"outcome": "queued",
"attempt": 1
}Responses
| Status | Description |
|---|---|
200 | OK. The resend outcome for this message — check outcome. |
401 | Missing or invalid API key. |
403 | The key’s scope does not allow sending (read_only), or the account is suspended. |
Code examples
curl -X POST https://api.wemail.io/v3/messages/{id}/resend \
-H "Authorization: Bearer afn_live_…"const res = await fetch("https://api.wemail.io/v3/messages/{id}/resend", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WEMAIL_API_KEY}`,
},
});
const data = await res.json();import os, requests
r = requests.post(
"https://api.wemail.io/v3/messages/{id}/resend",
headers={"Authorization": f"Bearer {os.environ['WEMAIL_API_KEY']}"},
)
data = r.json()