Documentation

Playhead is an MCP server and a REST API over the same engine. Agents use the tools; your own code uses the endpoints.

Quickstart

Add the server to your agent, then ask a question with a link in it. A free account starts with 60 credits and needs no card.

Claude Code
claude mcp add playhead -e PLAYHEAD_API_KEY=sk_live_… -- npx -y @playhead/mcp

For Claude on the web and on your phone, add https://mcp.tryplayhead.com/mcp as a custom connector and sign in — there is no key to copy.

MCP tools

Three tools. The agent picks between them from the question it was asked.

watch_video(url, start?, end?, detail?, language?)

Contact sheets as images, each preceded by its timestamp anchor, plus coverage and the next step.

The default. Without start and end it covers the complete video.

inspect_frame(url, t)

One frame at 1560 px on its long edge.

Reading text or judging a typeface. Even motion tiles are too small for that.

get_transcript(url, words?, language?)

Plain text, optionally with word-level timings.

The question is about what is said, not what is shown. Costs no image tokens.

Set language when the audio is mostly music, crowd or engine noise. Language detection misfires there, and a wrong language returns confident nonsense. Naming it also skips a detection pass. Every transcript reports whether the audio was speech at all — music scored over a video transcribes into sentences nobody said, and the response says so instead of handing you lyrics as dialogue.

Detail levels

Looking closer means fewer frames per sheet, never a bigger image — models downscale anything past 1568 px on the long edge. Higher levels are capped to short windows, and an over-long request answers with the call that would work.

LevelRatePer sheetMax window
overview0.5–2 fps30 framesno limit
standard5 fps30 framesno limit
detail5 fps6 frames30 s
fine10 fps2 frames10 s
motion30 fps2 frames3 s
singleone frame1 framea moment

A client caps one tool result at 1 MB, so a call returns at most two sheets as images. The rest come back as links with the exact follow-up call.

REST API

Base URL https://api.tryplayhead.com. Every response states what it covered, so nothing is silently left out.

Analyze a video
curl -X POST https://api.tryplayhead.com/v1/frames \
  -H "Authorization: Bearer $PLAYHEAD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://youtube.com/watch?v=…", "detail": "standard"}'

POST /v1/frames

Turn a video into contact sheets. Takes url, optional start and end, a detail level and an optional language. Returns the sheets, the geometry, exact frame times, what was covered and the estimated vision tokens.

POST /v1/transcript

Text only, no images. Optionally with word-level timestamps. Costs no vision tokens, so use it when the question is about what is said.

POST /v1/uploads

Send your own file when it is private, geo-blocked or never was on a platform. Returns an upload id you can pass as the url.

GET /v1/jobs/:jobId

Status of a queued job. Long videos are processed asynchronously.

GET /v1/credits

Balance, plan and what has been spent this period.

GET /v1/detail-levels

The six levels with their rates, grids and window limits, straight from the engine.

DELETE /v1/videos/:videoId

Delete a video and everything derived from it — sheets, transcript and cached artifacts.

Authentication

Send an API key as a bearer token. Keys are created in the dashboard and shown once — we store only a hash, so a lost key is replaced, never recovered.

Header
Authorization: Bearer sk_live_…

The remote MCP server passes the token through to the API, which resolves it to an organization and bills that organization. One deployment serves everyone; the token decides whose credits are spent.

Errors

Errors are written for an agent to act on, not just to report. When a window is too long for a level, the response carries the concrete call that would work:

Response
{
  "error": {
    "type": "window_too_long",
    "message": "motion is limited to 3s windows; you asked for 5s.",
    "suggestion": { "start": 0, "end": 3, "detail": "motion" },
    "max_window_seconds": 3
  }
}