Get a sandbox message
/api/v1/sandbox/messages/{id}The message in full: decoded text and HTML, headers, attachments, the simulated delivery events, and every sandbox webhook attempt it caused with your endpoint's response. The HTML is exactly what your code sent and is not sanitised — render it only in a sandboxed frame.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string | The id identifier. |
Request
/api/v1/sandbox/messages/{id}curl -X GET 'https://app.mailyte.com/api/v1/sandbox/messages/01JBT8XQ2M9WYC3K4F6R7S8T9V' \
-H 'Authorization: Bearer mk_live_YOUR_API_KEY'const response = await fetch('https://app.mailyte.com/api/v1/sandbox/messages/01JBT8XQ2M9WYC3K4F6R7S8T9V', {
method: 'GET',
headers: {
Authorization: 'Bearer mk_live_YOUR_API_KEY',
},
});
const { data } = await response.json();import requests
response = requests.get(
"https://app.mailyte.com/api/v1/sandbox/messages/01JBT8XQ2M9WYC3K4F6R7S8T9V",
headers={"Authorization": "Bearer mk_live_YOUR_API_KEY"},
)
data = response.json()["data"]<?php
$response = Http::withToken('mk_live_YOUR_API_KEY')
->get('https://app.mailyte.com/api/v1/sandbox/messages/01JBT8XQ2M9WYC3K4F6R7S8T9V');
$data = $response->json('data');require "net/http"
require "json"
uri = URI("https://app.mailyte.com/api/v1/sandbox/messages/01JBT8XQ2M9WYC3K4F6R7S8T9V")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer mk_live_YOUR_API_KEY"
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }Response
Success.
dataobjectidstringULID of the stored message.
inbox_idstringsubjectstringheader_fromstringThe From header, as written.
header_toarray<string>The To header addresses.
envelope_rcptsarray<string>Every address the message was sent to, INCLUDING Bcc: blind recipients are in the envelope, never in the headers, so this is the only place they show.
size_bytesintegerattachment_countintegersourcestringsmtp | api | inbound`api` for a test-mode API key send; `inbound` for mail sent to the inbox's `inbound_address`.
simulated_outcomestringdelivered | bounce | softbounce | complaint | suppressedThe outcome simulated for this message (a `@sim.mailyte.com` address or an `X-Mailyte-Simulate` header). Null means the default: accepted, then delivered.
spam_scorenumberNull until the message has been scored; scoring runs after it arrives.
read_atstringWhen it was marked read. Null means unread.
received_atstringWhen the sandbox accepted it.
headersarray<object>Every header in order, repeated names included.
namestringvaluestring
textstringThe text/plain part, decoded. Null when there is none.
htmlstringThe text/html part, decoded and NOT sanitised: it is exactly what your code sent. Render it only in a sandboxed frame with scripts disabled.
attachmentsarray<object>indexintegerPass to GET /sandbox/messages/{id}/attachments/{index}.
filenamestringcontent_typestringsizeintegercontent_idstringSet for an inline (cid:) part.
eventsarray<object>The simulated delivery timeline. These exist only in the sandbox: they never reach your suppression list, your live event log or your live webhooks.
event_typestringe.g. `email.accepted`, `email.delivered`, `email.bounced`.
recipientstringdetailobjectcreated_atstring
webhook_deliveriesarray<object>Every sandbox webhook attempt this message caused, with your endpoint's response.
idintegerwebhook_idstringmessage_idstringThe sandbox message that caused it. Null for a `sandbox.test` event.
event_typestringattemptinteger1 to 5. Retries back off 30 s, 2 min, 5 min, 15 min, 30 min.
status_codeintegerNull when no response arrived; see `error`.
duration_msintegerresponse_excerptstringThe first 1 KB of your response body.
errorstringWhy no response arrived (timeout, refused, blocked address).
created_atstringWhen the attempt was made.
spamobjectThe spam filter's verdict, as a receiving server would score it. Null until `analysed_at` is set; null after that means scoring was unavailable.
scorenumberrequired_scorenumberThe score at which mail is treated as spam.
actionstringe.g. `no action`, `add header`, `reject`.
symbolsarray<object>The rules that fired, largest effect first.
namestringscorenumberdescriptionstringoptionsarray<string>
checksarray<object>Problems found in the message (missing text part, images without alt text, insecure links, missing List-Unsubscribe on bulk mail...). An empty list means none; null means not analysed yet (see `analysed_at`) or the step failed.
idstringseveritystringerror | warning | infotitlestringdetailstring
html_supportobjectHow well the HTML is supported across email clients. Null for a message with no HTML part, before `analysed_at` is set, or if the step failed.
score_pctintegerMarket-share-weighted share of clients that fully support every feature used.
detected_countintegerclientsarray<object>familystringsupportstringfull | partial | none
featuresarray<object>Features the message uses that fail or are partial somewhere.
slugstringtitlestringunsupported_inarray<string>partial_inarray<string>
analysed_atstringWhen analysis finished. It runs a few seconds after the message arrives; until then `spam`, `checks` and `html_support` are null.
Returned inside the standard envelope.
Errors
| Status | When |
|---|---|
401 | The API key is missing, unknown, revoked or expired. All four answer identically, on purpose: distinguishing them would confirm which keys exist. |
403 | The 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. |
404 | No such resource in this organization. |
422 | The request was understood but the values were not acceptable. |
429 | Too 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.