Get a message
Returns one message with its headers, body and attachment metadata.
Permission
The key must be granted mail.messages.read
A key without it gets 403 insufficient_scope, with the missing permission named in details.
The message is parsed here: MIME traversal, transfer decoding and RFC 2047 header decoding are done for you. Attachment bytes are a separate call, so reading a message never pulls a large file through the response.
Path parameters
| Field | Type | Description |
|---|---|---|
id required |
string | The message to read. |
Request
curl https://api.veruapis.com/v1/messages/:id \
-H "Authorization: Bearer vak_live_..."
Response
| Field | Type | Description |
|---|---|---|
subject |
string | |
from |
object | The sender, parsed apart. Its fields are below. |
to |
object[] | Recipients. Its fields are below. |
cc |
object[] | Copied recipients. Its fields are below. |
date |
string | The Date header as the sender wrote it, timezone included. |
text |
string | The plain-text body. Absent when the message has none. |
html |
string | The HTML body. Absent when the message has none. |
headers |
object | Every header not lifted into a field above, so nothing is lost. |
attachments |
object[] | What is attached. Fetch the bytes separately. Its fields are below. |
The from
| Field | Type | Description |
|---|---|---|
name |
string | The display name, when the message carried one. |
email |
string | The address itself. |
Each item in to
| Field | Type | Description |
|---|---|---|
name |
string | The display name, when the message carried one. |
email |
string | The address itself. |
Each item in cc
| Field | Type | Description |
|---|---|---|
name |
string | The display name, when the message carried one. |
email |
string | The address itself. |
Each item in attachments
| Field | Type | Description |
|---|---|---|
part_id |
string | Pass this as :part to download the bytes. |
filename |
string | |
content_type |
string | |
size |
integer | Bytes after decoding, not the encoded length on the wire. |
inline |
boolean | True for an image the HTML body refers to rather than a file attached to it. |
{
"data": {
"id": "b2e4ec99-3ac1-4265-8b24-087db3f6cbde",
"subject": "Quarterly numbers",
"from": { "name": "Alice Ng", "email": "[email protected]" },
"to": [ { "name": "Bob Smith", "email": "[email protected]" } ],
"cc": [],
"date": "Wed, 2 Sep 2026 19:46:39 +0000",
"message_id": "<[email protected]>",
"text": "The numbers are attached.",
"html": "<p>The numbers are attached.</p>",
"headers": { "X-Campaign-Id": "autumn-2026" },
"attachments": [
{ "part_id": "2", "filename": "q3.pdf", "content_type": "application/pdf", "size": 102400, "inline": false }
]
},
"meta": { "request_id": "req_01j8z9...", "timestamp": "2026-09-02T10:00:00Z" }
}
The message is parsed for you: MIME traversal, transfer decoding and RFC 2047 header decoding are done here so every caller does not repeat them. Attachment bytes are a separate call, so reading a message never drags a 20 MB PDF through the response.
Every failure uses the same shape, with a stable string code you can branch on. See the error reference.
Related
- POST Create a draft
- POST Create a mail filter
- POST Create a mail folder
- DELETE Delete a draft
- DELETE Delete a mail filter
- DELETE Delete a mail folder
- DELETE Delete a message
- GET Download an attachment
- GET Get display preferences
- GET List attachments
- GET List drafts
- GET List mail filters
- GET List mail folders
- GET List messages
- POST Move messages
- PUT Replace a draft
- POST Send an email
- POST Change flags and labels
- PATCH Rename a mail folder
- PATCH Update display preferences