All endpoints

List messages

GEThttps://anjal.app/v1/inboxes/{id}/messages

Lists messages in an inbox. Tracking fields (firstOpenedAt, openCount, firstClickedAt, clickCount, etc.) are returned on every row — no separate detail fetch needed for an engagement-aware view. Each row also carries a ~200-char plain-body snippet for triage without fetching the full message. Filters can be combined.

Every row carries labels, isSpam and, for sent mail, deliveryStatus and deliveredAt. Spam is left out unless includeSpam=true.

Path parameters

id
required
string

Inbox UUID

Query parameters

limit
integer
offset
integer
labels
string

Comma-separated labels, e.g. `needs-review,billing`. Only results carrying every one are returned.

includeSpam
boolean

Spam is stored but left out by default. Pass `true` to include it (`include_spam` also works).

q
string

Substring search over subject, body, sender and recipient. Gmail-style operators work in the text: from:ben, to:, cc:, subject: (quote a value with spaces: from:"ben hubner"), is:unread, is:read, is:starred, has:attachment, label:billing, in:inbox|sent|archive|spam, before:2026-01-31, after:2026-01-01 (UTC, after inclusive, before exclusive), and -term or -from:x to exclude. Operators combine with AND; anything else is free text. in:drafts and in:trash are not supported.

direction
"inbound" | "outbound"
opened
boolean

When true, return only messages with open_count > 0.

clicked
boolean

When true, return only messages with click_count > 0. Useful for cadence engines listing engaged leads who haven't yet replied.

engagedSince
string

ISO-8601 timestamp. Returns only messages whose lastOpenedAt OR lastClickedAt is at or after this time. Use for incremental polling — pass the timestamp of your last successful sync.

Responses

200application/jsonOK
messages
object[]
id
string

format: uuid

direction
"inbound" | "outbound"

enum: "inbound" | "outbound"

from
string
to
string
subject
string
plainBody
string
htmlBody
string
isRead
boolean
threadId
string

format: uuid

messageIdHeader
string
inReplyTo
string
receivedAt
string

format: date-time

labels
string[]

Lowercase labels on this message.

isSpam
boolean

Flagged by the spam filter. Spam is left out of lists unless `includeSpam=true`.

deliveryStatus
"delivered" | "bounced" | "complained" | "rejected" | null

Outbound only. `delivered` means the recipient's mail server accepted it (not a guarantee of inbox placement). Null until known.

enum: "delivered" | "bounced" | "complained" | "rejected" | null

deliveredAt
string

When the recipient's mail server accepted the message (outbound only).

format: date-time

firstOpenedAt
string

Time of the first open (outbound sends with `trackOpens: true` only). NULL until the first open. Opens are a hint, not proof: Apple Mail Privacy Protection fetches images on delivery, and clients that block images never report an open.

format: date-time

lastOpenedAt
string

Most recent open event. Updates on every open.

format: date-time

openCount
integer

Total opens. Subject to the same caveats as the timestamps.

default: 0

firstClickedAt
string

Timestamp of the first recipient link-click. Reliable signal of engagement (unlike opens, click events are not Apple-MPP-poisoned). NULL until the first click.

format: date-time

lastClickedAt
string

format: date-time

clickCount
integer

default: 0

attachments
object[]
id
string

format: uuid

filename
string
contentType
string
sizeBytes
integer
inline
boolean

Present and true when `htmlBody` embedded this attachment as an inline image and `?inlineImages=refs` replaced it with `attachment:<id>`.

pagination
object
total
integer
limit
integer
offset
integer

Authentication

Send your API key in the X-API-Key header (or Authorization: Bearer <key>). Any prefix accepted by this endpoint — tk_, wk_, ak_, or sa_ — is documented in the key prefix table.