Skip to main content

Ingest a forwarded outreach message

POST /api/v1/sites/{siteId}/outreach/inbox/messages Push a forwarded-email-style message into the Outreach Agent’s inbox. This produces the exact same behavior as if a team member had forwarded a collab pitch to forward+<token>@<MAILGUN_DOMAIN>: Sight AI persists the inbound message, optionally runs the LLM extractor to pull out structured opportunities, creates a conversation, and dispatches the Outreach Agent to triage and reply. Use this endpoint when your platform receives a collab pitch (or has a lead) and you want the Sight AI Outreach Agent to handle it end-to-end — triage, draft a reply, send it, and track the response.

Required headers

Request body

Response

201 Created (fresh ingestion)

When the agent is paused for this conversation (noreply sender, agent inactive, or auto-reply disabled), the response is still 201 but with aiPaused: true and a skipReason:

200 OK (idempotent replay)

Same body as the original 201 response, returned when the same Idempotency-Key is reused within the 24h retention window.

Error responses

runExtraction behavior

When runExtraction: true (the default):
  • Sight AI runs a Claude Haiku call on the body to extract structured opportunities (target URL, anchor, suggested sentence, source URL).
  • The billing gate runs first — the team must have a healthy subscription and the site must be licensed. A 402 response means the gate denied.
  • The per-site daily extraction cap (default 100/day) applies. When over cap, the message is stored without extraction and the agent triages via the reply handler.
When runExtraction: false:
  • No LLM cost. The message is stored as direct_inbound_external and the agent triages it via the reply handler’s own LLM call (which has its own gate).
  • Use this when your platform has already parsed the pitch into structured fields and you want the agent to “just handle it” without re-parsing.

Side effects

A successful call creates:
  • One ai_visibility_outreach_opportunities row per extracted ask (or one stub row when no ask is extracted).
  • One outreach_conversations row per opportunity.
  • One outreach_messages row (direction: inbound, sender_type: recipient).
  • An outreach/reply.received Inngest event (when the conversation isn’t ai_paused), which triggers the agent to triage + reply.
When outbound webhooks are enabled for the site, Sight AI also emits outreach.opportunity_created and outreach.message_received events to active subscribers. See Webhooks.

Idempotency

Send an Idempotency-Key header to safely retry a failed request without creating duplicate conversations. The key can be any opaque string up to 128 characters (alphanumeric, ., _, -, :, .).
  • First request with a given key: runs the ingestion pipeline, returns 201, caches the result.
  • Repeat request with the same key within 24h: returns the cached response with 200 (no re-ingestion).
  • The key is scoped to your API key — two different API keys can use the same key value independently.
If you omit the header, every call is treated as a fresh ingestion. Only omit it when you genuinely want a new conversation; always send it when retrying a failed or timed-out request.

Example: push a forwarded collab pitch

Rate limits

Inherits the standard write rate tier (60 requests/minute per team). A per-site daily ingestion cap (default 500/day) also applies — see Rate Limits.
The Outreach Agent must be active for the site (Inbox → Settings) and the site must have a verified sending domain for the agent to auto-reply. When the agent is inactive, messages still land in the inbox but the agent won’t reply until the user turns it on.