HTTP API

Run the summarizer as a local REST API server

The Summarize HTTP API exposes all CLI functionality via REST endpoints. It is built with FastAPI and includes auto-generated interactive documentation at /docs.

Installation

Server dependencies are not included in the base package. Install the server extra in an isolated environment — the server pulls in pydantic via FastAPI, and version skew in shared ~/.local site-packages is the most common cause of startup failures.

Recommended (pipx):

$pipx install "martino-summarize[server]"

From a cloned repo (development):

$pip install -e ".[server]"

venv alternative:

$python3 -m venv ~/summarizer-venv
$source ~/summarizer-venv/bin/activate
$pip install "martino-summarize[server]"

This installs fastapi, uvicorn, and python-multipart. If startup fails with a pydantic version error, see Errors and Troubleshooting.

Starting the Server

$python -m summarizer serve

By default the server binds to 127.0.0.1:8000. You can customize the host and port:

$python -m summarizer serve --host 0.0.0.0 --port 8080

Interactive Documentation

Once the server is running, open your browser to:

  • Swagger UI: http://localhost:8000/docs
  • ReDoc: http://localhost:8000/redoc
  • OpenAPI JSON: http://localhost:8000/openapi.json

CORS

Cross-origin requests are disabled by default. To enable CORS, set the SUMMARIZER_CORS_ORIGINS environment variable:

$# Allow a specific origin
$SUMMARIZER_CORS_ORIGINS=http://localhost:3000 python -m summarizer serve
$
$# Allow all origins (not recommended for production)
$SUMMARIZER_CORS_ORIGINS=* python -m summarizer serve

When using *, credentials are automatically disabled for security compliance.

Endpoints Overview

MethodEndpointDescription
GET/healthHealth check
GET/providersList configured LLM providers
GET/promptsList available summary styles
GET/configGet merged config (secrets redacted)
POST/summarizeSummarize a URL or file path
POST/summarize/uploadSummarize an uploaded file
POST/summarize/batchSummarize multiple sources

Endpoint Reference

GET /health

Returns the service health status.

$curl http://localhost:8000/health
1{
2 "status": "ok",
3 "service": "summarize"
4}

GET /providers

Lists all providers configured in summarizer.yaml.

$curl http://localhost:8000/providers
1[
2 {
3 "name": "groq",
4 "base_url": "https://api.groq.com/openai/v1",
5 "model": "openai/gpt-oss-120b",
6 "chunk_size": null
7 }
8]

GET /prompts

Lists all available summary prompt types.

$curl http://localhost:8000/prompts
1[
2 "Questions and answers",
3 "Summarization",
4 "Distill Wisdom"
5]

GET /config

Returns the loaded configuration with provider api_key values redacted.

$curl http://localhost:8000/config
1{
2 "default_provider": "groq",
3 "providers": {
4 "groq": {
5 "base_url": "https://api.groq.com/openai/v1",
6 "model": "openai/gpt-oss-120b",
7 "api_key": "***REDACTED***"
8 }
9 },
10 "defaults": {
11 "chunk_size": 120000,
12 "prompt_type": "Questions and answers"
13 },
14 "config_file_path": "/path/to/summarizer.yaml"
15}

POST /summarize

Summarize a video from a URL or file path.

$curl -X POST http://localhost:8000/summarize \
> -H "Content-Type: application/json" \
> -d '{
> "source": "https://youtube.com/watch?v=VIDEO_ID",
> "provider": "groq",
> "speed": 2.0,
> "output_format": "markdown"
> }'

Request body

FieldTypeDescription
sourcestringRequired. Video URL or file path
typestringSource type: YouTube Video, Video URL, Google Drive Video Link, Dropbox Video Link, Local File, TXT
providerstringProvider name from summarizer.yaml
prompt_typestringSummary style
chunk_sizeintegerCharacters per chunk (100 – 500,000)
parallel_callsintegerConcurrent API requests (1 – 200)
max_tokensintegerMax output tokens per chunk (1 – 1,000,000)
languagestringCaption/transcription language
output_languagestringSummary output language
force_downloadbooleanSkip captions and download audio
transcriptionstringCloud Whisper or Local Whisper
whisper_modelstringtiny, base, small, medium, large
speednumberPlayback speed for audio preprocessing or visual-mode video (>0, ≤10)
output_formatstringmarkdown, json, or html
visualbooleanSend video directly to a vision model
use_proxybooleanRoute through Webshare proxy
api_keystringOverride API key
base_urlstringOverride API base URL
modelstringOverride model name
cobalt_urlstringCobalt base URL
verbosebooleanVerbose progress output

POST /summarize/upload

Summarize an uploaded video or text file.

$curl -X POST http://localhost:8000/summarize/upload \
> -F "file=@video.mp4" \
> -F "provider=groq" \
> -F "prompt_type=Summarization"

The source type is auto-detected from the file extension:

  • Text files (.txt, .md, .vtt, .srt, .csv, .log, .rst, .html, .xml, .json) are processed as TXT
  • Everything else is processed as Local File

Override detection by sending a type form field.

POST /summarize/batch

Summarize multiple sources in a single request. Sources are processed sequentially and results are returned in input order.

$curl -X POST http://localhost:8000/summarize/batch \
> -H "Content-Type: application/json" \
> -d '{
> "sources": [
> "https://youtube.com/watch?v=VIDEO1",
> "https://youtube.com/watch?v=VIDEO2"
> ],
> "provider": "groq",
> "output_format": "markdown"
> }'

Request body

FieldTypeDescription
sourcesarray of stringsRequired. List of URLs or file paths
All other fields from POST /summarize

Authentication

The API does not implement its own authentication layer. It is designed to run locally or behind a reverse proxy that handles authentication. If you expose it beyond localhost, place it behind a gateway (e.g., Nginx, Traefik, or a cloud API gateway) with token-based or mTLS auth.

Provider API keys are read from:

  1. The request body (api_key field)
  2. The provider config in summarizer.yaml
  3. Environment variables (e.g., GROQ_API_KEY)

Request Examples

Summarize a YouTube video

$curl -X POST http://localhost:8000/summarize \
> -H "Content-Type: application/json" \
> -d '{
> "source": "https://youtube.com/watch?v=VIDEO_ID",
> "provider": "groq",
> "output_format": "markdown"
> }'

Summarize with custom settings

$curl -X POST http://localhost:8000/summarize \
> -H "Content-Type: application/json" \
> -d '{
> "source": "https://youtube.com/watch?v=VIDEO_ID",
> "provider": "groq",
> "prompt_type": "Distill Wisdom",
> "chunk_size": 5000,
> "parallel_calls": 10,
> "output_format": "json"
> }'

Upload and summarize a local video

$curl -X POST http://localhost:8000/summarize/upload \
> -F "file=@video.mp4" \
> -F "provider=groq" \
> -F "prompt_type=Summarization"

Batch summarize multiple videos

$curl -X POST http://localhost:8000/summarize/batch \
> -H "Content-Type: application/json" \
> -d '{
> "sources": [
> "https://youtube.com/watch?v=VIDEO1",
> "https://youtube.com/watch?v=VIDEO2"
> ],
> "provider": "groq",
> "output_format": "markdown"
> }'

List configured providers

$curl http://localhost:8000/providers

Get redacted configuration

$curl http://localhost:8000/config

Response Format

All summarize endpoints return a SummarizeResponse:

1{
2 "success": true,
3 "source": "https://youtube.com/watch?v=VIDEO_ID",
4 "summary": "# Summary for: ...",
5 "format": "markdown",
6 "model": "openai/gpt-oss-120b",
7 "prompt_type": "Questions and answers",
8 "processing_time_seconds": 12.34,
9 "error": null,
10 "error_type": null
11}

On failure, success is false and error contains the message:

1{
2 "success": false,
3 "source": "https://youtube.com/watch?v=INVALID",
4 "summary": "",
5 "format": "markdown",
6 "processing_time_seconds": 0.52,
7 "error": "No captions available",
8 "error_type": "TranscriptError"
9}

Validation

Request fields are strictly validated:

  • type must be one of: YouTube Video, Video URL, Google Drive Video Link, Dropbox Video Link, Local File, TXT
  • output_format must be one of: markdown, json, html
  • transcription must be one of: Cloud Whisper, Local Whisper
  • whisper_model must be one of: tiny, base, small, medium, large
  • chunk_size: 100 – 500,000
  • parallel_calls: 1 – 200
  • max_tokens: 1 – 1,000,000
  • speed: greater than 0, up to 10
  • batch.sources: must contain at least 1 item

Requests that include the removed audio_speed field return HTTP 422. Use speed instead. YAML configs with audio-speed or audio_speed also raise a configuration error at merge time.

Invalid values return HTTP 422 with detailed validation error messages.

Upload Limits

The /summarize/upload endpoint accepts files up to 500 MB. Larger files are rejected with HTTP 413. Files are streamed to a temporary location in 1 MB chunks to avoid loading large uploads into memory.

Security Notes

  • The /config endpoint redacts all api_key values from provider configurations.
  • The server binds to 127.0.0.1 by default to prevent accidental exposure.
  • CORS is disabled by default.
  • If you need to expose the API beyond localhost, use a reverse proxy with authentication.

Async Behavior

Summarization is long-running and I/O-heavy. The API runs each job in a thread pool so that the event loop remains responsive to health checks, docs, and other concurrent requests. Batch requests process sources sequentially within the same request.

Error Handling

StatusMeaning
200Request processed (check success field for business-level failures)
413Upload exceeds 500 MB
422Request validation failed (bad enum value, out-of-range number, etc.)