Checking your session…

See What's Happening

Once your assistant is live, this chapter is where you'll spend your time: every call and chat with its transcript and summary, recordings, an AI quality reviewer, a persistent memory of who's called before, a log of every third-party call your integrations made, and a full history of every configuration change with one-call restore.

Each completed call or chat is stored with its full transcript, caller metadata, sentiment scores and analysis.

Available to any signed-in member of the account that owns the app.

Query params: limit (default 50), offset (pagination), mode. Pagination is offset-based.

Response (200):

GET/api/v1/apps/{appId}/conversations?limit=50&offset=0
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/conversations' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.
JSON
{
  "conversations": [ /* conversation rows — see Get a Single Conversation for field names */ ],
  "pagination": { "total": 248, "limit": 50, "offset": 0, "hasMore": true, "nextOffset": 50 },
  "isAdmin": false,
  "mode": "all"
}

Available to any signed-in member of the account that owns the app. Returns the full transcript + metadata:

GET/api/v1/apps/{appId}/conversations/{chatId}
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/conversations/{chatId}' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.
JSON
{
  "chatId": "call-_+447941190142_abc123",
  "source": "voice_phone",
  "contactId": "...",
  "transcript": [
    { "id": "...", "role": "ai", "message": "Hello, thank you for calling...", "createdAt": "..." },
    { "id": "...", "role": "user", "message": "Hi, I'd like to book...", "createdAt": "..." }
  ],
  "chatSummary": "...",
  "chatSentiment": "positive",
  "sentimentScore": 8,
  "durationSeconds": 145,
  "createdAt": "..."
}

Available to any signed-in member of the account that owns the app. Returns a secure, time-limited download link (15-minute expiry), or 404 if no recording exists.

Response (200): { "url": "https://...", "expiresIn": 900, "contentLength": 123456, "format": "mp3" } (plus filteredUrl when a noise-filtered version exists)

GET/api/v1/apps/{appId}/conversations/{chatId}/recording
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/conversations/{chatId}/recording' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.

Used for web-chat continue-session flows. Rare in API integrations.

POST/api/v1/apps/{appId}/conversations/{chatId}/messages
curl -X POST 'https://api.everycallhandled.com/api/v1/apps/{appId}/conversations/{chatId}/messages' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"role":"user","content":"One more thing, can we move it to 3pm?"}'
Sign in to run this against your account.

Imports historical conversations — useful when migrating from another system so your history lives in one place.

Body: { "chatId": "...", "userIdentifier": "...", "messages": [ { "role": "user"|"ai", "content": "..." } ], "source": "..." }userIdentifier and a non-empty messages[] are required.

POST/api/v1/apps/{appId}/conversations/import
curl -X POST 'https://api.everycallhandled.com/api/v1/apps/{appId}/conversations/import' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"chatId":"legacy-001","userIdentifier":"+447700900123","source":"import","messages":[{"role":"user","content":"Hi"},{"role":"ai","content":"Hello, how can I help?"}]}'
Sign in to run this against your account.

Available to any signed-in member of the account that owns the app. A per-app aggregate snapshot — daily call volume, conversion rate, dropped-call rate, abandoned/mid-drop breakdown, recent-issues count. One call instead of N queries for rendering an app overview.

GET/api/v1/apps/{appId}/dashboard-summary
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/dashboard-summary' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.

The platform can run an AI reviewer over each completed call to assess assistant quality — flagging issues with severity tags (info / warn / critical) and suggesting prompt improvements. Review cadence and model are configured per app; the review data itself is what you see in the dashboard's quality surfaces.

Requires enable_reviews.

Body:

  • reviewCadenceoff (default), per-call, daily, weekly. Default off means no reviews until explicitly enabled per app.
  • reviewModelsonnet (default), opus, haiku
PATCH/api/v1/apps/{appId}/review-settingsenable_reviews
curl -X PATCH https://api.everycallhandled.com/api/v1/apps/$APP_ID/review-settings \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "reviewCadence": "per-call",
    "reviewModel": "sonnet"
  }'
Sign in to run this against your account.

Your assistant can remember the people who contact it. When enabled, the platform builds a persistent caller profile per phone number per app: identity (name, organisation), a rolling AI-written summary refreshed each call, structured traits with confidence scores, and open issues — thread-style records that persist across calls until resolved. A returning caller gets an assistant that already knows the context.

Scope: profiles are per (appId, phoneNumber). Two callers with the same phone but different apps are distinct records. Do not assume cross-app continuity.

Requires view_caller_profiles. Query params: ?q=<substring>&limit=200&offset=0&includeArchived=false (q is a substring match across the profile; there is no dedicated phone/since filter). Returns the list of contacts (phone, name, last-called-at, callCount).

GET/api/v1/apps/{appId}/caller-profilesview_caller_profiles
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.

Requires view_caller_profiles. Returns the full profile — identity, rolling summary, traits with confidence, open issues, complete call history references, operator notes.

GET/api/v1/apps/{appId}/caller-profiles/{contactId}view_caller_profiles
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.

Requires edit_caller_profiles. Human-side updates — correct an extracted name, adjust a trait, add a note. Body shape mirrors the GET response with optional fields. AI-extracted fields can be overridden; future profile updates respect high-confidence human edits.

PUT/api/v1/apps/{appId}/caller-profiles/{contactId}edit_caller_profiles
curl -X PUT 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Jane Smith"}'
Sign in to run this against your account.

Requires delete_caller_profile (owner default). Supports GDPR Article 17: removes the profile, the caller's issue records and analytics keyed to them. Transcripts of past calls remain in your conversation records (needed for service-delivery and accounting) but their linkage to the deleted profile is severed. An audit entry records who, when, why. Irreversible.

DELETE/api/v1/apps/{appId}/caller-profiles/{contactId}delete_caller_profile
curl -X DELETE 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Copy-only. DELETE is destructive — run it from your own terminal with the sample above, not from the docs.

Requires view_caller_profiles. Bulk export across all profiles — supports GDPR Article 20 (data portability). Returns standard CSV with one row per contact + their analytics columns. Issue detail comes via the issues CSV (below). (There is no single-profile .csv endpoint — use the per-contact JSON detail route for one caller.)

GET/api/v1/apps/{appId}/caller-profiles.csvview_caller_profiles
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles.csv' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.

Requires view_caller_profiles. Call volume, common topics, conversion rates, average call length, etc. for one caller.

GET/api/v1/apps/{appId}/caller-profiles/{contactId}/analyticsview_caller_profiles
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}/analytics' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.

Requires view_caller_profiles. Returns only contacts matching the target's phone within the same {appId} — duplicates are strictly per-app.

GET/api/v1/apps/{appId}/caller-profiles/{contactId}/duplicatesview_caller_profiles
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}/duplicates' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.

Requires edit_caller_profiles. Strictly per-app: any sources[] entry whose contact belongs to a different app than the URL {appId} is refused with a per-source error in the response errors[] array (in-scope sources in the same payload still process normally). The target's own app is validated up front; a target-app mismatch returns 400 for the whole request. Cross-app merging is not performed regardless of caller role.

POST/api/v1/apps/{appId}/caller-profiles/{contactId}/mergeedit_caller_profiles
curl -X POST 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}/merge' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"sources":["contact-id-to-merge"]}'
Sign in to run this against your account.

Issues are persistent records tied to a caller; they have a status (open / monitoring / completed), kind, summary, severity, lastObservedAt, and notes. The assistant sees open issues on the next call from that number (when profile-apply is on), so "the engineer never called back" doesn't get forgotten between calls.

Requires view_caller_profiles. The app-wide /issues form returns the consolidated issues view — typically used for daily triage. Query params: ?status=open&severity=critical&since=....

GET/api/v1/apps/{appId}/caller-profiles/{contactId}/issues# per callerview_caller_profiles
GET/api/v1/apps/{appId}/issues# across all callers in the appview_caller_profiles
GET/api/v1/apps/{appId}/issues.csv?since=...&until=...# CSV export, date-filteredview_caller_profiles
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}/issues' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/issues' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/issues.csv' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.

Requires edit_caller_profiles. Update an issue's status and notes — close it out, mark it monitoring, or add context for the next person.

PUT/api/v1/apps/{appId}/issues/{issueId}edit_caller_profiles
curl -X PUT 'https://api.everycallhandled.com/api/v1/apps/{appId}/issues/{issueId}' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"status":"resolved","notes":"Resolved on callback."}'
Sign in to run this against your account.

Every outbound HTTP call your app makes to a third party during a conversation is recorded as one row in the call log — a flight recorder for the integrations wired into an app, so you can see what the app called, when, and whether it succeeded.

Requires view_call_logs.

Query params:

  • limit (default 50, max 200)
  • offset (default 0)
  • outcome — optional exact-match filter, one of ok, http_error, network_error, timeout

Rows are returned newest-first (descending timestamp).

Response (200):

Row fields:

Field Notes
timestamp ISO-8601, when the call was made
conversationId The conversation/call the request belonged to (may be empty for flow-level calls)
source What made the call — see prefixes below
url The target URL, query string and fragment stripped (query strings routinely carry API keys — secrets are never stored)
method Uppercased HTTP method
status HTTP status code; 0 means no response was received
latencyMs Round-trip time in milliseconds
outcome ok (2xx/3xx) · http_error (4xx/5xx) · network_error · timeout

What gets logged. The source field is prefixed by the kind of caller:

Source prefix What it is
tool:<toolName> A webhook tool the assistant invoked mid-conversation
pms:semble A call to the Semble integration (record lookup, booking)
booking:nylas A calendar booking call
post-call:custom-destination A post-call callback POST to a destination you configured
flow:onComplete A conversation-flow onComplete HTTP step
workflow:httpRequest An automation HTTP-request step, for chat-triggered automation runs

Reliability & retention:

  • Fire-and-forget. Log writes never block or fail a conversation. If a write is slow or errors, the call path proceeds unaffected — a missing log row never means the underlying call failed.
  • Query-stripped URLs. Only the path portion of each URL is stored (truncated at 500 chars); anything after ? or # is discarded before write, so credentials passed as query params are not retained.
  • 30-day retention. Rows are permanently deleted 30 days after their timestamp. There is no grace window — past 30 days the row is gone.
GET/api/v1/apps/{appId}/external-calls?limit=50&offset=0&outcome=http_errorview_call_logs
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/external-calls' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.
JSON
{
  "calls": [
    {
      "id": "0b6f2f0e-4c1d-4a52-9a3f-9a1b2c3d4e5f",
      "timestamp": "2026-07-11T10:32:04.512Z",
      "appId": "app-abc123",
      "conversationId": "conv_1783798947228_x1y2z3",
      "source": "tool:check_availability",
      "url": "https://api.partner.example/availability",
      "method": "POST",
      "status": 200,
      "latencyMs": 431,
      "outcome": "ok"
    }
  ],
  "total": 248,
  "limit": 50,
  "offset": 0
}

Every configuration change to an app is recorded, so you can always answer "what changed, and when?" — and undo it.

Available to any signed-in member of the account that owns the app.

List response (200):

The single-version form returns the full attribute set as it was at that point.

GET/api/v1/apps/{appId}/versions
GET/api/v1/apps/{appId}/versions/{auditTimestamp}
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/versions' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/versions/{auditTimestamp}' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.
JSON
{
  "appId": "...",
  "versions": [
    {
      "auditId": "...",
      "auditTimestamp": "2026-05-10T11:30:00.000Z",
      "userId": "...",
      "operation": "UPDATE",
      "changedConfigAttrs": ["voiceChatPrompt", "voice"]
    }
  ],
  "nextCursor": "..."
}

Requires edit_settings. Restores the app's configuration to that snapshot. Like any configuration change, the restore is a draft until you take the assistant live.


POST/api/v1/apps/{appId}/versions/{auditTimestamp}/restoreedit_settings
curl -X POST 'https://api.everycallhandled.com/api/v1/apps/{appId}/versions/{auditTimestamp}/restore' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Sign in to run this against your account.