Docs Home Beam MCP APIs

Unibox API

Lead email conversations and reply sending for connected tools

Lead Conversation Threads

The Unibox API exposes canonical lead email conversations so connected tools can review chronological messages, find an existing lead's sent campaign steps, send a reply to a step or a separate message, understand answer status, stage and reuse attachments, apply lead actions, and forward messages.

Find the right conversations

Filter by answer status, campaign, mailbox, conversation classification, reply primary category, and detailed reply subcategory.

Use Unibox semantics

Answer status mirrors the current Unibox behavior so API clients and the web inbox stay aligned.

Send safely

Replies require a current latest-message check, idempotency key, workspace sender validation, and content validation before sending.

Base URL and Authentication

All requests use your Organization API Key with the standard bearer token header.

https://beam.lightmeter.io Authorization: Bearer your_api_key_here

Example Request

GET
/api/v1/unibox/threads?filter[answer_status]=unanswered&filter[classification]=positive
curl -X GET "https://beam.lightmeter.io/api/v1/unibox/threads?filter[answer_status]=unanswered&filter[classification]=positive" \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json"

Filtering by date and time

The Commercial strip shows the same full-history counts as Deals. Select Reply needed, Cooling or Gone cold to see the matching threads. The notice shows how many conversations are listed and how many have no thread here. With other filters, it shows the count within those filters instead. API callers use filter[commercial_status] with reply_needed, cooling or gone_cold; MCP callers use commercial_status. Selecting a count clears other filters. Clearing the filter returns to the plain Inbox.

Use filter[latest_message_after] (inclusive) and filter[latest_message_before] (exclusive) with RFC 3339 timestamps to list threads by the time of their latest message. Include the offset of the time zone you mean, so that a day such as 1 October covers 2026-10-01T00:00:00+02:00 to 2026-10-02T00:00:00+02:00. Either bound may be used alone, and both combine with every other filter. In a query string, send a positive offset as %2B02:00 (or use Z for UTC), for example filter[latest_message_after]=2026-10-01T00:00:00%2B02:00.

Message identity

Observed CRM messages can have an application identity without an independently verified RFC Message-ID. In that case, message_id is an opaque integration-event:<event UUID> token and observed_event_id identifies the event. The optional rfc_message_id is omitted when unknown. Use the returned token for selection and expected_latest_message_id; do not construct email headers from it. Replies use a verified RFC identity or a qualifying recorded ancestor in the same conversation. If neither is available, reply_context.can_reply is false and a normal reply is rejected before sending. CRM observations expose metadata in thread detail. Read the selected accepted CRM message body on demand through the content endpoint below; mailbox messages and attachments keep their existing read paths.

Reading accepted CRM message content

First retrieve thread detail. Integration messages include source_kind, source_provider, observed_event_id, observation_id, and the selected observation_revision. Their body_text is empty and their latest-message body excerpt is omitted; a subject is not a message body. Mailbox bodies are unchanged.

Call GET /api/v1/unibox/threads/{thread_id}/observed-messages/{event_id}/content?observation_id={observation_id}&observation_revision={observation_revision} with the exact selected identifiers. The response contains plain text and sanitized HTML, up to 1 MiB combined, with Cache-Control: no-store. It reads the existing connected HubSpot or Close account and does not store bodies or change reply admission. The same workspace and Unibox access preferences apply.

A missing or retracted accepted source returns 404. A changed source, revision or provider record returns 409; reload thread detail before retrying. A provider or credential failure returns a generic 503 without exposing provider errors or credentials. Body requests and source checks share an eight-second context. Existing credential refresh and token-persistence recovery can take longer. The request does not retain a database transaction during body-provider I/O. MCP clients use unibox_observed_message_content_get with OAuth read.

Sending Replies

Lead Actions

Call POST /api/v1/unibox/threads/{thread_id}/lead-action with one action: unsubscribe, blocklist_email, or blocklist_domain. Use the canonical thread UUID from the list or detail response. The API key acts in its own workspace. Unsubscribe marks the campaign lead as unsubscribed, records its activity, and blocks its email. The blocklist actions only add the email or domain to the workspace blocklist. Existing active blocks are not duplicated.

{"action":"unsubscribe"}

Forwarding a Thread

Shared Reply Snippets

GET and POST /api/v1/reply-snippets, plus PUT and DELETE /api/v1/reply-snippets/{id}, manage the same workspace library used by the Unibox and Settings. A snippet can contain plain text, sanitized HTML, or both. New API writes require the combined body fields to fit 16 KiB both before and after sanitization, within a 32 KiB JSON request; existing UI snippets may be larger. List pages omit body fields above 8 KiB and mark those entries body_omitted: true. Read a legacy body through GET /api/v1/reply-snippets/{id}/content in UTF-8 chunks, carrying the returned content hash on continuation. Your integration must resolve variables against the intended lead and mailbox before calling the reply endpoint. Creating or reading a snippet does not send mail.

Previewing a Classification Correction

Call POST /api/v1/unibox/threads/{thread_id}/classification-impact with proposed_primary_category set to positive, neutral, or negative. The response reports no_credit_impact, refund_on_approval, or charge_on_approval. This read-only preview does not submit a correction or change credits; the effect may change if the conversation or billing state changes before approval.

Rate-Limit Feedback

Reply and forward sends return HTTP 429 details when limited. Current limits are 10 sends per API key per minute, 30 sends per workspace per minute, 10 sends per sender mailbox per minute, and 1 send per thread per 30 seconds. A new email uses a Lead-wide limit of 1 send per 30 seconds across that Lead's conversations instead of the thread limit.

AI replies in Unibox

Campaign AI draft history is available through GET /api/v1/campaigns/{campaign_id}/ai-replies/drafts and the MCP tool campaign_ai_drafts_list. Both return the original generated text and its current outcome, newest first. Responses contain up to 100 drafts and a nullable next_offset; pass that value as offset to continue. A null edit_distance means the amount of editing is unknown. Deleted campaigns and deleted leads are excluded. Access is restricted to the selected workspace.

An unchanged AI draft has a moving colour edge. Editing it changes the edge to a blue glow; human writing uses a blue glow within AI replies. Restore AI draft brings back the original text. Your own text is kept when a draft becomes unavailable. Discarded, superseded or stopped drafts become ordinary replies with a notice. Sending or already sent drafts disable Send and show their progress or sender. Review the draft and its reason before sending. Failed drafts show “No draft: write your own”.

Discard draft removes the draft identity immediately, keeps your text and edits, then offers optional reason chips. A reason can be saved once. Restoring a discarded draft only copies its original text into the composer; it remains an ordinary reply until you choose Send or clear the text. To add new Cc or Bcc recipients, discard the AI draft and write your own reply. Stop AI replies on this thread shows “AI replies off for this thread”; choose Turn back on to resume. Stops apply to the conversation or the same campaign and Lead, so they can cover more than one conversation. Stopping keeps your composer text and edits. The AI draft filter offers Any, Ready to send, Needs you and Holding reply.

Preview shows the server-derived envelope and the email delivered by every surface. The server adds quoted history and the eligible product footer, without adding a second personal sign-off. An uncertain delivery says “We can't confirm this sent. It may already have gone out. Open in Unibox.” and cannot be sent again automatically.

AI drafts are sent only after a person chooses Send. Slack, Unibox, API and MCP use the same send checks. The sender comes from the thread; recipients are the Lead and the people already on the Lead’s latest message, excluding your own mailboxes, blocklisted addresses and unsubscribed people. You cannot add recipients or choose another sender for an AI draft. Two people choosing Send at once deliver at most one reply.

If AI replies are switched off, a posted card cannot send. If the Lead booked a call after the draft was created, one-click Send is refused with “Booked a call since this draft. Open in Unibox.” You can still edit and send after reviewing the booking.

In Slack, Send uses the original draft. Edit opens a plain-text editor; invalid formatting keeps the editor open with the reason. Discard requires a reason. A Slack user must match a current workspace member allowed to send; other users see “Ask an approver.” A successful send updates the card with who sent it and the time, and appears in Activity.

API callers use the existing reply endpoint with ai_reply_draft_id; MCP callers use unibox_thread_reply_send with the same field. Omit sender and recipient overrides. To send edited text, also set ai_reply_edited: true and supply body_text. The original draft remains available for comparison. AI draft sends do not accept HTML, attachments, a different parent message or an unsubscribe acknowledgement. API and MCP retain their emoji refusal; Slack and Unibox allow emoji written by a person.

Why you wrote it this way is an optional note that helps future drafts. It is saved with the reply, separately from the email body.

Drafts use plain text and plain links. Unibox flags formatting, literal codes, corrupted characters, control characters and unfilled placeholders as you type. Human edits may include emoji.