Skip to main content

Calls

The calls API is the entry point of Scryon — upload an audio file, get a callId, poll for completion.

POST /api/calls/analyze

Submit a recording for analysis.

Request

Content-Type: multipart/form-data with two parts:

PartTypeRequiredNotes
fileaudio fileyes.m4a, .mp3, .wav, .aac, .ogg. Max MAX_FILE_SIZE (default 50 MB).
metadataapplication/json partyesThe envelope below.
titletext partnoConvenience for clients that don't want to build a JSON envelope.

metadata envelope

{
"title": "Quarterly review",
"contactName": "Ravi",
"contactId": "contacts:42",
"phoneNumber": "+91 98765 43210",
"organization": "Acme",
"direction": "OUTGOING",
"recordedAt": "2026-05-29T13:00:00Z",
"durationSeconds": 240
}

All fields are optional. The more you send, the better the speaker resolution.

Headers

  • Authorization: Bearer … (Firebase)
  • Idempotency-Key: … (recommended for flaky networks)
  • Content-Type: multipart/form-data; boundary=…

Response — 202 Accepted

{
"callId": "f0a1d2e3-...",
"status": "QUEUED"
}

Errors

StatuscodeCause
400validation_failedMissing file, bad metadata JSON.
401auth_invalidSee Authentication.
413payload_too_largeFile exceeds MAX_FILE_SIZE.
415unsupported_media_typeAudio MIME not recognised.

GET /api/calls

List the authenticated user's calls.

Query parameters

ParamTypeDefaultNotes
limitint50Max 100.
cursorstringFrom nextCursor on the previous page.
statusstringFilter (QUEUED, TRANSCRIBING, COMPLETED, FAILED).

Response — 200 OK

{
"items": [
{
"callId": "f0a1d2e3-...",
"title": "Quarterly review",
"contactName": "Ravi",
"direction": "OUTGOING",
"status": "COMPLETED",
"durationSeconds": 240,
"createdAt": "2026-05-29T13:00:00Z"
}
],
"nextCursor": "eyJjcmVhdGVk..."
}

GET /api/calls/status

Bulk poll the status of many calls at once.

GET /api/calls/status?ids=f0a1d2e3-...,a1b2c3d4-...

Response — 200 OK

{
"items": [
{ "callId": "f0a1d2e3-...", "status": "COMPLETED" },
{ "callId": "a1b2c3d4-...", "status": "TRANSCRIBING" }
]
}

Cheap, idempotent, safe to poll on a 3–5 second cadence.

GET /api/calls/{id}

Single call detail (no transcript / analysis — those have dedicated endpoints).

Response — 200 OK

{
"callId": "f0a1d2e3-...",
"title": "Quarterly review",
"status": "COMPLETED",
"direction": "OUTGOING",
"contactName": "Ravi",
"phoneNumber": "+91 98765 43210",
"durationSeconds": 240,
"recordedAt": "2026-05-29T13:00:00Z",
"createdAt": "2026-05-29T13:00:00Z",
"errorReason": null
}

POST /api/calls/{id}/reanalyze (dev/staging only)

Re-run the LLM analysis for a completed call using its stored NORMALIZED_TRANSCRIPT_JSON — no audio is re-transcribed or re-diarized. Overwrites the ANALYSIS_JSON artifact and re-applies action-item side effects (delete-then-insert), so it is idempotent and safe to re-run after a prompt change.

Gated to non-prod. The controller is annotated @Profile("!prod"), so the route is not registered when the server runs the prod profile (returns 404 there). The Android client mirrors this with a DEVELOPER_TOOLS build flag (true for dev/staging flavours only) and surfaces it under Settings → Developer → Reanalyze.

Scoped to the authenticated user; foreign/unknown ids return 404.

Response — 200 OK

The updated call detail (same shape as GET /api/calls/{id}), reflecting the refreshed analysis.

Errors

StatusCause
404Call missing, owned by another user, or has no stored transcript to re-analyze.
409Call is not in a re-analyzable (COMPLETED) state. error carries the offending status.
404 (prod)Route not registered — server is running the prod profile.

DELETE /api/calls/{id}

Hard-delete a call, all artifacts, all action items.

Response — 204 No Content

Irreversible. The artifacts in object storage are deleted before the row, so a partial delete on failure simply leaves orphans for the sweeper.

DELETE /api/calls

Bulk delete.

Request

{ "callIds": ["f0a1d2e3-...", "a1b2c3d4-..."] }

Response — 200 OK

{
"deleted": 2,
"missing": 0,
"failed": []
}

Errors common to all calls endpoints

StatuscodeCause
404call_not_foundThe call doesn't exist or belongs to another user.
422call_not_completedTrying to read transcript / analysis before completion.