ravenhook

Get one message

GET/messages/{id}Bearer token required

The complete message — both bodies, every header, and attachment metadata. Use the id from GET /messages or GET /messages/latest.

Path parameter

idrequiredThe message id we assigned. Not the sender's message_id, which is unreliable and may be empty

Example

import os, requests

reply = requests.get(
    f"https://api.ravenhook.dev/messages/{message_id}",
    headers={"Authorization": f"Bearer {os.environ['RAVENHOOK_TOKEN']}"},
)

if reply.status_code == 404:
    raise AssertionError("Message expired or was never yours")

message = reply.json()
const res = await fetch(`https://api.ravenhook.dev/messages/${id}`, {
  headers: { Authorization: `Bearer ${process.env.RAVENHOOK_TOKEN}` },
});

if (res.status === 404) {
  throw new Error("Message expired or was never yours");
}

const message = await res.json();
curl -s "https://api.ravenhook.dev/messages/ed32433d12e145b19ee0117418d688b6" \
  -H "Authorization: Bearer $RAVENHOOK_TOKEN"

Response

{
  "id": "ed32433d12e145b19ee0117418d688b6",
  "subject": "Your verification code",
  "from": "noreply@theircompany.com",
  "to": "mfa@ex4mple0ns.inbox.ravenhook.dev",
  "text_body": "Your code is 483920. It expires in 10 minutes.",
  "html_body": "<p>Your code is <b>483920</b>.</p>",
  "headers": {
    "Subject": "Your verification code",
    "From": "noreply@theircompany.com",
    "Date": "Sun, 23 Aug 2026 18:04:08 -0000"
  },
  "attachments": [
    { "filename": "receipt.pdf", "content_type": "application/pdf", "size": 18244 }
  ],
  "received_at": 1785515448.6,
  "has_attachments": true
}

About html_body

It is sanitised before we return it — scripts, event handlers and dangerous URL schemes are stripped, and links survive. The original is kept in storage exactly as it arrived; cleaning happens on the way out.

It is still markup written by whoever sent the email. If you render it, render it in a sandboxed iframe with a restrictive content security policy. Sanitisation should not be the only thing between you and a hostile sender.

html_body is null when the message was plain text only.

Attachments

You get the filename, media type and size. The file contents are not stored and cannot be downloaded — there is no endpoint for it, and the bytes were discarded when the message arrived.

That is deliberate. Storing attachments would multiply what a breach exposes for a use case that almost never needs the file, only the knowledge that one was attached.

Errors

CodeCause
401Token missing, malformed, or unknown
404No such message, it expired, or it belongs to another namespace — all three are indistinguishable on purpose
429Too many requests

A 404 on a message that worked minutes ago is usually retention, not a bug. Messages are deleted automatically 24 hours after they arrive.