API · webhooks

Mama events, pushed to your endpoint in real time.

Subscribe an HTTPS endpoint to events from your Mama workspace. JSON payload, HMAC-signed with a per-subscription secret, retried on 5xx. Same pattern as the status webhooks, scoped to your account.

Available events

brief.created
A new account brief has been generated.
brief.updated
An existing brief was regenerated (signal change, ICP rule change).
brief.shared
A teammate or guest opened the brief URL.
signal.fired
A strong signal landed on a tracked account.
signal.decayed
A previously-active signal dropped below the strength threshold.
opener.generated
Mama drafted a new opener for a brief.
reply.classified
An inbound reply was classified by the reply-loop (positive / not-now / wrong-person / never).
account.scored
An account's ICP score changed by ≥10 points in a single run.
export.completed
A bulk export (CSV / Snowflake push / etc.) finished.

Subscribe

curl -X POST https://api.signalmama.com/v1/webhooks \
  -H "Authorization: Bearer $MAMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.your-domain.com/mama",
    "events": ["signal.fired", "opener.generated", "reply.classified"]
  }'

Response includes a signing_secret. Store it — every delivery is HMAC-signed with it.

Sample payload — signal.fired

{
  "event": "signal.fired",
  "event_id": "evt_01J5XKQ9Y8M0N3R7W2P4VBHTZ8",
  "delivered_at": "2026-05-25T14:12:38Z",
  "workspace_id": "ws_outbound_na",
  "signal": {
    "id": "sig_2026_05_25_acme_funding_series_b",
    "type": "funding",
    "subtype": "series-b",
    "strength": 5,
    "recency_days": 2,
    "source_url": "https://techcrunch.com/...",
    "fired_at": "2026-05-25T14:12:00Z"
  },
  "account": {
    "id": "acc_acme_co",
    "domain": "acme.co",
    "name": "Acme Co",
    "icp_score_before": 64,
    "icp_score_after": 81
  },
  "brief_url": "https://app.signalmama.com/brief/acme.co"
}

Verify the signature

// X-Mama-Signature: sha256=<hex>
const sig = req.headers['x-mama-signature'].slice(7);
const expected = crypto.createHmac('sha256', SIGNING_SECRET)
  .update(req.rawBody)
  .digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
  return res.status(401).end();
}

Retry behavior + limits

2xx within 10s = delivered. 5xx (or timeout) retries at 1m, 5m, 25m, 2h, 12h. 4xx is treated as permanent rejection. Max 50 subscriptions per workspace; max 1,000 events per minute per subscription before throttling kicks in.

Related

API overview → Docs · API overview → Docs · endpoints →