Skip to content
Developers

anicall.io API v2 and MCP server

The anicall.io REST API v2 at https://api.anicall.io/api/v2 controls agents, knowledge base, calls and dial jobs; signed webhooks report events, and the MCP server at https://api.anicall.io/mcp makes everything usable for AI agents such as Claude.

More about anicall.io

Last updated: November 2026

At a glance

Authentication
Authorization: Bearer anc_live_…

Authentication

Every request to API v2 and the MCP server carries a key in the header Authorization: Bearer anc_live_….

Create keys in the dashboard under Settings → Integrations. anicall only stores a SHA-256 hash; you see the plain key once when you create it. Field names are camelCase, errors are returned as JSON {"error": "…", "message": "…"}.

curl https://api.anicall.io/api/v2/agents \
  -H "Authorization: Bearer anc_live_…"

Scopes

Every key only gets the scopes you grant; approving dial jobs (dial_jobs:approve) is a separate scope.

ScopeMeaning
agents:readRead agents and their configuration
agents:writeConfigure agents (knowledge boundary, calendar, active status)
knowledge:readRead knowledge sources, knowledge gaps and knowledge search
knowledge:writeCreate knowledge sources, approve answers
calls:readRead calls, transcripts and outcomes
calls:writeStart single outbound calls
dial_jobs:writeCreate and pause dial jobs
dial_jobs:approveApprove dial jobs (the human in the approval gate)
phone_numbers:readRead phone numbers
phone_numbers:writeAssign phone numbers to agents
calendars:readRead calendar connections
calendars:writeConnect calendars (Calendly)
stats:readRead stats
webhooks:manageManage webhook subscriptions

Endpoints

API v2 has endpoints for account, agents, knowledge base, knowledge gaps, phone numbers, calendars, calls, dial jobs, stats and webhooks.

MethodPathScopeMeaning
GET/api/v2/meagents:readAccount, plan, available scopes and event types
GET/api/v2/agentsagents:readList agents
GET/api/v2/agents/{agentId}agents:readGet an agent
PATCH/api/v2/agents/{agentId}agents:writeConfigure an agent: knowledge boundary, calendar, active status
GET/api/v2/agents/{agentId}/knowledgeknowledge:readAn agent's knowledge sources
POST/api/v2/agents/{agentId}/knowledgeknowledge:writeAdd a knowledge source (e.g. website)
POST/api/v2/agents/{agentId}/knowledge/searchknowledge:readSearch the knowledge base
GET/api/v2/agents/{agentId}/knowledge-gapsknowledge:readOpen knowledge gaps
POST/api/v2/agents/{agentId}/knowledge-gaps/{gapId}/answerknowledge:writeAnswer a knowledge gap (goes into the answer catalog)
POST/api/v2/agents/{agentId}/knowledge-gaps/{gapId}/dismissknowledge:writeDismiss a knowledge gap
POST/api/v2/agents/{agentId}/answersknowledge:writeAdd an answer directly to the answer catalog
GET/api/v2/phone-numbersphone_numbers:readList phone numbers
PATCH/api/v2/phone-numbers/{numberId}phone_numbers:writeAssign a phone number to an agent
GET/api/v2/calendarscalendars:readList calendar connections
POST/api/v2/calendars/calendlycalendars:writeConnect Calendly
GET/api/v2/callscalls:readCalls with outcome and review
GET/api/v2/calls/{callId}calls:readA call with transcript and summary
POST/api/v2/callscalls:writeStart a single call (contact basis required)
POST/api/v2/dial-jobsdial_jobs:writeCreate a dial job (waits for approval)
GET/api/v2/dial-jobs/{jobId}dial_jobs:writeStatus of a dial job
POST/api/v2/dial-jobs/{jobId}/approvedial_jobs:approveApprove a dial job
POST/api/v2/dial-jobs/{jobId}/pausedial_jobs:writePause a dial job
GET/api/v2/statsstats:readStats: calls, minutes, outcomes, traffic light
GET/api/v2/webhookswebhooks:manageList webhook subscriptions
POST/api/v2/webhookswebhooks:manageCreate a webhook subscription
DELETE/api/v2/webhooks/{webhookId}webhooks:manageDelete a webhook subscription
POST/api/v2/webhooks/{webhookId}/testwebhooks:manageSend a test event

Webhooks and signature

anicall signs every webhook delivery with HMAC-SHA256 over the timestamp and the raw request body.

X-Anicall-Signature: t=<unix ts>,v1=<hex HMAC-SHA256(secret, "<ts>.<body>")>

Every delivery carries the headers X-Anicall-Event, X-Anicall-Delivery and X-Anicall-Signature. Verify the signature against the raw body and reject timestamps older than 5 minutes.

If a delivery fails, anicall retries after 1, 5 and 30 minutes and after 2 and 6 hours. POST /webhooks/{id}/test sends a test event.

EventMeaning
call.startedA call has started (inbound or outbound).
call.completedA call has ended; transcript, summary and outcome are available.
call.reviewedThe knowledge boundary review is done (traffic light ok/warn/fail).
appointment.bookedThe agent booked an appointment.
callback.requestedThe caller wants a callback from a human.
knowledge.gapA factual question could not be answered from the knowledge base.
lead.updatedA lead has a new status or outcome.
lead.dncA contact objected and is now blocked.
dial_job.approval_requiredA dial job is waiting for human approval.
dial_job.completedA dial job has been fully processed.
Verify the signature (Node.js)
import crypto from 'node:crypto'

// header = X-Anicall-Signature, rawBody = unveränderter Request-Body (String)
export function verifyAnicallSignature(secret, rawBody, header, toleranceSec = 300) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
  const t = Number(parts.t)
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false
  const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex')
  const a = Buffer.from(expected)
  const b = Buffer.from(parts.v1 ?? '')
  return a.length === b.length && crypto.timingSafeEqual(a, b)
}

MCP server for AI agents

The anicall MCP server speaks Streamable HTTP (stateless) at POST https://api.anicall.io/mcp and uses the same key and scopes as API v2.

Set up in Claude Code

Add the server with your key as a header. Other MCP clients that support Streamable HTTP with an Authorization header are set up the same way.

claude mcp add --transport http anicall https://api.anicall.io/mcp \
  --header "Authorization: Bearer anc_live_…"

Tools that trigger real calls are marked as destructive. Dial jobs only start after a human runs approve_dial_job.

Tools

ToolMeaning
list_agentsList agents
get_agentAn agent's configuration
set_agent_strictnessSet an agent's knowledge boundary
search_knowledgeSearch the knowledge base
add_knowledge_sourceAdd a knowledge source
list_knowledge_gapsList knowledge gaps
answer_knowledge_gapAnswer a knowledge gap
list_callsCalls with outcome and traffic light
get_callA call with transcript and review
start_callStart a single call (destructive)
create_dial_jobCreate a dial job (destructive)
approve_dial_jobApprove a dial job (destructive)
get_dial_jobStatus of a dial job
get_statsStats

Frequently asked questions

Where can I find the OpenAPI spec?

At https://api.anicall.io/api/v2/openapi.json. It contains all API v2 endpoints and works with code generators and AI agents.

Can an AI agent start calls on its own via MCP?

Single calls only with the calls:write scope and a contact basis. Call lists are created as dial jobs; they only start once a human approves them with approve_dial_job or in the dashboard.

How do I verify that a webhook really comes from anicall?

Compute HMAC-SHA256 with your webhook secret over "<t>.<raw body>" and compare the result in constant time with v1 from the X-Anicall-Signature header. Reject timestamps older than 5 minutes.

Create your first API key

In the dashboard under Settings → Integrations – with exactly the scopes your integration needs.