Resend a message

POST/api/v1/email-logs/{event}/resend
Requires anorganization API keywith the scopemessages:send

Submits the stored copy of this message again. Requires messages:send, not events:read — it puts mail back on the wire.

Pass to to send it somewhere else. That is the usual reason to resend: the customer gave the wrong address, and reconstructing the message by hand to send it to the right one loses whatever the original actually said.

A redirected resend is not a privileged path — the new recipient is checked against your suppression list and counted against your rate limit exactly like a fresh send.

Parameters

NameInTypeDescription
eventrequiredpathstringThe event identifier.

Request body

  • toany

    Send to this address instead of the original recipient. Omit to resend to whoever it went to the first time.

Request

POST/api/v1/email-logs/{event}/resend
curl -X POST 'https://app.mailyte.com/api/v1/email-logs/01JBT8XQ2M9WYC3K4F6R7S8T9V/resend' \
  -H 'Authorization: Bearer mk_live_YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "to": "corrected@example.com"
  }'
The key names its own organization, so no X-Organization-ID header is needed.

Response

Success.

  • dataobject
    • objectstringmessage
    • idstring

      The opaque handle for this submission: a BARE ULID, no host and no angle brackets. `GET /email-logs/messages/{id}` resolves it immediately -- you do not have to wait for a webhook. It is NOT the Message-ID. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx: the send mints this before it records anything, so a response that carries a receipt carries a handle. If you are holding null you are not holding an accepted message.

    • message_idstring

      The RFC 5322 Message-ID as it went out on the wire, ANGLE BRACKETS INCLUDED -- `<01JBT8XQ2M...@example.com>`. It is the header your recipient sees and the id `GET /domains/{domain}/messages/{messageId}` takes; percent-encode it in the path. `id` is the bare ULID and the two are not interchangeable: giving `id` to the archive endpoint returns 404, which is precisely what this field used to publish. Null when no sending host could be determined, never a guess.

    • recipientstring

      The PRIMARY addressee, without any display name. Published as `recipient` rather than `to`, matching every event and message row in this section. It stays a single string now that a message may have several recipients, so code reading it does not change type underneath you -- read `recipients` for the whole set. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx, since `to` is required.

    • recipientsobject

      Everyone the message was addressed to. **`bcc` is deliberately absent**: blind recipients are recorded in your delivery log but never echoed on a receipt, which is the one response most likely to be forwarded, logged or shown to a customer.

      • toarray<string>

        As accepted, including any display name.

      • ccarray<string>

        Empty when none were given -- NONE, not unknown.

      • countinteger

        To plus Cc. Excludes Bcc, which is not published here; the limit of 50 counts all three together.

    • reply_tostring

      The Reply-To that went out. NULL MEANS NONE was set, in which case replies go to `from`.

    • attachment_countinteger

      How many files were attached. Zero means none were sent, never that we did not look.

    • fromobject

      The sender. An object here, and everywhere else a sender appears, so one piece of caller code reads all of them.

      • emailstring

        The address this was accepted as, echoed back. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx -- `from` is a required, validated field on the request and the receipt republishes the resolved sender's own address. It is never "sent from nowhere".

      • namestring

        The display name the message was sent with — the same one that went into the `From:` header, not a lookup done afterwards. NULL MEANS NONE: this sender has no display name set, so the message went out as a bare address. It is not "unknown" and it is not withheld — set a name on the sender and it appears here.

    • subjectstring

      The subject AS RENDERED -- `{{ }}` substituted, the same string that went into the header -- which is why it can differ from what you posted and why it is echoed at all. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx: the renderer falls back to the empty string, so a subjectless send is published as `""`, never as null. Test for `""`, not for null.

    • submitted_atstring

      When we ACCEPTED the message, not when it was delivered. A 200 here means queued; the outcome arrives as a delivery event or a webhook. NULL WOULD MEAN UNKNOWN -- we could not read the timestamp off the recorded submission -- and never that the message is not submitted yet. A 2xx has already written the row, and its timestamp column is `NOT NULL DEFAULT current_timestamp()`, so this is not a case to code for.

    • modestringlive | test

      Whether a real message was sent. `test` means this request was made with a TEST API KEY: it was validated exactly as a live one would be — the sender had to be verified, the recipients had to not be suppressed, the rate limit applied — and then nothing was handed to the mail server and nothing was recorded. `id`, `message_id` and `submitted_at` are null for that reason: there is no message to look up. Test mode is a property of the key, not of the request, so it cannot be switched on by a stray parameter in production code.

Returned inside the standard envelope.

Errors

StatusWhen
401The API key is missing, unknown, revoked or expired. All four answer identically, on purpose: distinguishing them would confirm which keys exist.
403The key is valid but may not do this: it lacks the required scope, its IP allowlist does not include you, or this endpoint does not accept API keys.
404No such resource in this organization.
422The request was understood but the values were not acceptable.
429Too many requests, or the organization has spent its sending allowance. `Retry-After` says how long to wait.

Every status, with what causes it and what to do, is on the error reference.