# PlainScribe API — Expanded Agent Reference Last updated: 2026-08-19 Canonical human documentation: https://www.plainscribe.com/developers Canonical OpenAPI contract: https://www.plainscribe.com/openapi.json Installable agent skill: https://www.plainscribe.com/SKILL.md ## What the API does PlainScribe turns uploaded audio/video files or supported YouTube URLs into asynchronous transcription jobs. Completed jobs expose timestamped JSON segments and TXT, Markdown, CSV, SRT, and VTT exports. The API uses the same pay-as-you-go credits as the PlainScribe dashboard. Pricing is $4 per audio hour. A new account includes 30 free transcription minutes. Uploaded API objects can be at most 1GB. Transcript artifacts expire after 30 days. ## Authentication Create a user API key from the PlainScribe profile page: https://www.plainscribe.com/profile/api-keys Send it as: Authorization: Bearer $PLAINSCRIBE_API_KEY The `/api/v1` routes accept Clerk user API keys only. Each key can use every endpoint currently exposed under v1; there are no per-endpoint scope checks. Browser session cookies, organization API keys, and PlainScribe's server secret are not accepted. Use API keys only from trusted servers or local agent processes. Never expose, print, commit, log, or embed a key in browser or mobile application code. ## Canonical workflow for a local file 1. Determine the exact file name, byte size, and audio/video MIME type. 2. POST https://www.plainscribe.com/api/v1/uploads with `file_name`, `size_bytes`, and `content_type`. 3. Include a caller-generated `Idempotency-Key` header. 4. Upload the exact bytes to the response's `upload.url` with the returned headers. The URL is valid for two hours. 5. For files above 6MB, prefer the returned TUS 1.0 configuration. Use its signed endpoint (ending in `/resumable/sign`), signature, metadata, and 6MB `chunk_size_bytes` value verbatim. 6. POST https://www.plainscribe.com/api/v1/transcriptions with source `{ "type": "upload", "upload_id": "..." }` and a new `Idempotency-Key`. 7. Do not submit duration. PlainScribe verifies the object and reads its duration before billing. 8. Poll the response's `links.self` approximately every five seconds. 9. When status is `completed`, GET `links.result`. Add `?format=txt`, `md`, `csv`, `srt`, or `vtt` for a non-JSON export. 10. If status is `failed`, surface the job's structured error to the user. Do not invent transcript content. Accepted API upload extensions: AAC, AIF, AIFC, AIFF, AU, AVI, CAF, FLAC, M4A, M4V, MKV, MOV, MP3, MP4, MPEG, MPG, OGA, OGG, OPUS, TS, WAV, WAVE, WEBA, and WEBM. ## Canonical workflow for YouTube POST https://www.plainscribe.com/api/v1/transcriptions with: ``` { "source": { "type": "youtube", "url": "https://www.youtube.com/watch?v=VIDEO_ID", "language": "auto" }, "mode": "transcription" } ``` Then poll and retrieve results using the same job links as file transcription. ## Endpoints - POST /api/v1/uploads — create direct upload credentials - POST /api/v1/transcriptions — start file or YouTube transcription - GET /api/v1/transcriptions — list jobs - GET /api/v1/transcriptions/{id} — get job status - GET /api/v1/transcriptions/{id}/result — get JSON or exported transcript - DELETE /api/v1/transcriptions/{id} — delete a completed or failed job and artifacts - GET /api/v1/credits — get available credits ## Retry behavior POST requests require `Idempotency-Key`. Generate a key once for each intended operation. If a response is lost or times out, retry with that same key and a byte-for-byte equivalent request body. Use a new key for a new operation. A completed retry replays the original result. Reusing the key with a different request body returns an idempotency conflict. A request still executing returns a conflict and `Retry-After` guidance. GET result requests for processing jobs return `result_not_ready` and `Retry-After: 5`. Rate-limited requests return HTTP 429, a structured `rate_limit_exceeded` error, RateLimit headers, and `Retry-After`. ## Error envelope Errors use: ``` { "error": { "code": "stable_machine_code", "message": "Human-readable explanation.", "request_id": "uuid", "details": {} } } ``` Important codes include `invalid_api_key`, `insufficient_credits`, `upload_incomplete`, `file_size_mismatch`, `unreadable_media`, `duration_unavailable`, `result_not_ready`, `no_speech`, `transcription_timed_out`, `transcription_failed`, and `rate_limit_exceeded`. ## Billing and user confirmation Creating an upload does not spend credits. Starting a transcription can spend credits. If the user has not clearly asked to transcribe media, confirm before creating the transcription job. `GET /credits` can be used to check balance. Do not retry HTTP 402 automatically; ask the user to add credits. ## Data lifecycle - Invalid or rejected uploads are deleted immediately when possible. - Raw media is deleted after successful or failed processing. - A scheduled cleanup sweep retries terminal cleanup and deletes orphaned raw uploads. - Unconsumed API uploads expire after 24 hours. - Transcript artifacts automatically expire after 30 days. - The user can delete terminal transcripts sooner with the DELETE endpoint. Privacy policy: https://www.plainscribe.com/privacy ## Programmatic discovery Use the OpenAPI document for schema generation and tool calling. Use SKILL.md for workflow, safety, and user-confirmation guidance. REST is the source of truth; MCP and platform-specific integrations should remain thin adapters over it.