Misar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisar PlatformMisar IdentityMisar Posts API
Api Reference

Autopilot API

Launch goal-driven outreach runs, read live progress, and pull full per-recipient delivery results — api.misar.io/reach/api/autopilot.

Autopilot turns a plain-language goal into a complete outreach run: it finds matching leads, drafts a campaign, queues the sends, and reports delivery as it happens. Queued sends are flushed by the campaign dispatcher, and delivery/open/click/bounce events flow back from MisarMail to the mail-events webhook.

Base URL: https://api.misar.io/reach

Start a run

POST/api/autopilot/start

Starts a new Autopilot run from a goal description. Costs 1 autopilot credit. Returns immediately with a runId; the run executes asynchronously — poll run status or read run detail for progress.

Body parameters

goalstringrequired

Plain-language description of the outreach goal (10–2000 chars), e.g. "Find SaaS founders in India and invite them to a demo of our analytics product."

curl -X POST "https://api.misar.io/reach/api/autopilot/start" \
  -H "Authorization: Bearer msr_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "goal": "Find SaaS founders in India and invite them to a demo" }'
{ "ok": true, "runId": "uuid" }
{ "error": "Autopilot credit limit reached" }

List runs

GET/api/autopilot/runs

Returns the authenticated user's Autopilot runs, most recent first. Counters (messages_sent, replies_count) are derived live from the underlying sends, not a cached guess.

Response fields

runs[].statusstring

One of "running" | "completed" | "failed" | "paused" | "stopped". A run stays running until every queued send has been dispatched.

runs[].leads_foundnumber

Leads matched and queued for this run.

runs[].messages_sentnumber

Sends that reached sent or beyond (sent|delivered|opened|clicked|replied) — never counts still-queued rows.

runs[].deals_countnumber

Always 0 for now — there is no CRM-deal linkage from Autopilot yet.

curl "https://api.misar.io/reach/api/autopilot/runs" \
  -H "Authorization: Bearer msr_your_key_here"
{
  "runs": [
    {
      "id": "uuid",
      "goal": "Find SaaS founders in India and invite them to a demo",
      "status": "running",
      "leads_found": 87,
      "messages_sent": 41,
      "replies_count": 0,
      "deals_count": 0,
      "campaign_id": "uuid",
      "error": null,
      "created_at": "2026-06-15T09:00:00Z"
    }
  ]
}

Get run status

GET/api/autopilot/:id/status

Lightweight polling endpoint for an in-progress run — returns the run record including its live log array. Use this while a run is running; switch to run detail for the full results view.

curl "https://api.misar.io/reach/api/autopilot/RUN_ID/status" \
  -H "Authorization: Bearer msr_your_key_here"
{
  "run": {
    "id": "uuid",
    "status": "running",
    "leads_found": 87,
    "messages_sent": 41,
    "log": ["Plan ready — audience: SaaS founders", "87 leads queued for sending"]
  }
}

Stop a run

POST/api/autopilot/:id/status

Stops a running run. Already-dispatched sends are not recalled; remaining queued sends will not be sent.

actionstringrequired

Must be "stop".

curl -X POST "https://api.misar.io/reach/api/autopilot/RUN_ID/status" \
  -H "Authorization: Bearer msr_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "action": "stop" }'
{ "ok": true }

Get run detail

GET/api/autopilot/:id

Full results for one run: the run record, the AI-drafted campaign plan, the aggregate delivery funnel, and a paginated per-recipient list joined from the run's sends.

Query parameters

pagenumberquerydefault: 1

Page of recipients to return.

limitnumberquerydefault: 50

Recipients per page.

Response fields

planobject

The campaign plan: subject_line, message_body, target_audience, industry, pain_point, keywords. May be null.

statsobject

Aggregate funnel: total, queued, sent, delivered, opened, clicked, replied, bounced, failed, skipped.

recipients[]object

Per-recipient rows: id, email, name, status, sent_at, last_event_at, error.

curl "https://api.misar.io/reach/api/autopilot/RUN_ID?page=1&limit=50" \
  -H "Authorization: Bearer msr_your_key_here"
{
  "ok": true,
  "run": { "id": "uuid", "status": "completed", "leads_found": 87 },
  "plan": {
    "subject_line": "Quick idea for your team",
    "message_body": "Hi {{first_name}}, …",
    "target_audience": "SaaS founders in India"
  },
  "stats": {
    "total": 87, "queued": 0, "sent": 87, "delivered": 80,
    "opened": 0, "clicked": 12, "replied": 0, "bounced": 7, "failed": 0, "skipped": 0
  },
  "recipients": [
    {
      "id": "uuid",
      "email": "[email protected]",
      "name": "Priya Sharma",
      "status": "delivered",
      "sent_at": "2026-06-15T09:02:00Z",
      "last_event_at": "2026-06-15T09:03:11Z",
      "error": null
    }
  ],
  "pagination": { "page": 1, "limit": 50, "total": 87, "totalPages": 2 }
}
{ "error": "Run not found" }

Inbox-vs-spam placement is not tracked. MisarMail/Postal report delivery, opens, clicks, and bounces — not whether a message landed in the inbox or the spam folder. Open tracking additionally depends on the recipient loading images, and replied/deals_count stay 0 until a reply or CRM signal exists.

Dispatch & delivery

Autopilot only queues sends. A dispatcher flushes the queue to MisarMail:

POST/api/campaigns/run

Dispatches due queued email sends for running campaigns via the MisarMail send API. Authenticated by the x-cron-secret header matching the CRON_SECRET env var (fail-closed: if CRON_SECRET is unset the endpoint is disabled). Intended to be driven by a scheduled task every ~2–3 minutes.

curl -fsS -X POST "https://reach.misar.io/api/campaigns/run" \
  -H "x-cron-secret: $CRON_SECRET"
{ "processed": 41, "sent": 41, "failed": 0, "skipped": 0 }

Delivery-events webhook

MisarMail forwards Postal delivery events for reach-originated sends to MisarReach, which advances each recipient's status. This is an internal service-to-service contract — not a public, user-callable endpoint.

POST/api/webhooks/mail-events

Receives a single delivery event from MisarMail and advances the matching send. Status transitions are monotonic — an out-of-order or replayed event never regresses a more-advanced status, so the endpoint is idempotent without a dedup store.

Authentication. HMAC-signed, not API-key authed. The header x-reach-signature must equal hex(HMAC-SHA256(rawBody, REACH_EVENTS_WEBHOOK_SECRET)), where the secret is shared with MisarMail.

Body parameters

reach_send_idstringrequired

The reach_campaign_sends row id this event applies to.

eventstringrequired

One of "sent" | "delivered" | "clicked" | "bounced" (mapped from the Postal event by MisarMail).

recipientstring

Recipient email address.

message_idstring

Postal message id, for tracing.

curl -X POST "https://reach.misar.io/api/webhooks/mail-events" \
  -H "Content-Type: application/json" \
  -H "x-reach-signature: <hex hmac-sha256 of body>" \
  -d '{ "reach_send_id": "uuid", "event": "delivered", "recipient": "[email protected]" }'
{ "ok": true, "matched": true, "status": "delivered" }
{ "ok": true, "matched": false }
{ "error": "Invalid signature" }