REST API for the Pro tier. GET, POST, webhooks, done.
If you want briefs, scores, and signals out of Mama and into your own pipeline — this is the surface. Standard REST, JSON in and out, API-key auth with optional HMAC signing. Webhook events for the things you'd be polling for anyway. Pro tier only; free and Team tiers use the native CRM and sequencer integrations instead.
Authentication.
Every request needs an API key in the Authorization header. Keys are workspace-scoped — one workspace, one key by default, multiple keys allowed with role-based scopes (read-only / read-write / admin).
Generating a key
Workspace settings → API keys → Create new key. Keys are shown once; copy and store somewhere you trust. Lost a key? Revoke it and generate a new one — old keys stop working within 30 seconds across all regions.
# Standard Bearer auth — works on every endpoint curl https://api.signalmama.com/v1/accounts \ -H "Authorization: Bearer sk_live_xxx" \ -H "Content-Type: application/json"
import requests resp = requests.get( "https://api.signalmama.com/v1/accounts", headers={"Authorization": f"Bearer {API_KEY}"}, ) resp.raise_for_status() accounts = resp.json()["data"]
const resp = await fetch( "https://api.signalmama.com/v1/accounts", { headers: { Authorization: `Bearer ${process.env.MAMA_KEY}` } } ); const { data } = await resp.json();
Optional: HMAC request signing
For incoming webhooks (and outbound calls if you're paranoid), pair the API key with an HMAC-SHA256 signature of the request body using a shared secret. The X-Mama-Signature header carries the digest. Reject requests whose signature doesn't match.
Rate limits.
Generous by default — most teams never see a 429. We page on our side before our customers do. Limits are per workspace, per minute, and reset on a sliding window. Every response includes the standard X-RateLimit-* headers so you can self-throttle.
POST /v1/accounts:batch callAccounts.
The core object. Each account has a score, a brief, a set of signals, and a list of contacts. CRUD is straightforward; bulk endpoints exist for ingest from a data warehouse or syncing back to a custom CRM.
Example · fetch a single account
curl https://api.signalmama.com/v1/accounts/acct_01H8X4 \
-H "Authorization: Bearer $MAMA_KEY"
acct = mama.get(f"/accounts/{acct_id}").json() print(acct["score"], acct["score_breakdown"]) # => 82, {fit: 95, recency: 78, strength: 82, depth: 68}
const acct = await mama.get(`/accounts/${id}`); console.log(acct.score, acct.score_breakdown); // => 82, { fit: 95, recency: 78, strength: 82, depth: 68 }
Briefs.
Briefs are immutable snapshots. Each time the score moves more than 10 points, Mama writes a new brief version rather than rewriting the previous one. Fetch the latest by default, or pass ?version=N for any historical snapshot.
Example · brief shape
{
"id": "brf_01H8X4ZRT9",
"account_id": "acct_01H8X4",
"version": 7,
"generated_at": "2026-05-22T14:32:08Z",
"score": 82,
"score_breakdown": {
"fit": 95,
"recency": 78,
"strength": 82,
"depth": 68
},
"why_now": "Series B announced 11 days ago…",
"who_to_talk_to": [
{ "name": "Priya Mehta", "role": "VP RevOps", "tag": "new" }
],
"draft_opener": "Saw the $45M Series B yesterday…",
"signals": ["sig_…", "sig_…", "sig_…"]
}
Signals.
Read-only — Mama detects, you consume. Filter by signal type, by account, by time window, by strength threshold. Useful for piping raw events into a data warehouse or building custom dashboards on top.
Common query params: ?type=funding,exec_move, ?since=2026-05-01, ?strength_gte=70, ?account_id=acct_….
Custom bots.
Programmatically create, list, pause, and delete your workspace's custom bots — the user-defined persistent crawlers that ride Mama's same infra as her built-in ones. Pro plan = 25 active bots; Company plan = 100. Same hard rules as the dashboard: public sources only, robots.txt respected, auto-pause after 3 consecutive failures.
Bot config shape · POST /v1/bots
{
"name": "Apollo pricing watcher",
"template": "competitor-pricing",
"source": "https://apollo.io/pricing",
"cadence": "daily",
"match_rule": {
"type": "content_diff",
"selector": ".pricing-tier"
},
"fires_signal": "competitor_price_change",
"signal_score": 25,
"alert": {
"channel": "slack",
"destination": "#competitive"
}
}
Returns the created bot with id, status: "active", and the resolved next_run_at timestamp. Bots count against your workspace's bot quota immediately on creation, even before the first crawl.
Webhooks.
For everything you'd be polling for, we'd rather push. Register an endpoint, pick the events you care about, sign every payload with an HMAC, retry with exponential back-off up to 24 hours. Six core event types so far:
Register a webhook
curl https://api.signalmama.com/v1/webhooks \ -H "Authorization: Bearer $MAMA_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.com/hooks/mama", "events": ["account.score_jumped", "brief.generated"], "secret": "whsec_yourGeneratedSecret" }'
mama.post("/webhooks", json={ "url": "https://your-app.com/hooks/mama", "events": ["account.score_jumped", "brief.generated"], "secret": "whsec_yourGeneratedSecret", })
await mama.post("/webhooks", { url: "https://your-app.com/hooks/mama", events: ["account.score_jumped", "brief.generated"], secret: "whsec_yourGeneratedSecret", });
Verifying a payload
Compute HMAC-SHA256(secret, raw_body) and compare to the X-Mama-Signature header. Constant-time compare. Reject anything that doesn't match — and include a timestamp tolerance to prevent replay. Full reference impl on every endpoint page.
SDKs & libraries.
The REST API is the source of truth. We don't ship official SDKs yet — the surface area is small enough that requests / fetch / http is fine. If demand warrants, we'll prioritize the languages with the most launch-partner usage. Status below:
| Language | Package | Status |
|---|---|---|
| Python | signalmama (official) | Coming Q3 2026 |
| TypeScript / JavaScript | @signalmama/node (official) | Coming Q4 2026 |
| Go | go-signalmama (community) | Community · maintained |
| Ruby, PHP, Java, .NET | — | No plan · raw HTTP |
| OpenAPI spec | spec.signalmama.com/v1.yaml | Live · auto-generated |
The OpenAPI 3.1 spec works in any code generator (openapi-generator, openapi-typescript, etc.) — most launch partners use that path instead of waiting on our SDKs.
Errors & conventions.
Standard HTTP status codes, JSON error bodies, idempotency keys on writes. Three conventions worth noting:
- Idempotency. Pass an
Idempotency-Keyheader on anyPOST— Mama de-dupes for 24 hours. Safe to retry on network failure. - Pagination. Cursor-based — never offset. Responses include
has_moreandnext_cursor. Pass?cursor=…on the next call. - Timestamps. Always ISO 8601 in UTC, with millisecond precision. Never relative ("3 days ago"). Never Unix integers in response bodies — only as query params.
Error bodies look like this:
{
"error": {
"type": "invalid_request",
"code": "missing_param",
"message": "`account_id` is required.",
"docs_url": "https://signalmama.com/api#accounts",
"request_id": "req_01H8X4ZRT9PQRSTU"
}
}
Always quote the request_id when emailing [email protected] — it lets us pull the exact trace from our logs in seconds.
API changelog.
We version on the path (/v1/). Within a major version, we only add — never remove or rename fields, never change response shapes in incompatible ways. Breaking changes mean a new major version (/v2/), with at least 12 months of dual-running before /v1/ sunsets.
The full API changelog lives on the main /changelog page tagged api. Subscribe via the changelog RSS to get notified on every release.
API access ships with the Pro tier. Most teams don't need it.
If our 22 native integrations cover your stack, the API isn't worth the extra cost. If you're piping briefs into a data warehouse or a custom workflow, Pro unlocks all of the above. Or get on Free first and see if the natives cover you.