Documentation

Calls & Playbook

Configure the AI coach that listens on live sales calls, and pull back the call history it produced — over both REST and MCP.

Two surfaces share the same data. The Sales Playbook drives what the live-call coach knows: a base coaching prompt, a set of call types (each with its own script, checklist, and prompt additions), and reference documents. The Call History surface is read-only recall of completed calls — transcript, checklist coverage, sentiment, lead verdict, and drafted emails.

One playbook per organization

Each organization has exactly one playbook. GET /api/v1/playbook creates it on first access, so there is no "create playbook" call — you read it, then edit its parts.

Authentication

REST endpoints accept an API key as a bearer token: Authorization: Bearer avs_YOUR_API_KEY. The same key authorizes the MCP server, where tenant scope comes from the connected agent's context. See Authentication for how to obtain a key.

Writes return 200, not 201

Every successful REST response — including create and delete — returns HTTP 200 with the envelope { "success": true, "data": ... }. There is no 201 Created.

REST — Playbook Configuration

Base path /api/v1/playbook. All numeric IDs are integers.

Method Endpoint Description
GET /api/v1/playbook Get the full playbook (prompt, call types, documents)
PUT /api/v1/playbook/coaching-prompt Replace the base coaching prompt
GET /api/v1/playbook/call-types List all call types
GET /api/v1/playbook/call-types/{id} Get one call type
POST /api/v1/playbook/call-types Create a call type
PUT /api/v1/playbook/call-types/{id} Replace a call type
DELETE /api/v1/playbook/call-types/{id} Delete a call type
GET /api/v1/playbook/documents List reference documents
GET /api/v1/playbook/documents/{id} Get one document
POST /api/v1/playbook/documents Create a document
PUT /api/v1/playbook/documents/{id} Replace a document
DELETE /api/v1/playbook/documents/{id} Delete a document

GET /api/v1/playbook

Returns the whole playbook. The appliesTo value is one of Phone, Video, or Both.

{
    "success": true,
    "data": {
        "id": 1,
        "baseCoachingPrompt": "You are a discovery-call coach. Keep the rep curious...",
        "callTypes": [
            {
                "id": 4,
                "name": "Discovery Call",
                "appliesTo": "Phone",
                "isDefault": true,
                "isActive": true,
                "promptAdditions": "Probe for budget authority before pitching.",
                "endGoal": "Book a 30-minute discovery demo",
                "callScript": "Open with the referral source, then ask...",
                "checklist": [
                    { "text": "Confirmed decision maker", "coverageHint": "Ask who signs off" },
                    { "text": "Identified pain point", "coverageHint": null }
                ]
            }
        ],
        "documents": [
            { "id": 2, "title": "Objection Handling", "content": "When they say it's too expensive..." }
        ],
        "updatedAt": "2026-06-18T14:22:05Z"
    },
    "timestamp": "2026-06-18T14:30:00Z"
}

PUT /api/v1/playbook/coaching-prompt

Replaces the base prompt. Call types and documents are preserved.

Request body

{
    "baseCoachingPrompt": "You are a discovery-call coach. Keep the rep curious..."
}

POST /api/v1/playbook/call-types

Creates a call type. appliesTo defaults to Phone; isActive defaults to true. endGoal is optional — the outcome this call drives toward, which the live AI coach steers every suggestion toward. Each checklist item has a text and an optional coverageHint.

Request body

{
    "name": "Discovery Call",
    "appliesTo": "Phone",
    "isDefault": true,
    "isActive": true,
    "promptAdditions": "Probe for budget authority before pitching.",
    "endGoal": "Book a 30-minute discovery demo",
    "callScript": "Open with the referral source, then ask...",
    "checklist": [
        { "text": "Confirmed decision maker", "coverageHint": "Ask who signs off" }
    ]
}

The response wraps the created call type (with its new id) in the standard envelope.

DELETE /api/v1/playbook/call-types/{id}

{
    "success": true,
    "data": { "id": 4, "deleted": true },
    "timestamp": "2026-06-18T14:30:00Z"
}

REST — Call History (read-only)

Base path /api/v1/calls. Recall only — billing and internal fields are never returned (see the callout below).

Method Endpoint Description
GET /api/v1/calls List or search calls; with recent, returns the last N
GET /api/v1/calls/{id} Get one call with transcript, checklist results, sentiment, lead verdict, and emails

Query parameters for /api/v1/calls

Param Type Description
outcome string Filter by outcome label (e.g. Interested, NotNow, NoAnswer)
from ISO-8601 Start of the date window (inclusive)
to ISO-8601 End of the date window (inclusive)
search string Free-text across contact, company, outcome, and notes
recent integer Return the N most-recent calls with no aggregate totals

The filtered list adds totalHours and totalCredits aggregates; the recent list omits them.

{
    "success": true,
    "data": {
        "count": 2,
        "totalHours": 0.85,
        "totalCredits": 51,
        "calls": [
            {
                "id": 318,
                "source": "Browser",
                "callTypeId": 4,
                "status": "Completed",
                "startedAt": "2026-06-18T13:02:11Z",
                "endedAt": "2026-06-18T13:23:48Z",
                "durationSeconds": 1297,
                "fromNumber": "+15125551212",
                "toNumber": "+16317454144",
                "contactName": "Dana Reyes",
                "companyName": "Northside Integrators",
                "outcome": "Interested",
                "coverageCovered": 5,
                "coverageTotal": 6
            }
        ]
    },
    "timestamp": "2026-06-18T14:30:00Z"
}

GET /api/v1/calls/{id} returns the same fields plus summary, nextSteps, and the parsed JSON columns transcript, checklistResults, sentiment, leadVerdict, and emails.

Billing fields are never exposed

Call recall uses a strict allow-list. Credits used, credits settled, the Twilio call SID, the internal user ID, and lead linkage are never present in any response — by design, not by omission.

MCP Tools

The same configuration and recall are available to AI agents as MCP tools. Tool inputs and outputs use snake_case. Connect the MCP server as described in MCP Server.

Playbook configuration tools

Tool Key parameters Description
get_sales_playbook Full playbook: prompt, call types, documents
update_coaching_prompt base_coaching_prompt Replace the base coaching prompt
list_call_types List all call types
get_call_type call_type_id Get one call type
create_call_type name, applies_to, is_default, is_active, prompt_additions, end_goal, call_script, checklist_json Create a call type
update_call_type call_type_id + any field to change Partial update; omitted fields are unchanged
delete_call_type call_type_id Delete a call type
list_playbook_documents List reference documents
get_playbook_document document_id Get one document
create_playbook_document title, content Create a document
update_playbook_document document_id, title, content Partial update; omitted fields are unchanged
delete_playbook_document document_id Delete a document

Call recall tools

Tool Key parameters Description
list_calls outcome, from, to, search, recent List or search calls; recent returns the last N with no aggregates
get_call call_id Full call detail including transcript and analysis columns

The optional end_goal parameter sets the outcome the call drives toward; the live AI coach steers every suggestion toward it. The checklist_json parameter takes a raw JSON array. Note the casing asymmetry: input items use coverageHint, while tool output renders it as coverage_hint.

{
    "id": 4,
    "name": "Discovery Call",
    "applies_to": "Phone",
    "is_default": true,
    "is_active": true,
    "prompt_additions": "Probe for budget authority before pitching.",
    "end_goal": "Book a 30-minute discovery demo",
    "call_script": "Open with the referral source, then ask...",
    "checklist": [
        { "text": "Confirmed decision maker", "coverage_hint": "Ask who signs off" }
    ]
}

Recall tools return snake_case fields. A list_calls item:

{
    "count": 1,
    "calls": [
        {
            "id": 318,
            "source": "Browser",
            "call_type_id": 4,
            "status": "Completed",
            "started_at": "2026-06-18T13:02:11Z",
            "ended_at": "2026-06-18T13:23:48Z",
            "duration_seconds": 1297,
            "from_number": "+15125551212",
            "to_number": "+16317454144",
            "contact_name": "Dana Reyes",
            "company_name": "Northside Integrators",
            "outcome": "Interested",
            "coverage_covered": 5,
            "coverage_total": 6
        }
    ]
}

MCP errors are flat: { "error": "not_found" } for a missing ID, and { "error": "invalid", "message": "..." } for a bad value. Deletes return { "success": true, "id": 4, "deleted": true }.

Error codes (REST)

Status Code Meaning
400 INVALID appliesTo or checklist value could not be parsed
400 INVALID_TENANT The request had no resolvable organization context
404 NOT_FOUND The call type, document, or call ID does not exist for this organization
500 INTERNAL_ERROR Unexpected server error