REST API

Summary

Overview

Generate a meeting summary from any transcript text, with the response streamed segment by segment over SSE. This endpoint is independent of the recording flow and can be used to integrate transcripts from external sources (meeting notes from other systems, pre-upload previews, and so on).

If you want to regenerate a summary for a recording that has already been uploaded to VAS, use GET / POST /api/v1/sse/regenerate/summary/{taskId} instead.


Connection Information

ItemValue
EndpointPOST /api/v1/summary
Base Pathhttps://vas-poc.vurbo.ai
ProtocolHTTP + Server-Sent Events (SSE) response
AuthenticationHeader Authorization: Bearer <api_key>

Note: This endpoint uses Authorization: Bearer authentication, which differs from the X-API-Key used by other REST endpoints.


Request

Request Body (JSON)

FieldTypeRequiredConstraints / DefaultDescription
contentstringYes≤100,000 charactersTranscript content to summarize
modestringYesenum "builtin" | "custom"Explicit path selection
templatestringRequired for builtin / forbidden for customexists prompt_templates.slugBuilt-in template slug
promptstringRequired for custom / forbidden for builtin≤2000 charactersThe customer's full prompt (replaces the built-in prompt)
prompt_slugstringRequired for custom / forbidden for builtin≤64 characters, Unicode, no control charactersThe customer's own identifier (pass-through)
formatstringNobullet_points / paragraph / structured (default bullet_points)Built-in output format (not applicable under custom)
languagestringNo-Output language code (e.g. zh-TW, en-US)
plain_textboolNoDefault falsePlain-text output (the backend applies Markdown post-processing to strip #/*/**/list markers, etc.)
max_lengthintNo-Maximum length of the summary, in words

Mutual-exclusivity rules:

  • Under mode=builtin, you must not include prompt or prompt_slug
  • Under mode=custom, you must not include template, but prompt and prompt_slug are required

Violation → 400 summary_mode_field_mismatch

Request Examples

builtin mode (apply a built-in template)

curl -N -X POST "https://vas-poc.vurbo.ai/api/v1/summary" \
  -H "Authorization: Bearer vas_..." \
  -H "Content-Type: application/json" \
  -d '{
    "content": "...transcript...",
    "mode": "builtin",
    "template": "medical_consultation",
    "language": "zh-TW",
    "plain_text": true
  }'

custom mode (fully customized prompt)

curl -N -X POST "https://vas-poc.vurbo.ai/api/v1/summary" \
  -H "Authorization: Bearer vas_..." \
  -H "Content-Type: application/json" \
  -d '{
    "content": "...transcript...",
    "mode": "custom",
    "prompt": "You are a dermatology specialist assistant. From the transcript, extract: 1) chief complaint 2) Fitzpatrick type 3) allergy history. Output JSON.",
    "prompt_slug": "skin-clinic-acme-v2",
    "language": "zh-TW",
    "plain_text": true
  }'

Effect:

  • The backend does not query any built-in template
  • The customer's prompt replaces the built-in template rules; only minimal default processing is applied (language, plain text, safety guard)
  • The prompt content is forcibly snapshotted into the done event and stored in the backend record (the sole basis for reconstruction)

SSE Events

Event Sequence

1. start    → Generation begins
2. chunk    → Summary segment (repeated N times, includes markdown)
3. done     → Generation complete (includes the final cleaned content; in custom mode, includes prompt_snapshot)
4. error    → An error occurred (replaces done)

start event

{
  "summary_id": "sum_abc123",
  "mode": "custom",
  "template": "skin-clinic-acme-v2",
  "format": "bullet_points",
  "language": "zh-TW",
  "plain_text": true
}
FieldTypeDescription
summary_idstringThe internal ID of this summary
modestring"builtin" or "custom"
templatestringEffective slug — builtin → the built-in slug; custom → the customer slug (i.e. the request's prompt_slug)
formatstringOutput format
languagestringOutput language
plain_textboolWhether plain-text mode is enabled

chunk event

{ "content": "This meeting discussed..." }

A streamed segment (includes markdown; the frontend can render it in real time).

done event

{
  "summary_id": "sum_abc123",
  "tokens_used": { "input": 1234, "output": 567 },
  "created_at": "2026-05-13T08:30:00Z",
  "mode": "custom",
  "template": "skin-clinic-acme-v2",
  "plain_text": true,
  "final_content": "This meeting... (cleaned plain text when plain_text=true)",
  "prompt_snapshot": "You are a dermatology specialist assistant..."
}
FieldTypeDescription
summary_idstringSame as in start
tokens_used.input / .outputintToken usage
created_atstringISO 8601 timestamp
modestringSame as in start
templatestringEffective slug
plain_textboolWhether plain-text mode is enabled
final_contentstringThe full content (cleaned plain text when plain_text=true)
prompt_snapshotstringAppears only in custom mode; the prompt content passed in verbatim by the customer (forcibly snapshotted)

error event

{
  "errorCode": "summary_mode_field_mismatch",
  "message": "Field mismatch with mode",
  "details": { "provider": "llm_service" }
}

Security discipline: details does not include the LLM's internal raw error (to avoid exposing prompt fragments, API key hashes, and other sensitive information); it only indicates the provider. The full error message goes into the server log.


Specific Error Codes

Error CodeHTTPDescriptionRecommended Action
summary_text_empty400content is an empty stringProvide a valid transcript
summary_text_too_long400content exceeds 100,000 charactersShorten or split it
summary_invalid_mode400mode is not builtin / customChange to a valid mode
summary_mode_field_mismatch400The mode and field combination does not match (a required field is missing or a forbidden field was included)Adjust the fields according to the mode rules
summary_prompt_too_long400prompt exceeds 2000 charactersShorten it
summary_prompt_slug_too_long400prompt_slug exceeds 64 charactersShorten it
summary_prompt_slug_invalid400prompt_slug contains control characters (\n/\r/\t/\0, etc.)Remove the control characters
summary_failed500LLM generation failedRetry later
summary_timeout504Generation timed outRetry later

Integration Best Practices

  1. For the builtin path, first call GET /api/v1/summary-templates/{slug} to understand the built-in template content (see summary-templates.md)
  2. Under the custom path, your prompt must include the output language, structure description, and field requirements (the backend no longer applies built-in template rules)
  3. Avoid using markdown symbols in the prompt (-, *, #) — if plain_text=true, the backend post-processing strips them out
  4. Do not splice untrusted end-user input directly into prompt (you assume the prompt-injection risk; the backend includes prompt-injection protection but it is not foolproof)
  5. Do not write passwords or API keys in prompt (the content is sent to the LLM service for processing, and in custom mode the prompt content is stored in the backend record for auditing)
  6. It is recommended that prompt_slug include a version (e.g. acme-v1acme-v2) so integrators can trace it
  7. When plain_text=true, expect fully plain-text output (even - list markers are stripped); if you need to preserve list structure, use CJK symbols (, ①②③, 【】)


Version: V1.5.7 Last Updated: 2026-05-20

Copyright © 2026