訊息
訊息代表收件匣發送或接收的個別電子郵件。發送豐富的 HTML 電子郵件、追蹤投遞狀態和讀取內送回覆。
Overview
A message is a single email associated with an inbox. When your agent sends an email it creates an outbound message. When someone replies or sends an email to your agent's address, an inbound message is created automatically.
Every message belongs to a thread — either one that already exists (for replies) or a new thread that is created automatically when a fresh conversation starts.
Messages are immutable once created. To send a follow-up, create a new message in the same thread by passing the threadId.
Sending an Email
POST /inboxes/{inboxId}/messages
Send an email from an inbox by posting to its messages endpoint. The to array and subject are required; everything else is optional.
Request Body
| Field | Type | Description |
|---|---|---|
to 必填 |
string[] | Array of recipient email addresses. |
subject 必填 |
string | Email subject line. |
cc |
string[] | CC recipients. |
bcc |
string[] | BCC recipients. Not visible to other recipients. |
bodyText |
string | Plain-text body. Used as fallback when bodyHtml is also provided. |
bodyHtml |
string | HTML body. When both bodyText and bodyHtml are provided, the email is sent as multipart/alternative. |
threadId |
string | Thread to reply into. If omitted, a new thread is created. |
attachmentIds |
string[] | IDs of previously uploaded attachments to include. |
const res = await fetch( `https://api.agentsend.io/inboxes/${inboxId}/messages`, { method: "POST", headers: { "x-api-key": process.env.AGENTSEND_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ to: ["customer@example.com"], subject: "Following up on your request", bodyText: "Hi, just checking in on your request.", bodyHtml: "<p>Hi, just checking in on your request.</p>", }), } ); const message = await res.json(); console.log(message.id); // msg_abc123 console.log(message.delivery); // "email" or "dry-run" console.log(message.status); // "queued"
Message Properties
Each message object returned by the API has the following fields.
| Property | Type | Description |
|---|---|---|
id |
string | Unique message identifier. |
inboxId |
string | The inbox this message belongs to. |
threadId |
string | The conversation thread this message is grouped into. |
direction |
string | outbound for emails your agent sent; inbound for emails received. |
fromAddress |
string | Sender email address. |
toAddresses |
string[] | Primary recipients. |
ccAddresses |
string[] | CC recipients. |
subject |
string | Email subject line. |
bodyText |
string | Plain-text body content. |
bodyHtml |
string | HTML body content. |
delivery |
string | Whether the environment sent real email (email) or only simulated it (dry-run). |
status |
string | Current delivery status. See Message Status below. |
attachments |
object[] | Array of attachment objects with id, filename, contentType, and size. |
messageIdHeader |
string | The RFC 5322 Message-ID header value, used for threading in email clients. |
createdAt |
string | ISO 8601 timestamp of when the message was created. |
Message Status
Outbound messages move through a delivery lifecycle. Check delivery first to confirm whether the environment sent real mail or only simulated it, then use status or webhooks to follow the provider-side lifecycle.
Outbound lifecycle
- queued — The message has been accepted and is waiting to be sent.
- sending — The message is actively being delivered to the recipient's mail server.
- sent — The message was accepted by the recipient's mail server.
- delivered — Delivery confirmed (where supported by the receiving server).
Failed states
- failed — A transient or permanent error prevented delivery. Check the webhook payload for the reason.
- bounced — The recipient address does not exist or the server rejected the message permanently.
- complained — The recipient marked the email as spam.
Inbound messages
- received — An email arrived at the inbox from an external sender.
If a message reaches bounced or complained status, avoid sending further emails to that address to protect your sender reputation.
Listing Messages
GET /inboxes/{inboxId}/messages
Retrieve a paginated list of messages for an inbox. Filter by status to find inbound replies, failed sends, or any other subset.
| Query Param | Type | Description |
|---|---|---|
limit |
number | Number of messages to return. Defaults to 20, max 100. |
offset |
number | Number of messages to skip for pagination. Defaults to 0. |
status |
string | Filter by status. One of queued, sending, sent, delivered, failed, bounced, complained, received. |
// Fetch the 10 most recent inbound messages const res = await fetch( `https://api.agentsend.io/inboxes/${inboxId}/messages?status=received&limit=10`, { headers: { "x-api-key": process.env.AGENTSEND_API_KEY } } ); const { data, total } = await res.json(); for (const msg of data) { console.log(msg.fromAddress, msg.subject, msg.bodyText); }
Use webhooks instead of polling to get notified the moment a new message arrives. Polling is a good fallback for simple scripts and short-lived tasks.
HTML vs Plain Text
AgentSend supports plain-text, HTML, and multipart emails. Use bodyText for plain text and bodyHtml for HTML content.
- If you provide only
bodyText, the email is sent astext/plain. - If you provide only
bodyHtml, the email is sent astext/html. - If you provide both, the email is sent as
multipart/alternative. Email clients that support HTML will show the HTML version; others fall back to the plain-text version.
Always include a bodyText version alongside bodyHtml. This improves deliverability, accessibility, and compatibility with plain-text email clients.
Deleting Messages
DELETE /messages/{id}
Delete a message by its ID. This removes the message record from AgentSend. It does not recall an already-delivered email from the recipient's mailbox.
await fetch(`https://api.agentsend.io/messages/${messageId}`, { method: "DELETE", headers: { "x-api-key": process.env.AGENTSEND_API_KEY }, });
Deleting a message is permanent. Inbound messages that are part of an active thread should be deleted with care, as the thread history will be incomplete.