API
API
Back to appIntroductionAuthenticationQuickstartCore conceptsUploading callsGetting resultsWebhooksPagination and searchErrorsRate limits and billing

Quickstart

Upload your first call and read the transcript.

Upload a recording and read its transcript. You need an API key (Settings → API keys) and a project id, which you can get from the app's URL or from GET /v1/projects.

export AFTERTALK_KEY="at_live_..."
export BASE="https://app.aftertalk.co/api"

1. Upload the recording

curl -X POST "$BASE/v1/projects/$PROJECT_ID/calls/upload" \
  -H "X-API-Key: $AFTERTALK_KEY" \
  -F "file=@call.wav"
{ "jobId": "8f14e45f-ea0f-4e21-9c1a-2b3c4d5e6f70", "status": "PENDING" }

2. Wait for processing

Poll the job until it reaches a terminal state:

curl "$BASE/v1/projects/$PROJECT_ID/calls/jobs/$JOB_ID" \
  -H "X-API-Key: $AFTERTALK_KEY"
{ "jobId": "8f14e45f-...", "status": "COMPLETED", "transcriptId": "b7e2..." }

See getting results for the full status list, or webhooks to skip polling entirely.

3. Read the result

curl "$BASE/v1/projects/$PROJECT_ID/calls/$TRANSCRIPT_ID" \
  -H "X-API-Key: $AFTERTALK_KEY"

You get the transcript with speaker-attributed segments, plus whatever analysis your project has configured — summary, sentiment, category, and action items.

The same flow in code

upload.mjs
const BASE = 'https://app.aftertalk.co/api';
const headers = { 'X-API-Key': process.env.AFTERTALK_KEY };

const form = new FormData();
form.set('file', new Blob([await readFile('call.wav')]), 'call.wav');

const { jobId } = await fetch(`${BASE}/v1/projects/${projectId}/calls/upload`, {
  method: 'POST',
  headers,
  body: form,
}).then((r) => r.json());

// Poll until the job finishes.
let job;
do {
  await new Promise((r) => setTimeout(r, 5000));
  job = await fetch(`${BASE}/v1/projects/${projectId}/calls/jobs/${jobId}`, { headers }).then((r) => r.json());
} while (job.status === 'PENDING' || job.status === 'PROCESSING');

const call = await fetch(`${BASE}/v1/projects/${projectId}/calls/${job.transcriptId}`, { headers }).then((r) =>
  r.json()
);
console.log(call.summary);
upload.py
import os, time, requests

BASE = "https://app.aftertalk.co/api"
headers = {"X-API-Key": os.environ["AFTERTALK_KEY"]}

with open("call.wav", "rb") as f:
    job = requests.post(
        f"{BASE}/v1/projects/{project_id}/calls/upload",
        headers=headers,
        files={"file": f},
    ).json()

while True:
    time.sleep(5)
    status = requests.get(
        f"{BASE}/v1/projects/{project_id}/calls/jobs/{job['jobId']}", headers=headers
    ).json()
    if status["status"] not in ("PENDING", "PROCESSING"):
        break

call = requests.get(
    f"{BASE}/v1/projects/{project_id}/calls/{status['transcriptId']}", headers=headers
).json()
print(call["summary"])

Next

  • Uploading calls — formats, speaker roles, duplicate handling
  • Getting results — job statuses and partial analysis
  • Webhooks — get told when a call is ready instead of polling
  • Errors — what the status codes mean

Authentication

Organization API keys and the X-API-Key header.

Core concepts

Projects, calls, categories, templates, presets, and action items.

On this page

1. Upload the recording2. Wait for processing3. Read the resultThe same flow in codeNext