Subtitle lint: SRT and WebVTT overlaps, duration, reading speed, line length
Parses an SRT or WebVTT file (up to 400000 characters, 4000 cues) and checks every cue for an agent about to deliver or burn in captions: end after start, overlaps and out-of-order cues, minimum gap, minimum and maximum duration, lines per cue, characters per line and characters per second (markup tags are not counted). Rules come from a named profile (netflix-en-adult, netflix-en-children, values quoted from the Netflix Partner Help Center with page URLs) or from your own custom values; with neither it checks structure only and answers unknown. It does not judge translation quality, shot changes, positioning or languages other than the profile's own, and does not read ASS/SSA or TTML.
What you get
A delivery rejected for reading speed or overlaps costs a re-spin; this lists every offending cue with the exact numbers.
Call it
Send the JSON body below to https://agents.writerslogic.com/api/v1/subtitle-lint. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.
curl -i -X POST https://agents.writerslogic.com/api/v1/subtitle-lint \
-H 'content-type: application/json' \
-d '{"text":"1\n00:00:01,000 --> 00:00:03,000\nHello there.\n\n2\n00:00:02,500 --> 00:00:04,000\nOverlapping cue.\n","profile":"netflix-en-adult","frameRate":24}'
Input
| Field | Type | Required | Description |
|---|---|---|---|
text | string; length 1..400000 | yes | The whole .srt or .vtt file. |
format | string; one of "srt", "vtt" | no | Default: vtt if the text starts with WEBVTT, else srt. |
profile | string; one of "netflix-en-adult", "netflix-en-children" | no | netflix-en-adult: 42 chars/line, 2 lines, 20 cps, 5/6 s to 7 s, 2-frame gap. netflix-en-children: same at 17 cps. |
custom | object | no | Your own rules; these override profile values. |
frameRate | number; 1..240 | no | Needed to turn a minimum gap in frames into milliseconds. |
Example request body
{
"text": "1\n00:00:01,000 --> 00:00:03,000\nHello there.\n\n2\n00:00:02,500 --> 00:00:04,000\nOverlapping cue.\n",
"profile": "netflix-en-adult",
"frameRate": 24
}
Result
The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.
| Field | Type | Required | Description |
|---|---|---|---|
status | string; one of "pass", "fail", "unknown", "unsupported" | no | pass: every rule held. fail: a rule was violated (see witnesses). unknown: the input lacks the evidence to decide. unsupported: outside what this engine covers. Missing evidence is never a pass. |
format | string | no | |
profile | string | no | |
appliedRules | object | no | The rule values actually applied. |
cueCount | integer | no | |
violationCounts | object | no | Violations per rule id. |
maxCps | one of | no | |
skippedRules | array<string> | no | |
witnessesTruncated | boolean | no | True when more than 200 violations were found; counts are still complete. |
witnesses | array<object> | no | |
versions | object | no | Every semantic dependency of this answer (engine, tables and their as-of dates, tokenizer, calendar, rounding profile). |
limits | array<string> | no | |
deterministic | boolean | no | Always true: pure code, no model. |
Pay and connect
Available through: x402 (USDC on Base), MCP. MCP clients reach it through the identifier-text-kit package.
Machine-readable
- This agent as JSON (schemas, example, OpenAPI operation)
- Free signed sample response
- OpenAPI 3.1 · Catalog · Index of every agent