SSE API

Regenerate Summary SSE

Connection Information

ItemValue
Base pathhttps://vas-poc.vurbo.ai/api/v1/sse
ProtocolHTTP + Server-Sent Events (SSE)
Data formattext/event-stream
AuthenticationHeader X-API-Key: {KEY}, or query ?api_key={KEY} (either works; query takes precedence)

Note: The browser's native EventSource API does not support custom headers. Use the fetch API with a ReadableStream, or use an SSE client library that supports headers.


Endpoint Overview

Split into two endpoints, preview and persist:

MethodEndpointPersists ResultSaves transcriptBilledPurpose
GET/api/v1/sse/regenerate/summary/{taskId}NoNoYesPreview (dry run, compare results across prompts)
POST/api/v1/sse/regenerate/summary/{taskId}YesYes (and increments revision)YesPersist (official save)

Known limitation: The GET preview is still billed — the LLM genuinely consumes tokens, so the GET endpoint cannot be used for free. Calling GET repeatedly is billed each time, but does not change the backend's stored state.


Shared: Request Parameters

GET uses the query string and POST uses a JSON body, with identical field names and types:

ParameterTypeRequiredConstraintsDescription
taskId (path)stringYesUUIDRecording ID
modestringYesenum "builtin" | "custom"Explicit path selection
templatestringRequired for builtin / forbidden for customexists prompt_templates.slugBuilt-in template slug
promptstringRequired for custom / forbidden for builtin≤3000 charactersThe customer's complete prompt (replaces the built-in layered prompt)
promptSlugstringRequired for custom / forbidden for builtin≤64 characters, Unicode, no control charactersThe customer's own identifier (returned as-is, not processed)
languagestringNo-Summary output language code (e.g. zh-TW, en-US); when unspecified, the first transcription language is used
plainTextbooleanNoDefault falseRequest plain-text output (the backend performs additional markdown post-processing)

Mutual exclusion rules:

  • With mode=builtin, you may not include prompt or promptSlug
  • With mode=custom, you may not include template, but prompt and promptSlug are required

Violations → parameter validation failure (an error event whose data carries only message, with no error_code)


GET /api/v1/sse/regenerate/summary/{taskId} (preview)

Description

Runs the LLM once to regenerate the summary, streaming only to the client. Does not write the DB and does not update the transcript record.

Use case: the client wants to try different prompt / plain_text settings, compare the results, and then decide whether to persist.

Request Examples

builtin mode

curl -N "https://vas-poc.vurbo.ai/api/v1/sse/regenerate/summary/550e8400-e29b-41d4-a716-446655440000?mode=builtin&template=meeting&language=zh-TW&plainText=true" \
  -H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"

custom mode

curl -N "https://vas-poc.vurbo.ai/api/v1/sse/regenerate/summary/550e8400-e29b-41d4-a716-446655440000?mode=custom&prompt=%E8%AB%8B%E5%BC%B7%E8%AA%BFKPI&promptSlug=acme-meeting-v2&plainText=true" \
  -H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"

Side Effects

  • Incurs one summary billing charge (the LLM genuinely consumes tokens)
  • Does not update the three columns recordings.summary_mode / summary_template / summary_prompt_slug
  • Does not overwrite the saved summary

POST /api/v1/sse/regenerate/summary/{taskId} (persist)

Description

All actions of the GET preview, plus writing to the DB and the transcript record.

Request Examples

builtin mode

curl -N -X POST "https://vas-poc.vurbo.ai/api/v1/sse/regenerate/summary/550e8400-e29b-41d4-a716-446655440000" \
  -H "X-API-Key: vas_..." \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "builtin",
    "template": "meeting",
    "language": "zh-TW",
    "plainText": true
  }'

custom mode

curl -N -X POST "https://vas-poc.vurbo.ai/api/v1/sse/regenerate/summary/550e8400-e29b-41d4-a716-446655440000" \
  -H "X-API-Key: vas_..." \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "custom",
    "prompt": "You are a dermatology specialist assistant. Extract the Fitzpatrick skin type from the transcript...",
    "promptSlug": "skin-clinic-acme-v2",
    "language": "zh-TW",
    "plainText": true
  }'

Side Effects

  • Incurs one summary billing charge
  • Mutually exclusive writes to the three recordings columns, depending on mode:
    • builtin → summary_mode='builtin', summary_template=<slug>, summary_prompt_slug=NULL
    • custom → summary_mode='custom', summary_template=NULL, summary_prompt_slug=<customer slug>
  • Updates the task's summary language: the summary_language in the task list and in the history init_metadata changes to the language used this time
  • Updates the top-level fields of the transcript record and bumps revision += 1:
    • summary (plain string), summary_language, summary_mode, summary_template (effective slug), summary_plain_text
    • Required in custom mode: summary_prompt_snapshot (a verbatim snapshot of the customer's prompt, the only basis for reconstruction)

Event Sequence (same for both endpoints)

1. connected              → connection confirmation
2. summary_regeneration   → sends summary chunks (repeats N times, cumulative)
3. done                   → generation complete
   or
3. error                  → generation failed (sse_summary_regeneration_failed; can occur on both endpoints;
                            nothing is saved or billed, and **no** done is sent)
   or
3. error                  → save failed, or another write is in progress (storage_upload_failed /
                            transcript_revision_conflict; the request stops and **no** done is sent)

The error for a failed save or a concurrent write occurs only on the save endpoint (POST). The preview endpoint (GET) does not write to the transcript and never reaches it.

connected

{
  "message": "Summary regeneration stream connected (taskId: 550e8400-..., mode: custom, endpoint: preview)"
}

Note: Avoid confusion: The mode in the message is the summary mode (builtin / custom, the mode passed in the request); endpoint is the endpoint mode (preview for GET / persist for POST). The two have different meanings; do not conflate them.

summary_regeneration

{ "text": "This meeting discussed the following topics:\n1. Product development progress", "is_final": false }
FieldTypeDescription
textstringCumulative summary content (when plainText=true, the text of the is_final=true event is the cleaned plain text)
is_finalbooleanWhether this is the final result

done

{
  "task_id": "550e8400-e29b-41d4-a716-446655440000",
  "tokens_used": 123,
  "final_content": "This meeting... (complete cleaned content)",
  "mode": "custom",
  "template": "skin-clinic-acme-v2",
  "plain_text": true,
  "persisted": true,
  "summary_language": "zh-TW",
  "characters_billed": 12700,
  "charged": "1.3",
  "billed": true,
  "prompt_snapshot": "You are a dermatology specialist assistant..."
}
FieldTypeDescription
task_idstringRecording UUID
tokens_usednumberTotal token usage
final_contentstringComplete summary content (cleaned plain text when plainText=true)
modestringSummary mode: "builtin" or "custom"
templatestringeffective slug — builtin → built-in template slug; custom → customer slug
plain_textbooleanWhether plain-text mode is enabled
persistedbooleanWhether this summary has been officially saved (false for GET, true for POST)
summary_languagestringThe language actually used for this summary (BCP 47). The language value if one was sent; otherwise the first transcription language. Present for both preview (GET) and save (POST), and always has a value (added in v1.16.5)
characters_billednumberCharacter count used as the billing basis for this request
chargedstringPoints consumed by this operation, calculated from the rate. This value reflects usage: usage already covered by an unlimited plan is still reported here
billedbooleanWhether this request incurred consumption; always true (all three fields are absent when nothing was consumed)
prompt_snapshotstringAppears only in custom mode; the verbatim prompt content passed in by the customer (a required snapshot, the only basis for reconstruction)
truncatedbooleanPresent only when the summary could not be produced in full (the value is always true). The field is absent entirely when the summary is complete. When present, final_content is not a complete summary: the summary reached the output length limit, or generation reached the processing time limit (only the part completed so far is returned). Both cases are billed as usual, and the save endpoint (POST) also saves this incomplete summary

Billing fields: characters_billed, charged, and billed appear only when the request actually incurred consumption. When nothing was consumed (for example, when generation fails), all three are absent. Always use billed to determine whether a request was billed (billed only when billed is true) — that criterion applies to every endpoint that carries billing fields, with no per-endpoint exceptions. Integrators that call this API on behalf of end users and bill them separately can use charged directly instead of deriving it. Both preview (GET) and save (POST) are billed, so both carry the billing fields. If generation fails (sse_summary_regeneration_failed), or the save endpoint emits error because the save failed (see "Event Sequence", step 3), that request is not billed and no done is sent.


Specific Error Codes

Error CodeHTTPDescriptionRecommended Action
recording_not_found404The specified recording was not foundConfirm taskId is correct
sse_template_not_found404The template exists but has been disabled (builtin mode)Use a different template
sse_transcript_not_found404The transcript was not foundThe recording may not have finished processing yet
summary_text_empty400The transcript has no content to summarizeThe recording content is too short or is entirely silence
summary_text_too_long400The transcript exceeds the length limit (200,000 characters)Shorten the recording or split the file
sse_summary_regeneration_failed500Summary regeneration failed (the response does not include internal error details). Also returned when the stream stalls or does not end normally; nothing is saved or billed, and the summary_regeneration chunks received before it are not a complete result, so discard themRetry later
transcript_revision_conflict409Another write to the same transcript is in progress (save endpoint only)The summary was not saved and is not billed; retry shortly. No done follows this code
storage_upload_failed500Failed to write the transcript back to storage (save endpoint only)The summary was not saved and is not billed; retry later. No done follows this code
auth_insufficient_credit402Insufficient creditThis is a real HTTP 402 JSON response returned before the stream starts, not an SSE event; top up and retry
stt_quota_exceeded402Available credit does not cover the estimated cost of this requestAlso a JSON response returned before the stream starts; top up and retry

Parameter validation failures carry no error code. An invalid mode, a field combination that does not match the mode, a prompt or promptSlug that is too long or contains control characters — all of these are rejected during parameter validation. The response is an error event whose data carries only message, with no error_code. Present message to the user; do not try to match on an error code.

A nonexistent template slug is also a parameter validation failure (message: The specified summary template does not exist) - it is not a 422 and carries no error code.

Content filtering — current status of this SSE endpoint:

Realtime recording summaries and file-import summaries already support automatic content-filter fallback (standard mode -> neutral mode -> segment-omission mode), and produce a simplified summary when blocked. This endpoint (SSE regenerate/summary) does not support it yet — when content filtering is triggered, this endpoint always returns sse_summary_regeneration_failed, and the response does not distinguish "filtered" from any other generation failure.

A future release will add automatic fallback and extend the done event with fallback_level / dropped_segments fields. Until then, if a retry still fails, revise the prompt or the transcript content.


Version: V1.24.1 Last Updated: 2026-09-28

Copyright © 2026