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
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);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