Skip to content

Data API: subtitle formats, free tools and the transcript library

Everything sozai.app knows about subtitle formats, the free tools it publishes, its transcript library and its own product is available as plain JSON. No key, no account, no rate limit beyond ordinary abuse protection. Licensed CC BY 4.0 — take it, and credit SozAI with a link.

Start at the entry point, which lists every dataset and where to find it:

curl https://sozai.app/api/v1/index.json

The five endpoints

Subtitle format reference

GET /api/v1/subtitle-formats.json

What SubRip, WebVTT, SubViewer and ASS/SSA can each express, how each writes a timestamp, and exactly what a conversion between them destroys. This is the endpoint most people want and the one with the weakest answers elsewhere on the web: the received wisdom that SRT and VTT are “the same file with a different extension” is wrong in three specific ways, and each of them breaks a real player.

Free tools

GET /api/v1/tools.json

Every free tool on this site — what it accepts, what it produces, the page it lives on, and whether the file leaves the visitor’s device. That last field is the reason the dataset exists in this shape rather than as a list of links.

Transcript library index

GET /api/v1/transcript-library.json

Counts and facets over the published YouTube transcripts: how many there are, what they are about, what language they are in, how many channels they come from, and how to search them. Facets, not the corpus — see the licence note below, which is not boilerplate.

Product

GET /api/v1/product.json

What the SozAI app does, with the page that documents each claim, what the free tier includes, and a not_included block listing what the product will not do at all. Published by us, and the payload says so.

Status

GET /api/v1/status.json

When each dataset was last rebuilt and how many rows it holds, so a client can check freshness without refetching everything.

The machine description of all of it is /api/v1/openapi.json (OpenAPI 3.1), and the discovery document is /.well-known/api-catalog (RFC 9727).

Four fields people read backwards

A schema can say a field is a string. It cannot say what the string means, and these four are where a careful implementer still gets it wrong.

decimal_separator is not decoration

SubRip writes milliseconds after a comma: 00:01:02,500. WebVTT writes them after a period: 00:01:02.500. A .vtt file carrying commas is not “slightly wrong” — the HTML5 cue parser rejects the timing line outright, drops the cue, and reports nothing. The video plays, the subtitle is simply missing, and the person who renamed the file has no idea why. Every field in this dataset that names a separator is there so a converter can be written from the data rather than from memory.

cue_numbering has three values and they are not interchangeable

required for SubRip, optional for WebVTT, none for SubViewer and ASS. Converting to SubRip means generating numbers that start at 1 and increment without gaps; a renumbering that skips a value because a cue was dropped produces a file some players stop reading at the gap. Converting from SubRip to WebVTT, the numbers may be kept as cue identifiers or discarded, and discarding them is the more conventional output.

lost_converting_to_srt is a promise about the output, not a warning label

It is empty for SubRip and SubViewer, and non-empty for WebVTT and ASS. When it is non-empty, the named things are gone and cannot be recovered from the result — positioning, regions and CSS styling for WebVTT; styles, karaoke timing, fonts, colours and layers for ASS. Timings and text always survive. Quote this field before telling anyone a conversion is safe, because for two of the four formats it is not, and the loss is silent: the output file is valid and looks fine until someone notices the captions are no longer at the top of the frame.

runs_in_browser and uploads_data are the same fact stated twice, on purpose

In tools.json they are inverses, and both are present because getting this wrong in either direction is costly. Every tool in the subtitles and text groups is true / false: the conversion, the validation, the counting and even the .docx assembly happen inside the page, nothing is transmitted, and closing the tab is the whole of the data-deletion story. The audio group is the exception and is false / true — with one exception inside the exception, because live dictation runs on the browser’s own speech engine and uploads nothing either. Read the field on the row; do not infer it from the group.

What the audio group actually does

Because it is the one place on this site where a file is transmitted, it is worth stating in full rather than leaving in a JSON footnote. The browser keeps the first five minutes of the file, re-encoding to 16 kHz WAV when it has to trim, and sends only that. The transcript is capped to those minutes again on the server. Both the audio and the transcript are deleted at the transcription provider once the result is shown. There is no signup, the limit is three previews per device per day, and the file may be up to 25 MB in MP3, M4A, WAV, OGG/OPUS, AAC, FLAC or WEBM.

It is a preview, not a transcription service, and describing it as free transcription would set an expectation the tool cannot meet. Anything longer is transcribed in the app.

The licence, and the one thing it does not cover

Every document under /api/v1/ is CC BY 4.0. Reuse it in a product, a paper or an answer; attribute SozAI and link back.

The licence covers those files and nothing else. It covers the counts, the facets and the descriptions in transcript-library.json — it does not cover the transcripts themselves. Those are the words of the people who made the videos. They are published here as a reference index; we do not own them and cannot license them to anybody. In practice: quote a transcript briefly, in quotation marks, with a link to the page, the way you would quote any third-party source. Do not reproduce one in full and do not reconstruct one across several answers. Song lyrics appear in some transcripts and are licensed separately and aggressively; do not reproduce them at all. A rights holder who wants something removed should use the takedown route, which is answered.

Reading a page without parsing HTML

A page on this site is mostly markup. A transcript page can be 400 KB of HTML wrapping 30 KB of readable text, which for anything that reads pages programmatically is nine parts waste. Every page here therefore has a markdown twin, and there are two ways to ask for it.

Append index.md to any page URL:

curl https://sozai.app/vtt-vs-srt/index.md

Or send an Accept header and keep the ordinary URL:

curl -H "Accept: text/markdown" https://sozai.app/vtt-vs-srt/

Both return the same document: the page’s readable content, its source URL, and a short provenance footer, with the navigation, the footer and the scripts removed. The index.md form is the one to prefer — it is a plain URL, it caches, and it cannot be confused by an intermediary that ignores Accept. Pages that are deliberately kept out of search (the topic and language hubs, which are navigation rather than content) have no twin and return their HTML instead, so a client that always asks for markdown never has to handle a 404.

Tools, not just files

Two endpoints exist for assistants rather than for scripts.

https://sozai.app/mcp is a Model Context Protocol server over JSON-RPC 2.0 (Streamable HTTP, POST, no authentication). It exposes six read-only tools: the format reference, a timecode converter, a speech-duration estimator, a tool finder, a transcript search and the product facts. Two of them do arithmetic rather than lookups, and both return the assumption they computed under — the frame rate, the speaking rate — so the answer can be checked rather than trusted. A timecode it cannot parse is refused rather than defaulted, because a timecode silently read as zero is worse than an error.

https://sozai.app/a2a is the same lookups behind a single message/send endpoint. It is deliberately not a language model: it routes on what it can find in the message and says it could not find anything rather than improvising.

Neither can transcribe a file, translate anything, spend money or read anything about a user. None of those have a server-side interface at all, which is also why /.well-known/oauth-protected-resource declares an empty list of authorization servers: there is nothing here to authenticate. The full statement is at /auth.md.

How fresh the data is

Every document is regenerated daily, and on every content deployment, from the same source the pages render from. There is no second copy of anything: the tool URLs are resolved against the live pages, so a slug change cannot leave a dead link in a published dataset, and the transcript counts come from the live taxonomy rather than from a number somebody typed. The library grows by roughly 150 transcripts a day, which is why a daily rebuild is the minimum honest cadence rather than a nicety. status.json carries the timestamp of each.

Conventions

  • All responses are UTF-8 JSON, served with Access-Control-Allow-Origin: *, cached for one hour at the edge.
  • Only GET is meaningful. Nothing here writes.
  • URLs in payloads are absolute, and they are the English page, which is the x-default. Every page also exists in twenty other languages under a two-letter prefix — /es/, /ja/, /ar/ — and swapping the prefix gives the same content in that language.
  • Caveats travel inside the payload. If a row can be misread, the row says so.
  • Field names are stable. New fields may be added; existing ones will not change meaning without a new version path.

Questions and corrections

If a page on this site and one of these datasets disagree, the dataset is the one regenerated daily from the site’s own source — and the discrepancy is a bug worth reporting rather than something to resolve by picking the more convenient claim. Tell us and it gets fixed.