Three on-ramps. One credit wallet.
Ounie accounts hit the REST endpoints with a bearer key. AI assistants — including the Ounie AI Team — connect over MCP and get a native tool surface. Account-less agents can pay per call in USDC via x402 for the lead compliance scrub. Account calls draw your shared Ounie credits (1 credit = 1¢), and every dial reserves its deposit first — an agent can never overdraw.
clr_live_… key on Dashboard → API keys. It's shown once; we store only a hash. Up to 5 active keys.Authorization: Bearer clr_live_… # If your client can't set headers, the key can ride the URL: https://caller.ounie.com/api/campaigns?api_key=clr_live_…
Already have an Ounie developer key? Turn on “Use across Ounie apps” on ounie.com and your ounie_live_… master key works here too — same header, same URL form, same wallet, every Ounie app.
Authorization: Bearer clr_live_… (or ?api_key=) on any of them./api/campaigns— List campaigns{ "campaigns": [ { "id": "…", "name": "solar-follow-up", "status": "active", … } ] }/api/campaigns— Create a draft campaign{
"name": "solar-follow-up",
"brainId": "…", // the Ounie brain that grounds every answer
"businessName": "Meridian Solar",
"scriptMd": "You are calling warm leads who…",
"maxCallMinutes": 5, // optional; drives the per-call deposit
"voicemailOption": "leave_message",
"callingWindow": { "days": [1,2,3,4,5], "start": "09:00", "end": "17:00" }
}201 { "campaign": { "id": "…", "status": "draft", … } }Drafts are free. Nothing dials until you start the campaign.
/api/campaigns/{id}— Campaign detail{ "campaign": { "id": "…", "status": "paused", "pausedReason": null, … } }/api/campaigns/{id}— Edit · start · pause · archive{ "action": "start", "consentAttested": true }{ "campaign": { "status": "active", … } }
// short on credits → 402, nothing dials:
{ "error": "insufficient_credits",
"required_credits": 100,
"balance_credits": 12,
"buy_credits_url": "https://ounie.com/dashboard/settings" }Starting requires "consentAttested": true — you attest your leads consented to be called. The first-ever start charges 25 credits once; pausing and resuming is free.
/api/campaigns/{id}/leads— Upload leads (raw CSV body)Content-Type: text/csv phone,name,consent,plan +14155550123,Dana Reyes,yes,annual +13035550188,Sam Ortiz,yes,monthly
{ "imported": 2, "skipped": 0 }Send the CSV as the raw request body. phone is required; name and consent are recognized; every other column becomes a {{variable}} the script can use (e.g. {{plan}}).
/api/campaigns/{id}/calls— Call outcomes{ "calls": [ {
"id": "…", "leadPhone": "+1415555…", "status": "analyzed",
"disposition": "interested", "connectedSeconds": 187,
"summaryMd": "…", "transcript": "…", "recordingUrl": "…",
"creditsSpent": 48, "creditsReserved": 75
} ] }Reading transcripts, outcomes, and recordings is free forever.
/api/mcp (legacy SSE at /api/sse). Auth with a clr_live_… key or the Ounie master key ounie_live_….// Claude / Cursor / the AI SDK
{
"mcpServers": {
"sales-caller": {
"url": "https://caller.ounie.com/api/mcp",
"headers": { "Authorization": "Bearer clr_live_…" }
}
}
}
// Ounie AI Team (manual MCP entries can't set headers) —
// the key rides the URL instead:
https://caller.ounie.com/api/mcp?api_key=ounie_live_…| Tool | What it does |
|---|---|
| create_campaign | Create a draft campaign (name, brain, script, calling window). |
| upload_leads | Add leads to a campaign from CSV text. |
| start_campaign | Start dialing. Requires the consent attestation; charges activation once ever. |
| pause_campaign | Stop new dials. In-flight calls run to their cap. |
| list_campaigns | List your campaigns with status and counts. |
| get_campaign | One campaign's full detail. |
| list_calls | Calls for a campaign: disposition, duration, credits spent. |
| get_call | One call: transcript, summary, recording URL, exact cost. |
| get_credit_balance | Spendable Ounie credits + monthly included. |
| whoami | The authenticated key's owner + key id. |
| get_pricing | Per-action pricing + the x402 endpoint. Public — no auth required. |
Requests that would overdraw are refused with insufficient_credits and a top-up link — they never partially run.
POST https://caller.ounie.com/api/x402/scrub
{ "numbers": ["+14155550123", "+13035550188"] }
# → 402 { x402Version, accepts: [ { maxAmountRequired, payTo, asset, … } ] }
# sign the quote and retry with the header:
# X-Payment: <signed payload>
# → 200
{ "ok": true, "payment": { … },
"results": [ {
"phone": "+14155550123",
"timezone": "America/Los_Angeles",
"state": "CA",
"all_party_consent": true,
"dialable_now": false,
"window": { "start": "08:00", "end": "21:00" } // lead-local
} ] }x402 covers the scrub utility only. Placing calls is never anonymous — outbound calling requires an Ounie account and a consent attestation, so there is always a compliance chain from every dial back to an accountable caller of record.
| connected minute | 15 cr | billed in 6-second increments |
| voicemail message | 4 cr | only when a message is left |
| campaign activation | 25 cr | one-time, per campaign, on first start |
| unanswered dial | 0 cr | no answer, no charge |
Every call reserves a deposit before dialing (minute rate × the campaign's per-call cap) and refunds the unused remainder pool-exact at settle — monthly included credits go back to monthly, purchased back to purchased. In your Ounie credit ledger, talk time settles as caller_call and activation as caller_activate.
- Calling hours are enforced server-side. Dials only go out between 8am and 9pm in each lead's local timezone, derived from their number. Your campaign window can narrow that floor, never widen it — outside it, nothing dials, whatever the API asks.
- Opt-outs are permanent. When a lead asks to stop, the agent ends the call politely and the number lands in an opt-out registry that applies across all of your campaigns. It is never dialed again.
- You are the caller of record. Starting a campaign requires attesting that your leads consented to be called (
consentAttested: true). See the terms.