# Proofread API

Canonical docs: https://platform.sonilo.com/docs/api/proofread
Source path: /docs/api/proofread
Runtime API host: https://api.sonilo.com/v1

Do not send API requests to platform.sonilo.com, docs.sonilo.com, or local docs URLs. Documentation pages are for reading only. Send runtime requests to https://api.sonilo.com/v1 with Authorization: Bearer sk_your_api_key.

## Endpoint

POST /v1/proofread

## Summary

Transcribe a video and translate the transcript into the requested target languages, returning one editable .srt per language plus the source-language transcript, so the wording can be reviewed before it is dubbed. Does not produce audio or video.

## Use This For

- Reviewing or correcting a translation before calling video translation (POST /v1/dubbing), so the dub speaks exactly the approved text: send the edited files back as subtitles[<language>].
- Getting a timed transcript of a video's speech as an .srt without any translation (omit languages).
- Producing subtitle files for several languages from one source in one call.

## Request

- video: file upload. Provide exactly one of video or video_url. Max file size: default 300MB. Max duration: 300 sec. The video must have an audio track.
- video_url: URL input. Provide exactly one of video or video_url. Same limits.
- languages: optional JSON array string of target language codes, e.g. ["ja", "zh_cn"] — the same codes video translation accepts. Omit it, or send [], for the source-language transcript only.
- source_language: optional hint of the spoken language, one of the same codes. Omit it to have the language detected; either way the response's source_language reports the detected code.

## Response And Errors

- 202 returns task_id and status=processing.
- Poll GET /v1/tasks/{task_id} every 2-3 seconds.
- On success, read subtitles — a map of language code to a downloadable .srt URL, always including the source language under its detected code — plus source_language, cue_count (subtitle cues in the source script) and warnings (per-language non-blocking validation issues; empty when none). There is no audio.url, video.url or output_url.
- A failed task's error.code is one of SOURCE_DOWNLOAD_FAILED, SOURCE_PROCESSING_FAILED, TRANSCRIPTION_EMPTY (no speech was found), TRANSCRIPTION_FAILED, TRANSLATION_FAILED, PREFLIGHT_BLOCKED, PREFLIGHT_UNAVAILABLE or TRANSFER_FAILED.
- Billed per second of video multiplied by the number of target languages (a transcript-only request counts as one), with a 10-second floor. 2 free trial calls.
- 400 invalid_request (both or neither of video and video_url), 401 auth_invalid, 402 payment_required or insufficient_balance, 403 forbidden, 404 not_found, 422 unprocessable_entity (no audio track or over-limit duration), and 429 Retry-After should be handled explicitly.

## Example

```bash
curl -X POST "https://api.sonilo.com/v1/proofread" \
  -H "Authorization: Bearer sk_your_api_key" \
  -F "video=@episode1.mp4" \
  -F 'languages=["ja", "zh_cn"]'
```

## Shared Error Handling

- 401 auth_invalid: set Authorization: Bearer sk_your_api_key on the request.
- 402 payment_required or insufficient_balance: add credits before rerunning; do not create fake audio.
- 403 forbidden: the key is valid but the account or service permission is missing.
- 404 not_found: check the endpoint path and host. Use https://api.sonilo.com/v1, not a docs URL.
- 429 rate_limit_exceeded: honor Retry-After and retry with backoff.

## Endpoint Vocabulary

- GET /v1/account/services
- GET /v1/account/usage
- POST /v1/text-to-music
- POST /v1/video-to-music
- POST /v1/audio-ducking
- POST /v1/text-to-sfx
- POST /v1/video-to-sfx
- GET /v1/tasks/{task_id}

