Developer docs
Place AI phone calls and collect their results from your own code or an AI agent. Two surfaces, one set of capabilities: a REST API and a remote MCP server. Calls draw from your account's credit balance.
Authentication
Create a key in Developers → API keys (shown once). Send it as a bearer token on every request. Keys carry scopes: calls:write, calls:read, campaigns:write, billing:read.
Authorization: Bearer cai_live_xxxxxxxxxxxxxxxxxxxxxxxxBase URL: /api/v1 · OpenAPI: /api/v1/openapi.json
Quickstart — place a call
One request creates everything and dials. Poll the returned call until isComplete is true.
# 1. Place the call
curl -X POST https://app.asklucien.com/api/v1/calls \
-H "Authorization: Bearer $LUCIEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+33185094454",
"language": "fr",
"objective": "book a table for 2 tonight at 8pm",
"collect": ["confirmation", "deposit required?"]
}'
# → { "id": "call_…", "status": "dialing", "isComplete": false, ... }
# 2. Poll for the result
curl https://app.asklucien.com/api/v1/calls/call_… \
-H "Authorization: Bearer $LUCIEN_API_KEY"
# → { "status": "completed", "outcome": "success",
# "summary": "...", "collected": { "confirmation": "..." },
# "priceUsd": 0.15, "isComplete": true }Endpoints
| Method & path | Description |
|---|---|
| POST /calls | Place a single call |
| GET /calls | List your calls (filter by requestId, status) |
| GET /calls/{id} | Get a call's status + result |
| POST /calls/{id}/refresh | Force-pull the latest result |
| POST /calls/{id}/cancel | Hang up a live call |
| GET /calls/{id}/transcript | Transcript (?translate=<lang>) |
| GET /calls/{id}/recording | Stream the recording (audio/mpeg) |
| POST /campaigns | Start a discovery campaign |
| GET /campaigns/{id} | Campaign progress + ranked results |
| GET /balance | Spendable credit + per-call estimate |
Discovery campaigns
Find businesses and call several of them for one objective. Calls are paced automatically; poll the campaign for the AI-ranked summary.
curl -X POST https://app.asklucien.com/api/v1/campaigns \
-H "Authorization: Bearer $LUCIEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "query": "flower shops in Mykonos",
"objective": "cheapest price for a dozen red roses",
"maxTargets": 5 }'
# Then poll GET /campaigns/{id} → { "isComplete": true,
# "headline": "…", "results": [ { "businessName": "…", "value": "4 €/rose" } ] }Webhooks
Instead of polling, register an endpoint in Developers → Webhooks. We POST a signed JSON body on call.completed, call.failed and campaign.completed. Verify the X-Lucien-Signature header (HMAC-SHA256 of the raw body with your endpoint secret) and dedupe on X-Lucien-Delivery.
// Express receiver — verify the signature
import crypto from "node:crypto"
app.post("/hooks/lucien", express.raw({ type: "*/*" }), (req, res) => {
const sig = req.header("X-Lucien-Signature") || ""
const expected = "sha256=" + crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(req.body) // the raw bytes
.digest("hex")
if (sig !== expected) return res.status(400).end()
const { event, data } = JSON.parse(req.body.toString())
// event: "call.completed" | "call.failed" | "campaign.completed"
// data: the same shape as GET /calls/{id} or /campaigns/{id}
res.status(200).end()
})MCP server
Connect an AI client (Claude Desktop/Code, Cursor, …) to the remote MCP server. Same API key, same capabilities as tools: place_call, start_discovery_campaign, get_call, get_campaign, list_calls, get_transcript, cancel_call, get_balance.
{
"mcpServers": {
"lucien": {
"url": "https://app.asklucien.com/api/mcp",
"headers": { "Authorization": "Bearer cai_live_…" }
}
}
}Errors
Errors return { "error": { "code", "message" } } with a matching HTTP status. Switch on code.
| 401 | unauthenticated — missing/invalid API key |
| 402 | insufficient_credit — top up to place calls |
| 403 | forbidden_scope — key lacks the required scope |
| 404 | not_found |
| 422 | validation_error — body/query failed the schema |
| 429 | rate_limited |
| 502 | dial_failed — both voice providers failed |
| 503 | no_voice_provider |
Create an API key to get started.
