API basics

The Liveleg API is a REST API at https://api.liveleg.dev/v1. Send JSON or form-encoded bodies and get JSON back. This page covers what every endpoint has in common.

Requests and responses

  • Authenticate with a Bearer API key. See Authentication.
  • IDs carry a prefix for their type: cal_ calls, dls_ dial sessions, num_ numbers, agt_ agents.
  • Phone numbers are E.164, such as +15125550147. Times are ISO 8601 in UTC. Durations end in _ms or _seconds.
  • Amounts are strings in US dollars, such as "12.40".

Errors

Errors use standard HTTP status codes. The body has a machine-readable code and a message for people. When a compliance check stops a request, rule names the check and next_allowed_at says when the lead can be called. Quote request_id when you contact us.

Response
{
  "error": {
    "code": "blocked_by_rule",
    "message": "The lead's local time is outside calling hours.",
    "reason": "outside_calling_hours",
    "rule": "calling_hours.PA",
    "next_allowed_at": "2026-11-03T14:00:00Z",
    "request_id": "req_6tB02xQe"
  }
}
StatusCodeMeaning
400invalid_requestA parameter is missing or has the wrong format. param names it.
401invalid_api_keyThe key is missing, wrong or revoked.
403insufficient_scopeThe key is valid but its scopes do not allow the request.
404not_foundThe object does not exist in this account.
409idempotency_conflictThe Idempotency-Key was used with a different request body.
422blocked_by_ruleA compliance check stopped the request. rule names the check.
500, 503server_errorOur side failed. Retry with the same Idempotency-Key.

Idempotency

Send an Idempotency-Key header on any POST. If you retry with the same key within 24 hours, you get the first response back and nothing runs twice. A retry after a timeout with the same key does not place a second call. Use a value tied to the action, such as your CRM ID plus an attempt number. The same key with a different body returns 409.

POST/v1/calls
curl https://api.liveleg.dev/v1/calls \
  -H "Authorization: Bearer $LIVELEG_API_KEY" \
  -H "Idempotency-Key: crm-88213-call-3" \
  -d to=+15125550147 \
  -d caller_id_pool=pool_local_presence \
  -d agent_id=agt_114

Pagination

List endpoints return the newest objects first. Set limit from 1 to 100 (default 20). To get the next page, pass the last ID you received as starting_after. Stop when has_more is false.

GET/v1/call_records
curl "https://api.liveleg.dev/v1/call_records?limit=100&starting_after=cal_8Jq2mT4x" \
  -H "Authorization: Bearer $LIVELEG_API_KEY"
Response
{
  "object": "list",
  "data": [
    {"id": "cal_7Hd1aP2c", "object": "call", "status": "completed"}
  ],
  "has_more": true
}

Versioning

The version is in the path. Within v1 we add new endpoints, fields and event types without notice. Your code should ignore fields it does not know. Removing or renaming anything needs a new version, and the old one keeps working for at least 12 months after the new one ships.

Test mode

Requests made with a test key run the same validation and compliance checks as live ones, and place no calls. Dial sessions simulate answers, machines and no-answers and send the same events, with livemode false. Test objects are kept apart from live ones and cost nothing.