Skip to Content
🚀 Sendbox is live — this documentation is a work in progress.
API ReferenceInbox & Reply Agents

Inbox & Reply Agents

Inbox

MethodPathDescription
GET/repliesFlat list of replies. Query: page, limit, q, intent, campaignId, hasReminder
GET/replies/threadsGrouped by lead — one row per conversation, newest first
GET/replies/summaryToday/yesterday/earlier counts
GET/replies/unread-countUnread replies in the workspace: { messages, conversations }
GET/replies/thread/:leadIdFull conversation: every outbound send plus every inbound reply, in order
POST/replies/thread/:leadId/readMark every reply in the conversation as read. Returns marked
GET/replies/attachments/:idDownload a file attached to a message in a conversation
POST/replies/uploadsUpload a file for a reply before sending it (raw bytes). Returns { id, filename, size }
PATCH/replies/:id/starStar/unstar
POST/replies/:id/draftAI-draft a response (consumes one AI credit; never sends)
POST/replies/:id/sendSend a real reply from the receiving mailbox, with chosen To / Cc / Bcc, formatting and files (see below)
POST/replies/sent/:id/retrySend again a reply that failed (status: "FAILED"). Returns 202
POST/replies/:id/forwardForward the original message to another address
PATCH/replies/:id/remindSet (remindAt: ISO datetime) or clear (remindAt: null) a follow-up reminder

intent is one of: UNCLASSIFIED, INTERESTED, NOT_INTERESTED, OUT_OF_OFFICE, WRONG_PERSON, UNSUBSCRIBE_REQUEST, QUESTION.

OUT_OF_OFFICE is only for automatic replies: the message has Auto-Submitted, X-Autoreply or Precedence: auto_reply, a subject like “Automatic reply:” or “Out of Office”, or an unmistakable out-of-office phrase in its text. A reply a person wrote is not classified as OUT_OF_OFFICE.

Conversation list

Each row of GET /replies/threads has:

  • latestReply: id, rawBody, intentClassification, receivedAt, remindAt, starred, and from ({ name, address } of who wrote it: the lead, or a colleague answering for them; null on replies received before 1 Oct 2026).
  • unreadCount: their replies in this conversation nobody has opened yet.
  • answered: true when you replied after their latest message. lastAnsweredAt is when.
  • replyCount, lead, mailbox, campaign.

Conversation

GET /replies/thread/:leadId returns lead and messages, oldest first. Each message has direction (inbound or outbound), timestamp, subject, body, mailboxEmail, to and cc.

  • Inbound messages also have from, html (the HTML as received, or null), attachments, intentClassification, remindAt and starred.
  • Your own replies (kind: "reply") also have bcc, html, attachments, sentBy (HUMAN, API or AGENT), and status: SENDING, SENT or FAILED (with the reason in error).
  • Campaign emails (kind: "campaign") also have campaign.

Addresses are { name, address }. Each attachment is { id, filename, contentType, size }; download it with GET /replies/attachments/:id.

Received files are kept up to 15 MB per file and 25 MB per message. Inline images (such as a signature logo) are skipped.

Answers written directly in Gmail or Outlook are picked up from the mailbox’s Sent folder (IMAP mailboxes) and show in the conversation as your replies, with sentBy: "HUMAN".

Sending a reply

POST /replies/:id/send body:

FieldDescription
bodyRequired. The text of the reply
htmlOptional. The formatted version (bold, links, images). body stays the plain-text part
toOptional. Up to 20 addresses. Default: whoever wrote the message being answered (the lead, or a colleague who answered for them)
cc, bccOptional. Up to 20 addresses each
attachmentsOptional. Up to 10 files, 20 MB in all: [{ filename, contentType, contentBase64, cid? }]
uploadIdsOptional. Ids from POST /replies/uploads, sent as attachments. Counted in the same 20 MB
backgroundOptional. true returns at once with 202 and sends in the background (see below)

Set cid on an image shown inside html as src="cid:<cid>". It is then sent as an inline image.

For large files, upload them first with POST /replies/uploads while the reply is being written, then send their ids in uploadIds. The send then only sends the email. The upload body is the raw file with Content-Type: application/octet-stream; the file name goes in the X-Filename header (URL-encoded) and its type in X-Content-Type. An upload that is never sent is removed after a day.

curl -X POST https://api.sendboxes.tech/v1/replies/uploads \ -H "Authorization: Bearer sb_live_..." \ -H "Content-Type: application/octet-stream" \ -H "X-Filename: Pitch%20Deck.pdf" -H "X-Content-Type: application/pdf" \ --data-binary @"Pitch Deck.pdf"
curl -X POST https://api.sendboxes.tech/v1/replies/REPLY_ID/send \ -H "Authorization: Bearer sb_live_..." -H "Content-Type: application/json" \ -d '{ "body": "Thanks Sam, Tuesday works.", "to": ["[email protected]"], "cc": ["[email protected]"] }'

Returns { sent, sentReplyId, sentAt } once the mail server has accepted the reply. Attachments over 20 MB in all return 413.

With "background": true the request does not wait for the mail server, which can take up to a minute to accept a large attachment. It returns 202 with { queued, status: "SENDING", sentReplyId }. The reply shows in the conversation right away with status: "SENDING", then SENT, or FAILED with the reason in error. A failed reply is never sent again on its own: send it again with POST /replies/sent/:id/retry. A reply still SENDING after 10 minutes shows as FAILED and can be retried. The dashboard always sends this way.

Through an API key (and so over MCP), a reply can only go to people already in the conversation. Any other address in to, cc or bcc returns 403. In the dashboard you can address anyone.

AI settings

MethodPathDescription
GET/ai-settingsGet workspace AI configuration
PATCH/ai-settingsUpdate aiClassificationEnabled, aiDraftEnabled, autoTagOnReply, customInstructions

Reply agents

MethodPathDescription
GET/reply-agentsList reply agents
POST/reply-agentsCreate one: name, companyName?, companyDomain?, tone?, additionalInfo?, autonomousReplies?, followUpsEnabled?
GET / PATCH / DELETE/reply-agents/:idGet, update, or delete
GET/reply-agents/:id/documentsList trained documents
POST/reply-agents/:id/documentsUpload a document (filename, mimeType, contentBase64 — PDF/DOCX/TXT, max 10MB)
DELETE/reply-agents/:id/documents/:docIdRemove a document
POST/reply-agents/:id/searchPreview knowledge-base retrieval for a query
POST/reply-agents/:id/website/scanStart a background crawl of a domain
GET/reply-agents/:id/website/scanPoll crawl progress
POST/reply-agents/:id/website/indexConfirm which discovered pages to actually train on

tone is one of: PROFESSIONAL, FRIENDLY, CASUAL, FORMAL.