Public API

Call Trace API Documentation

Submit call recordings from your own system, receive an immediate 202 response, and get the final transcript and evaluation through webhooks.

Create an API key

Open Admin > Integrations and create a key with the analysis:write scope.

Submit a file URL

Send an HTTPS fileUrl to POST /api/v1/analyses. The API responds with 202 Accepted.

Receive the result

Subscribe to analysis.completed and analysis.failed to get the final evaluation.

Check the secret

Compare X-CallTrace-Secret with the webhook secret you saved when creating the endpoint.

API keys

Create a token in the admin panel

Only admins can create integration API keys. Keys are scoped, can expire, can be revoked, and are independent from employee sessions.

  1. 01

    Open Integrations

    Sign in as an admin and open Admin > Integrations > API Keys.

  2. 02

    Name the key

    Use a name that identifies the external system, environment, and owner.

  3. 03

    Choose scopes

    Select only the permissions that system needs. Most upload integrations need analysis:write and analysis:read.

  4. 04

    Set lifetime

    Choose an expiration date for temporary access or leave it permanent for long-running service integrations.

  5. 05

    Copy once

    The full ct_live_ token is shown only once. After closing the panel, only the prefix remains visible.

    ct_live_••••••••

Token format

ct_live_8Lk3...full-secret-value

Store the full token in your external system secret manager. Call Trace stores only a hash and shows only the prefix after creation.

Authentication

Use a scoped integration key

Integration API keys are separate from employee sessions. Send the key in the Authorization header and grant only the scopes your system needs.

Header

Authorization: Bearer ct_live_...
Content-Type: application/json

Scopes

analysis:write creates analyses.

analysis:read reads status and results.

webhooks:write manages webhook settings.

Permissions

What each scope allows

Scopes are additive. Start with the smallest set that supports the integration and add more only when a specific endpoint requires it.

Scope
Use
Description
analysis:write
Create new analyses
Required for POST /api/v1/analyses. Allows the external system to submit a fileUrl and queue analysis.
analysis:read
Read analysis status and result
Required for GET /api/v1/analyses and GET /api/v1/analyses/{analysisId}. Use it for polling and reconciliation.
calls:read
Read call-level data
Allows access to call metadata exposed through integration-safe endpoints. Do not grant it if the integration only sends files.
storage:write
Write source files
Reserved for integrations that need direct storage upload flows. fileUrl integrations usually do not need it.
webhooks:read
Read webhook configuration and history
Allows listing webhook endpoints and delivery attempts for support or monitoring tooling.
webhooks:write
Manage webhooks
Allows creating or updating webhook endpoints. Keep it on admin/service keys, not ordinary analysis submission keys.

Recommended minimum

For the standard flow, create one token with analysis:write and analysis:read. Webhooks are configured by an admin in the UI, so the external sender usually does not need webhooks:write.

Token lifetime

Expiration, permanent access, and rotation

Each API key has its own lifetime. A token can be permanent, expire automatically, or be revoked manually.

Permanent token

expiresAt is empty. The token stays active until an admin revokes it. Use this only for trusted backend-to-backend integrations with a rotation process.

Expiring token

expiresAt is set. After that date the API returns 401 and no new requests are accepted. Use this for tests, contractors, or temporary access.

Revoked token

revokedAt is set immediately when an admin revokes the key. Revocation is instant and cannot be undone; create a new key instead.

Rotation

Create a new key, deploy it in the external system, confirm last used updates, then revoke the old key. This avoids downtime.

API reference

Create an analysis

The request stores the source file and starts background processing. Your client should not wait for transcription or evaluation to finish in this request.

Create analysis

Returns 202 Accepted and queues processing.

POST/api/v1/analyses

Request

POST /api/v1/analyses
Authorization: Bearer ct_live_...
Content-Type: application/json

{
  "fileUrl": "https://example.com/calls/call-123.mp3",
  "agentId": "6f6af4bb-4f23-4f3f-a87e-85f2f8322dc1",
  "queueId": "7a7bf5cc-5e34-4f4g-b98f-96g3g9433ed2",
  "externalId": "crm-call-123",
  "idempotencyKey": "crm-call-123",
  "metadata": {
    "customerId": "cust_42",
    "source": "crm"
  }
}

Response

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "analysisId": "6f6af4bb-4f23-4f3f-a87e-85f2f8322dc1",
  "status": "queued",
  "externalId": "crm-call-123"
}
Field
Type
Required
Description
fileUrl
string
Required
HTTPS URL of the audio file to analyze. Maximum size is 20 MB.
fileName
string
Optional
Display name in Call Trace. If omitted, the last path segment of fileUrl is used.
agentId
uuid
Required
Agent to associate with the analysis. Must exist in your company.
queueId
uuid
Required
Queue with the script used for evaluation. Must have an active script version.
language
string
Optional
Language for transcription. Defaults to auto when omitted.
externalId
string
Optional
Your CRM, helpdesk, or telephony identifier.
idempotencyKey
string
Optional
Deduplicates retries from your system.
metadata
object
Optional
Small JSON object returned in status and webhook payloads.

File URL requirements

fileUrl must use HTTPS. Private, localhost, and internal IP ranges are rejected, including redirects into private networks. Maximum file size is 20 MB. Files are downloaded with timeouts and content-type checks before processing.

API reference

Read status and results

Use this endpoint when your system needs to reconcile state or recover after missed webhook deliveries.

Get analysis

Returns the latest job status and available result fields.

GET/api/v1/analyses/{analysisId}
{
  "analysisId": "6f6af4bb-4f23-4f3f-a87e-85f2f8322dc1",
  "status": "completed",
  "externalId": "crm-call-123",
  "call": {
    "durationSeconds": 184,
    "agentId": "agent-uuid",
    "queueId": "queue-uuid"
  },
  "evaluation": {
    "score": 82,
    "summary": "The agent followed the script and resolved the main request.",
    "emotion": {
      "label": "neutral",
      "score": 55,
      "comment": "The caller stayed calm throughout the conversation."
    },
    "criteria": [
      { "name": "Greeting", "score": 10, "maxScore": 10 },
      { "name": "Need discovery", "score": 18, "maxScore": 20 }
    ]
  },
  "transcript": {
    "language": "en",
    "segments": [
      { "speaker": "agent", "text": "Good afternoon, how can I help?" }
    ]
  },
  "metadata": {
    "customerId": "cust_42"
  },
  "error": null
}
queued

The request is accepted and waiting for processing.

processing

The file is being downloaded, transcribed, and evaluated.

completed

The evaluation, transcript, and call summary are available.

failed

Processing failed after retries. Details are returned in error.

API reference

List analyses

Search by status, externalId, agent, queue, or date range. Use this for back-office reconciliation and support tooling.

List analyses

Returns paginated analyses for the integration company.

GET/api/v1/analyses
GET /api/v1/analyses?status=completed&externalId=crm-call-123
Authorization: Bearer ct_live_...

Webhooks

Webhook payload

Configure webhook endpoints in Admin > Integrations. Payloads include the information needed to store the assessment result in your own system.

analysis.createdanalysis.completedanalysis.failed
{
  "deliveryId": "whd_01jz8n0f8ck2bk0smq7h2x1t0r",
  "event": "analysis.completed",
  "occurredAt": "2026-06-19T12:00:00.000Z",
  "analysisId": "6f6af4bb-4f23-4f3f-a87e-85f2f8322dc1",
  "externalId": "crm-call-123",
  "call": {
    "status": "completed",
    "durationSeconds": 184,
    "recordingUrl": "https://storage.example.com/audio/call-123.mp3"
  },
  "evaluation": {
    "score": 82,
    "summary": "The agent followed the script and resolved the main request.",
    "emotion": {
      "label": "neutral",
      "score": 55,
      "comment": "The caller stayed calm throughout the conversation."
    },
    "criteria": [
      { "name": "Greeting", "score": 10, "maxScore": 10 }
    ]
  },
  "transcript": {
    "language": "en",
    "segments": [
      { "speaker": "agent", "text": "Good afternoon, how can I help?" }
    ]
  },
  "metadata": {
    "customerId": "cust_42"
  },
  "error": null
}

Script text is not included by default. Use deliveryId for deduplication and analysisId plus event when storing state transitions.

Webhooks

Delivery and retries

Call Trace stores every delivery attempt and retries failed deliveries so results are not lost on timeout or temporary customer outages.

Success

Any 2xx response marks the delivery as delivered.

Retry policy

Initial attempt plus 3 retries with backoff, for example 10 seconds, 1 minute, and 5 minutes.

History

Each attempt stores status, response code, error message, timestamps, and payload snapshot.

Webhooks

Webhook secret

Each webhook endpoint gets a secret. Call Trace sends it in every delivery so you can reject requests from unknown sources.

Why check the secret

Your webhook URL is reachable from the internet. Compare the X-CallTrace-Secret header with the secret you saved when creating the endpoint. If it does not match, return 401 and ignore the payload.

What arrives in each delivery

POST /your/webhook-handler

X-CallTrace-Secret: whsec_8Lk3...your-endpoint-secret

X-CallTrace-Delivery: whd_01jz8n0f8ck2bk0smq7h2x1t0r

X-CallTrace-Event: analysis.completed

X-CallTrace-Timestamp: 2026-06-19T12:00:00.000Z

{ "event": "analysis.completed", "analysisId": "6f6af4bb-..." }

X-CallTrace-Secret

The endpoint secret. Compare this value with CALL_TRACE_WEBHOOK_SECRET on your server.

X-CallTrace-Delivery

Unique delivery ID. Use it to ignore duplicate retries of the same event.

X-CallTrace-Event

Event type, for example analysis.completed.

X-CallTrace-Timestamp

When Call Trace sent the request. Useful for logging and support.

How to verify

Read X-CallTrace-Secret from the request headers and compare it with the secret shown once in Admin > Integrations when you created the webhook. Store the secret in an environment variable and reject mismatches before processing the JSON body.

Node.js example

const secret = request.headers.get("x-calltrace-secret");

if (secret !== process.env.CALL_TRACE_WEBHOOK_SECRET) {
  return new Response("Unauthorized", { status: 401 });
}

const payload = await request.json();

Examples

Create an analysis from your language

All examples use the same stable endpoint and expect the API key in CALL_TRACE_API_KEY.

const response = await fetch("https://your-domain.com/api/v1/analyses", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.CALL_TRACE_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    fileUrl: "https://example.com/calls/call-123.mp3",
    fileName: "call-123.mp3",
    language: "auto",
    externalId: "crm-call-123",
    idempotencyKey: "crm-call-123"
  })
});

const analysis = await response.json();
console.log(analysis.analysisId);

Errors

Error handling

Use idempotency keys for safe retries. Validation errors are returned synchronously. Processing errors are returned by status endpoint and analysis.failed webhooks.

400

Invalid JSON, missing fileUrl, unsupported content type, or invalid metadata.

401

Missing, expired, revoked, or malformed API key.

403

The API key does not include the required scope.

409

The same idempotency key was already used for another payload.

422

The file URL is blocked, private, not HTTPS, too large, or not reachable.

500

Temporary server error. Retry with the same idempotency key.