OpenAPI for agents
The whole API is published as an OpenAPI 3.1 document at https://api.tryplayhead.com/openapi.json, unauthenticated so a tool can read it before it has a key. That is the file an agent framework loads to turn Playhead into callable tools, and the one a code generator turns into a client in any language.
Last updated
The spec
OpenAPI 3.1, served unauthenticated and cached for an hour.
Specification URL
curl -s https://api.tryplayhead.com/openapi.json | jq '.paths | to_entries[] |
{path: .key, ops: (.value | keys)}'Wiring it into an agent
Four steps, and the fourth is the one that catches people out.
Fetch the spec
GET https://api.tryplayhead.com/openapi.json. It needs no authentication, on purpose — a tool has to be able to read it before it has a key.Register the operations as tools
Each operation carries an operationId, a summary and a description written for a reader with no other context. Those three fields are what a model uses to decide which call answers a question.Supply the credential
One bearer token on the Authorization header covers every operation. The scheme is declared as bearerAuth in components.securitySchemes.Handle the two answer shapes
Calls made with sync false return a QueuedJob rather than a result. Poll getJob until status is succeeded and read the result field.
from agents import Agent
from agents.tool import HostedMCPTool # or your framework's OpenAPI loader
spec = requests.get("https://api.tryplayhead.com/openapi.json").json()
agent = Agent(
name="video analyst",
tools=openapi_tools(spec, headers={
"Authorization": f"Bearer {os.environ['PLAYHEAD_API_KEY']}"
}),
)If your client speaks Model Context Protocol rather than OpenAPI, use the MCP server instead — it is the same engine with tool descriptions already written for an agent, and it handles the queueing and the sheet budget for you.
Generating a client
Any language your generator supports. The TypeScript one we maintain by hand, because a hand-written client can have better ergonomics than a generated one.
openapi-generator generate \
-i https://api.tryplayhead.com/openapi.json \
-g python \
-o ./playhead-pythonoapi-codegen -package playhead \
https://api.tryplayhead.com/openapi.json > playhead.gen.gonpm install @playhead/sdkWhat is in it
Eight operations, and the descriptions are written for a machine deciding between them rather than for a person browsing.
| operationId | Method and path | Chosen when |
|---|---|---|
createFrames | POST /v1/frames | The question is about what is shown. |
createTranscript | POST /v1/transcript | The question is about what is said. No vision tokens. |
createUpload | POST /v1/uploads | The file is private, geo-blocked or local. |
createUploadTicket | POST /v1/uploads/tickets | Bytes are somewhere your key is not. |
getJob | GET /v1/jobs/{jobId} | Polling work queued with sync false. |
getCredits | GET /v1/credits | Checking a balance before an expensive pass. |
getDetailLevels | GET /v1/detail-levels | Discovering the levels. No credential needed. |
deleteVideo | DELETE /v1/videos/{videoId} | Erasure. |
There is also an llms.txt at the site root — the same product described in prose, for a model answering a question rather than calling an endpoint.
Questions
- Can I add Playhead to a custom GPT as an Action?
- Yes. Import https://api.tryplayhead.com/openapi.json as the Action schema and set authentication to API key with a bearer token. Every operation has an operationId, which is what the Action builder names each call from.
- Can an agent framework load this as tools?
- Yes — that is what the spec is for. LangChain, LlamaIndex, the OpenAI Agents SDK and anything else that consumes OpenAPI can turn these eight operations into callable tools without a line of glue code.
- Can I generate a client in another language?
- Yes. It is a standard OpenAPI 3.1 document, so openapi-generator, Kiota, oapi-codegen or your generator of choice will emit a Python, Go, Java, C# or Rust client from it. The TypeScript one we maintain by hand is @playhead/sdk.
- Is the spec generated or written?
- Generated from the same objects the engine enforces. The detail levels, their window caps, their grids and their prices come out of the presets, so a client built against the spec cannot drift from what the server will accept.
- Does the spec describe a self-hosted deployment correctly?
- Yes. The servers block is filled in from the deployment's own public URL rather than from a constant, so an on-premise instance describes itself and a generated client talks to the right host.