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):
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/conversations' \
-H 'Authorization: Bearer YOUR_TOKEN'{
"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:
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/conversations/{chatId}' \
-H 'Authorization: Bearer YOUR_TOKEN'{
"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)
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/conversations/{chatId}/recording' \
-H 'Authorization: Bearer YOUR_TOKEN'Used for web-chat continue-session flows. Rare in API integrations.
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?"}'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.
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?"}]}'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.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/dashboard-summary' \
-H 'Authorization: Bearer YOUR_TOKEN'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:
reviewCadence—off(default),per-call,daily,weekly. Defaultoffmeans no reviews until explicitly enabled per app.reviewModel—sonnet(default),opus,haiku
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"
}'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).
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles' \
-H 'Authorization: Bearer YOUR_TOKEN'Requires view_caller_profiles. Returns the full profile
— identity, rolling summary, traits with confidence, open issues,
complete call history references, operator notes.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}' \
-H 'Authorization: Bearer YOUR_TOKEN'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.
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"}'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.
curl -X DELETE 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}' \
-H 'Authorization: Bearer YOUR_TOKEN'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.)
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles.csv' \
-H 'Authorization: Bearer YOUR_TOKEN'Requires view_caller_profiles. Call volume, common
topics, conversion rates, average call length, etc. for one caller.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}/analytics' \
-H 'Authorization: Bearer YOUR_TOKEN'Requires view_caller_profiles. Returns only contacts
matching the target's phone within the same
{appId} — duplicates are strictly per-app.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}/duplicates' \
-H 'Authorization: Bearer YOUR_TOKEN'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.
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"]}'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=....
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/caller-profiles/{contactId}/issues' \
-H 'Authorization: Bearer YOUR_TOKEN'curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/issues' \
-H 'Authorization: Bearer YOUR_TOKEN'curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/issues.csv' \
-H 'Authorization: Bearer YOUR_TOKEN'Requires edit_caller_profiles. Update an issue's status
and notes — close it out, mark it monitoring, or add context for the
next person.
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."}'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 ofok,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.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/external-calls' \
-H 'Authorization: Bearer YOUR_TOKEN'{
"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.
curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/versions' \
-H 'Authorization: Bearer YOUR_TOKEN'curl 'https://api.everycallhandled.com/api/v1/apps/{appId}/versions/{auditTimestamp}' \
-H 'Authorization: Bearer YOUR_TOKEN'{
"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.
curl -X POST 'https://api.everycallhandled.com/api/v1/apps/{appId}/versions/{auditTimestamp}/restore' \
-H 'Authorization: Bearer YOUR_TOKEN'