Developers

Everything the Console does, over the API.

Fourteen endpoints cover dialling, transfers, transcripts, agent versions, rehearsals, webhooks, usage and the audit chain. Nothing is Console-only, and nothing is hidden behind a partner tier.

▪ API version v1, backwards-compatible since launch ▪ HMAC-signed webhooks, replayable for 7 days ▪ Sandbox workspace with no dialling cost
Base facts
Transport
HTTPS only, TLS 1.3, HTTP/2 supported
Auth
Bearer key per workspace, scoped per resource
Format
JSON request and response, UTF-8
Idempotency
Idempotency-Key header honoured for 24 hours
Pagination
Cursor-based, 200 records per page maximum
Support
developers contact through the demo form, same-day reply
Sandbox workspaces carry the same scopes and the same audit chain as production.
Quickstart

Three blocks, and you have a call.

Place a call, receive the webhook, then move the agent definition into version control once you are happy with it. Nothing here needs an SDK.

1 — Place an outbound call

curl -X POST "${NIVAKYA_API_BASE}/v1/calls/dial" \
  -H "Authorization: Bearer ${NIVAKYA_KEY}" \
  -H "Idempotency-Key: 8f2c1a4e-b7d0-4f31-9c22-6a5e0b9b1d44" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "collections-v4@2026-08-30",
    "to": "+131****4471",
    "from": "+1307****1120",
    "region": "uk-south",
    "consent": { "basis": "prior_express", "captured_at": "2026-08-30T09:12:04Z" },
    "context": { "account_ref": "AC-88213", "balance_bucket": "31-60" }
  }'

A dial request is validated against consent, regional calling windows and your suppression list before it is queued. A rejected request returns 422 with the specific rule that refused it.

2 — Receive the webhook

{
  "id": "evt_01J8QK3W7A2M4T",
  "type": "call.ended",
  "created_at": "2026-09-18T14:22:51Z",
  "workspace": "ws_helpline_retail",
  "region": "uk-south",
  "data": {
    "call_id": "call_01J8QK2R9B",
    "agent": "collections-v4",
    "agent_version": "2026-08-30",
    "started_at": "2026-09-18T14:19:07Z",
    "duration_seconds": 224,
    "outcome": "payment_promise",
    "disposition": "promise_to_pay",
    "escalated": false,
    "turns": 38,
    "chain_verdict": "intact",
    "tool_calls": [
      { "name": "verify_identity", "status": "ok" },
      { "name": "create_promise", "status": "ok", "amount": 184.0 }
    ],
    "recording": { "available": true, "retention_days": 180 },
    "consent": { "basis": "prior_express", "verified": true }
  }
}

3 — Keep the agent in version control

apiVersion: nivakya.dev/v1
kind: Agent
metadata:
  name: collections-v4
  region: uk-south
spec:
  voice:
    language: en-GB
    alternate_languages: [es-US]
    speaking_rate: 1.02
    barge_in: true
  policy:
    rule_set: lending-collections-2026-q3
    fail_mode: escalate
    max_call_minutes: 12
    required_disclosures: [P-114, P-119]
  guardrails:
    - never_quote_below_list
    - verify_identity_before_balance
    - readback_digit_by_digit
  tools:
    - name: verify_identity
      timeout_ms: 1800
    - name: create_promise
      timeout_ms: 2500
  escalation:
    triggers: [caller_asks_for_human, distress_detected, policy_unevaluable]
    warm_transfer_queue: collections-tier2
  rehearsal:
    personas: adversarial-standard
    runs: 10000
    required_pass_rate: 0.995

The same file is accepted by the CLI, by the Studio's import screen and by the API. A publish is refused unless the referenced rehearsal run passed at or above the declared rate.


REST reference

Fourteen endpoints, no surprises.

Every path is versioned under /v1. Scopes are granted per key and are listed in the Console under Developer → Keys, together with a live call counter for each key.

MethodPathPurposeRequired scope
POST/v1/calls/dialStart an outbound call against a published agent versioncalls:write
POST/v1/calls/{id}/transferWarm transfer to a human queue with context attachedcalls:write
POST/v1/calls/{id}/hangupEnd a live call and write the dispositioncalls:write
GET/v1/calls/{id}Retrieve one call record with outcome and dispositioncalls:read
GET/v1/calls/{id}/turnsPaged turn-by-turn transcript, each turn carrying its hashcalls:read
GET/v1/calls/{id}/recordingIssue a signed, time-limited link to the recordingrecordings:read
GET/v1/callsSearch calls by caller, agent version, outcome or date rangecalls:read
POST/v1/agentsCreate or update an agent version from a definitionagents:write
POST/v1/agents/{id}/publishPublish a version; requires the reviewer role as a second approveragents:write + reviewer
GET/v1/agents/{id}/versionsVersion history with rehearsal signature and pass rateagents:read
POST/v1/rehearsalsStart a simulated run against a draft versionrehearsals:write
GET/v1/rehearsals/{id}Run status, pass count and the failure list with suggested fixesrehearsals:read
GET/v1/auditQuery the audit chain by policy clause, agent or date, with a verdict per turnaudit:read
POST/v1/webhooksRegister a webhook endpoint and select its event typeswebhooks:write

Usage and billing figures are served from /v1/usage with the same key scopes as the Console's billing screen. Errors follow one shape: an error code, a human sentence, and the field or rule responsible.

Webhooks

At-least-once delivery, and a way to prove it happened.

Every event carries a monotonic id and an HMAC signature over the raw body plus a timestamp. Duplicates are expected; ordering is not guaranteed. Deduplicate on the event id and you will never double-write a CRM record.

Event types
call.startedcall.answeredcall.ended call.escalatedcall.transferredturn.completed tool.invokedtool.deniedconsent.captured optout.receivedrehearsal.completedagent.published usage.thresholdincident.opened

Fourteen types in total. A workspace subscribes per endpoint, so a CRM integration can take call outcomes while an incident channel takes only incident.opened and tool.denied.

Retry semantics
DeliveryAt least once, from the region that handled the call
Attempts10 over 24 hours: 5s, 20s, 75s, 5m, 20m, 1h, 3h, 8h, 12h, 24h
Timeout10 seconds per attempt; slower endpoints are treated as failures
SuccessAny 2xx. Bodies are ignored.
Permanent4xx other than 429 stops retries and raises an endpoint warning
ReplayDead-letter queue kept 7 days, replayable per event or in bulk
SignatureHMAC-SHA256 over timestamp plus raw body, 5-minute replay window
RotationTwo signing secrets live at once so you can rotate without downtime

If your endpoint is down for more than 24 hours, the queue stops rather than growing forever, and the backlog is replayed from the Console when you are back.


Client libraries

Six libraries, one command each.

Client libraries are generated from the same specification as this reference, versioned with the API, and shipped from our own artifact host. The Console's Developer tab prints the install command pinned to your workspace's API version, so nothing in a README can drift out of date.

TypeScript and Node

First-class async client with typed event unions and a webhook verifier. Ships as both ESM and CommonJS, no transitive dependencies.

Maintained by the runtime team. Breaking changes only on major versions.

Python

Sync and async clients, typed with dataclasses, and a rehearsal helper that streams failure lists as they finish rather than waiting for the run.

Python 3.10 and above. Ships with a sandbox mode that never dials.

Go

Small surface, context-aware, with a middleware hook for request tracing. Used internally by our own carrier edge tooling.

Go 1.22 and above. No reflection at request time.

Java

Built for the environments banks actually run: no mandatory framework, Java 17 baseline, blocking and reactive clients behind one interface.

Published with a shaded jar and a signed checksum manifest.

PHP

Aimed at the CRM plugin ecosystem. Handles signature verification and idempotent dial retries, which is where most integrations get it wrong.

PHP 8.1 and above, PSR-18 compatible.

Ruby (community)

Maintained by a partner, reviewed by us each release. Covers calls, transcripts and webhooks but not rehearsal tooling.

Community-supported; we will always fix documented protocol bugs.

The CLI. The same specification drives a command-line tool, niv, used for validating agent definitions, running a rehearsal against a local file and printing a diff between two published versions. It is the fastest path from a laptop to a signed agent version, and it requires no Console session.
Limits and quotas

Published, enforced, and adjustable on request.

Limits are per workspace unless stated otherwise. Every response carries the current window's remaining allowance in headers, and a 429 always includes a retry-after value rather than leaving you to guess.

SurfaceSustained limitBurstOn breach
Management API, all endpoints600 requests / minute1,200 for 10 seconds429 with retry-after
Call control, per workspace300 requests / minute600 for 10 seconds429, live calls unaffected
Dialling concurrencyPlan limit: 50 / 200 / custom20% over for 5 minutesQueue holds, no dropped calls
Rehearsal runs started20 / hour5 simultaneousQueued, ordered
Simulated calls per run10,000—422 at request time
Audit queries60 / minute120 for 30 seconds429, query not counted
Media link generation120 / minute—429
Webhook endpoints, per workspace25—422 on registration

Sandbox workspaces get one tenth of every limit and a hard ceiling of 200 simulated calls per run. Current p50 and p99 latency for these surfaces is on the status page.


Agent as code

Review an agent the way you review a migration.

An agent definition is a file. It diffs, it reviews, it rolls back. The example below is a real change from a collections deployment: a guardrail added after a caller disclosed a hardship situation that the previous rule set had no branch for.

--- collections-v4@2026-08-30
+++ collections-v4@2026-09-14
@@ spec.policy
   rule_set: lending-collections-2026-q3
   fail_mode: escalate
   max_call_minutes: 12
-  required_disclosures: [P-114]
+  required_disclosures: [P-114, P-119]
@@ spec.guardrails
   - never_quote_below_list
   - verify_identity_before_balance
   - readback_digit_by_digit
+  - hardship_indicator_halts_negotiation
+
@@ spec.escalation.triggers
   - caller_asks_for_human
   - distress_detected
   - policy_unevaluable
+  - hardship_disclosed
@@ spec.rehearsal
   personas: adversarial-standard
   runs: 10000
-  required_pass_rate: 0.990
+  required_pass_rate: 0.995
Why the pass rate moved at the same time. Adding a guardrail without raising the bar is how regressions slip through. The publish endpoint refuses this definition unless a rehearsal run at 99.5% or better is attached to the version hash.
Rollback is a publish. Every earlier version stays addressable, so reverting is a one-line change to the version pinned in the dial request rather than a redeploy. Live calls already in progress finish on the version they started on.
Changelog

Six releases, most recent first.

v1.42 · 14 September 2026

Audit queries accept a policy clause filter and return a verification verdict per turn. New webhook type tool.denied fires whenever the policy engine blocks a tool call, which previously only appeared in the Console.

v1.41 · 21 August 2026

Webhook delivery moved to explicit at-least-once with ten attempts over 24 hours, replacing the previous five-attempt window. Dead-letter replay added, per event or in bulk.

v1.40 · 24 July 2026

Rehearsal API v2: adversarial personas are now selectable by name, and failure lists stream as runs complete instead of arriving at the end. The v1 run endpoint still works and is marked deprecated for July 2027.

v1.39 · 9 June 2026

Call search gained outcome and agent-version filters, plus cursor pagination on the turn endpoint. Response size for a 40-turn transcript dropped by roughly 38%.

v1.38 · 11 May 2026

Added the digit-by-digit readback tool for alphanumeric fields, introduced as the fix for the postcode incident. It is now a required guardrail on any agent that captures an address.

v1.37 · 27 March 2026

Rule-set publishes are staged to 5% of traffic for ten minutes with automatic rollback on a p95 regression. The agent.published webhook now reports whether a stage was rolled back, and why.

Start

A sandbox key takes about four minutes.

Sandbox workspaces dial nothing, simulate everything, and carry the same scopes and the same audit chain as production. Ask for one and we will send it with a rehearsal run already attached.

Before you file a bug, check the status page — if a surface is degraded we already know, and the incident entry will tell you what we are doing.