Specala AIDocs
API Reference

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" }
  ]
}
FieldTypeDescription
slugstringThe identifier to pass in reports. Custom templates get theirs from the name; it can be edited in the app under Settings → AI reports.
namestringDisplay name. Built-in names are always in English; custom templates keep the name given in the app.
kindstringbuiltin or custom.
scopestring | nullFor custom templates: workspace (shared with the team) or personal (the key owner's own). null for built-in.
descriptionstring | nullBuilt-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 / bodyTypeDescription
idUUIDTranscription identifier.
reportsstring[]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 / processing accepts the request; the report starts when the text is ready. A failed transcription returns 409 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:

statusMeaning
queuedWaiting for the transcript or for a generation slot.
processingBeing generated.
completedDone — text is present. Terminal.
failedCouldn'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

LimitValue
Reports per request3
Reports per workspace per day300
Reports waiting per workspace200
Generations per transcription30 (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

StatusCodeWhen
403reports_scope_requiredThe 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.
409transcription_failedThe transcription failed; there is no text to build a report on.
422prompt_not_foundA slug is unknown or not visible to the key's owner — detail.slug says which. Drafts and other members' personal templates are not visible.
422too_many_reportsMore than 3 slugs in one request.
429report_generation_limit30 generations already made for this transcription.
429daily_reports_quota_exceededDaily cap for the workspace. Honour Retry-After (UTC midnight).
429too_many_queued_reportsToo many reports waiting in the workspace. Honour Retry-After.

See Errors for the full reference and retry guidance.

On this page