AI reports
GET /prompts and POST /transcriptions/{id}/reports — list the report templates a key can use, and generate reports with an upload or for a finished transcription.
Reports through the API
An AI report is a template (built-in like Summary, or one your team created in the app)
applied to a transcript. Through the API a template is addressed by its slug — a stable
identifier such as summary or sales-call-analysis. You can ask for reports together
with an upload (?reports= on Upload a file) or for any
transcription you already have. Results come back in prompt_results of
Get transcription.
Both endpoints need a key created with Allow AI reports — see Authentication. Reports are generated in a batch lane, so they never slow down the app for your team; expect a few minutes when the queue is busy.
List available reports
GET /prompts returns exactly the templates the key's owner sees in the report picker: the
built-in catalogue, templates published for the whole workspace, and the owner's own
published personal templates. Drafts are never listed and cannot be requested.
curl "https://app.specala.ai/api/v1/developer/prompts" \
-H "Authorization: Bearer sk_live_your_key_here"{
"prompts": [
{ "slug": "razbor-prodayushchego-zvonka", "name": "Sales call review", "kind": "custom", "scope": "workspace", "description": null },
{ "slug": "summary", "name": "Summary", "kind": "builtin", "scope": null, "description": "General" },
{ "slug": "tasks", "name": "Action items", "kind": "builtin", "scope": null, "description": "For meetings" }
]
}| Field | Type | Description |
|---|---|---|
slug | string | The identifier to pass in reports. Custom templates get theirs from the name; it can be edited in the app under Settings → AI reports. |
name | string | Display name. Built-in names are always in English; custom templates keep the name given in the app. |
kind | string | builtin or custom. |
scope | string | null | For custom templates: workspace (shared with the team) or personal (the key owner's own). null for built-in. |
description | string | null | Built-in category, in English, e.g. For Sales. |
Slugs are stable — until someone edits them
A custom template's slug can be changed in the app, and that breaks integrations using the
old value. Treat prompt_not_found on a slug that used to work as a signal to re-read the
list. Built-in slugs never change.
Request reports with an upload
Add reports=slug1,slug2 to Upload a file. The slugs are
validated before the body is read, so a typo costs nothing:
curl -X POST "https://app.specala.ai/api/v1/developer/transcriptions?reports=summary,tasks" \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Disposition: attachment; filename=\"call.mp3\"" \
--data-binary @call.mp3{
"uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "queued",
"reports": [
{ "id": "8d2f6a1e-0c4b-4f0e-9d3a-6b1c2e7f5a90", "slug": "summary", "status": "queued" },
{ "id": "1b7c0e9a-5f2d-4a63-8e41-2f9d0c3b6e75", "slug": "tasks", "status": "queued" }
]
}Up to 3 reports per upload. Generation starts automatically the moment the transcript is ready — you do not need to call anything else.
Request reports for a transcription
POST /transcriptions/{id}/reports — for a transcription that is already uploaded, whether
finished or still processing. Returns 202 Accepted.
curl -X POST "https://app.specala.ai/api/v1/developer/transcriptions/3fa85f64-5717-4562-b3fc-2c963f66afa6/reports" \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"reports": ["summary"]}'{
"reports": [
{ "id": "8d2f6a1e-0c4b-4f0e-9d3a-6b1c2e7f5a90", "slug": "summary", "status": "queued" }
]
}| Path / body | Type | Description |
|---|---|---|
id | UUID | Transcription identifier. |
reports | string[] | Report slugs, up to 3 per request. |
Rules that keep this safe to retry:
- A slug whose report is already being generated returns that report, not a duplicate.
- A slug whose report is already completed returns the existing report. Regeneration is not available through the API — use the app.
- A transcription that is still
queued/processingaccepts the request; the report starts when the text is ready. Afailedtranscription returns409 transcription_failed. - The app's limit of 30 report generations per transcription applies here too.
Report status & polling
Reports live in prompt_results of Get transcription,
each with its own status:
status | Meaning |
|---|---|
queued | Waiting for the transcript or for a generation slot. |
processing | Being generated. |
completed | Done — text is present. Terminal. |
failed | Couldn't be generated — see error_code. Terminal. |
The transcription itself becomes completed as soon as the text is ready; reports follow a
little later. Poll until every report you asked for is terminal:
import time
def wait_reports(uuid: str, slugs: set[str], poll_seconds: int = 10) -> dict:
while True:
t = httpx.get(f"{BASE}/transcriptions/{uuid}", headers=HEADERS).json()
if t["status"] in ("failed", "insufficient_balance"):
raise RuntimeError(t["status"])
wanted = [r for r in t["prompt_results"] if r["slug"] in slugs]
if t["status"] == "completed" and all(r["status"] in ("completed", "failed") for r in wanted):
return {r["slug"]: r for r in wanted}
time.sleep(poll_seconds)Export transcription includes only completed
reports.
Limits
| Limit | Value |
|---|---|
| Reports per request | 3 |
| Reports per workspace per day | 300 |
| Reports waiting per workspace | 200 |
| Generations per transcription | 30 (shared with the app) |
Current values for your workspace are in Get workspace under
limits.reports_per_upload and limits.reports_per_day. Reports requested through the API are
not billed separately in this release.
Errors
| Status | Code | When |
|---|---|---|
403 | reports_scope_required | The key was created without Allow AI reports. Permissions can't be added later — create a new key. |
404 | — | The transcription does not exist or is not visible to this key. |
409 | transcription_failed | The transcription failed; there is no text to build a report on. |
422 | prompt_not_found | A slug is unknown or not visible to the key's owner — detail.slug says which. Drafts and other members' personal templates are not visible. |
422 | too_many_reports | More than 3 slugs in one request. |
429 | report_generation_limit | 30 generations already made for this transcription. |
429 | daily_reports_quota_exceeded | Daily cap for the workspace. Honour Retry-After (UTC midnight). |
429 | too_many_queued_reports | Too many reports waiting in the workspace. Honour Retry-After. |
See Errors for the full reference and retry guidance.