Skip to main content

Search mail

Find received and sent mail by words, sender, recipient, date, folder or label.

GET /v1/search searches received and sent mail together: subjects, body text, addresses and, on received mail, the sender’s name, newest first. Only the first 100,000 characters of each message are searched. Each result says whether it was received or sent and carries a snippet of text around the match.

A search never leaves your workspace. A key tied to one agent searches only that agent’s mail, a test key searches only test mail, and a live key only live mail.

How words match

  • Every word in q must appear somewhere in the message.
  • A word of three or more characters matches the start of a word: inv finds “invoice”, and acme finds billing@acme.com.
  • Shorter words must match a whole word, so in does not find every word that starts with it.
  • A word never matches inside another word: voice does not find “invoice”.

Examples

import { createClient } from "@mailsai/sdk";

const client = createClient(); // reads MAILS_API_KEY

// Invoices received since September with a file attached
const invoices = await client.search({
  q: "invoice",
  after: "2026-09-01",
  has_attachment: true,
  type: "received",
});

// "refund" in mail from acme.com, in every folder
const refunds = await client.search({
  q: "refund",
  from: "acme.com",
  folder: "all",
});
console.log(invoices.data.length, refunds.data.length);

To read a whole message, pass a received hit’s id to GET /v1/messages/received/{id} and a sent hit’s id to GET /v1/messages/{id}.

Filters

Every filter is optional and they combine: a result must match all of them.

ParameterDescription
qstring Full-text search: every word must appear in the subject, body or addresses, as a whole word or, from three letters up, the start of one (inv finds invoice). At most 16 different words (more is a 400).
agent_idstring Filter by agent id or name. A key tied to one agent always reads that agent's mail, and naming another agent is a 403.
fromstring The sender's address contains this text (the display name, which the sender chooses, is not matched).
tostring A recipient address contains this text.
afterstring Only mail at or after this time (ISO 8601, or YYYY-MM-DD).
beforestring Only mail before this time (ISO 8601, or YYYY-MM-DD).
has_attachmentboolean true for mail with a file attachment, false for mail without.
folderstring Which folder's mail to return, or all for every folder. Without it: every folder except trash. One of: inbox, archive, spam, trash, sent, all.
labelstring Only mail in threads carrying this label (a name, or a label id lbl_…).
typestring Only received or only sent mail. One of: received, sent.
limitinteger Page size (1–100). Default: 25.
cursorstring Opaque cursor from a previous page's next_cursor.

Results

The response is a page of hits, { "data": [...], "has_more": …, "next_cursor": … }. Pass next_cursor back as cursor for the next page. Each hit:

FieldDescription
typestring Required. received for a message an agent received, sent for one it sent; it says which kind of id id is. One of: received, sent.
idstring Required. The message id (rcv_… or msg_…).
thread_idstring | null Required. The thread (thrd_…) the message is in. Null for a message in no thread.
agent_idstring Required. Id (agt_…) of the agent that received or sent the message.
subjectstring | null Required. The message's subject. Null when it has none.
fromobject Required. Who the message is from: the sender for received mail, the agent itself for sent mail.
from.addressstring Required. The sender's address for received mail, as on the received message's from.address; the sending agent's address for sent mail.
from.namestring | null Required. The sender's display name on received mail, null when there is none. Always null on sent mail.
tostring[] Required. For received mail, the one agent address it was delivered to. For sent mail, its to recipients; cc and bcc are not listed.
datestring Required. Received time, or sent time for sent mail.
has_attachmentboolean Required. For received mail, true when it carries at least one file attachment (images embedded in the HTML do not count); for sent mail, true when it was sent with any.
folderstring | null Required. The folder of the message's thread. A message in no thread counts as inbox; null only when its thread cannot be found. One of: inbox, archive, spam, trash, sent.
labelsstring[] Required. The label names on the message's thread. Empty when the thread has none or the message is in no thread.
snippetstring Required. Plain text from the message's body around the match (the start of the body when the match is only in the subject or an address, or when q is absent).

Limits

  • 120 searches a minute per workspace, shared by every key and the dashboard. Past that, the API answers 429 rate_limit_exceeded with a Retry-After header.
  • At most 16 different words in q, and at most 200 characters. More words is a 400 rather than a quietly shortened search.
  • A search that runs too long is a 400 that asks for another word or a filter to narrow it.

Next steps

Every parameter is also in the API reference.

Was this page helpful?