---
title: "Check speech in your own video or audio — free"
method: POST
path: "/media/check"
tags: ["Landings"]
---

# Check speech in your own video or audio — free

`POST /media/check`

## Request

- Base URL: `https://vibemarketolog.ru/api/agent`
- URL: `https://vibemarketolog.ru/api/agent/media/check`
- Auth: HTTP bearer

Recognizes speech in your own finished generation (video or audio up to 120 s) on our server and compares it with the intended line: word similarity (%), what was not said, what was said instead (with the second; tail=true means the end of the line), consecutive repeats of a word or phrase, where speech ends and where to cut (suggested_trim_at). Verdict ok/warn with advice: a repeat or extra words AFTER the line — POST /media/loop mode=trim with trim_at=suggested_trim_at; a problem in the middle of speech or a distorted end — regenerate (suggested_trim_at is null then). If words_timed=false and the message asks to repeat — call again in a minute. Without expected_text only consecutive repeats are searched; for a background video "no speech" is ok. Up to 100 per day, one at a time per account. Service texts name the MCP tools: media_check = POST /media/check, video_loop = POST /media/loop. MCP twin: media_check.

## Request body

- object
  - `generation_id` integer, required: Your finished generation (status=complete) — video or audio
  - `expected_text` string: The line the character had to say, verbatim (as in the generation prompt)

## Response `200`

Recognized text, similarity, problems and verdict

- MediaCheckResult
  - `status` 'ok'
  - `generation_id` integer
  - `type` 'video' | 'audio'
  - `duration` number
  - `expected` string, nullable
  - `text` string: Recognized speech
  - `channel` string: Recognition channel
  - `words_timed` boolean: Per-word timings available; without them the cut point cannot be found
  - `similarity_pct` integer, nullable
  - `missing` unknown[]: Words of expected_text that were not said
    - unknown
  - `extra` object[]: Said but not intended: {text, at}
  - `replaced` object[]
    - `expected` string
    - `heard` string
    - `at` number
    - `tail` boolean
  - `repeats` object[]
    - `phrase` string
    - `times` integer
    - `at` number, nullable
  - `speech_end_at` number, nullable
  - `suggested_trim_at` number, nullable: Where to cut with POST /media/loop mode=trim; null — regenerate instead
  - `verdict` 'ok' | 'warn'
  - `message` string: Verdict in words and what to do

## Other responses

- `401`: Ключ не передан, недействителен, отозван или истёк (missing_token / invalid_token)
- `403`: sandbox_not_allowed (shared trial key from self-registration: its files would be visible to everyone) / insufficient_scope / ip_not_allowed
- `422`: bad_params — no generation_id / media_rejected — not your generation, not finished, too long, recognition busy, daily limit or another call in progress (message says what to do) / validation_failed
- `429`: Превышена частота запросов или суточный лимит траты ключа (rate_limit_exceeded / daily_spend_limit_exceeded)

---

[API](https://skmtc.dev/vibemarketolog/apis/agent-api.md) · [All operations](https://skmtc.dev/vibemarketolog/apis/agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/vibemarketolog/apis/agent-api/revisions/6a74f8ad5d58?raw)
