A machine-readable API: OpenAPI 3.1, Markdown docs, and llms.txt
If you integrate Transloadit without one of our SDKs, you have had to read the docs and hand-write every HTTP call, request body, and webhook handler. Now the whole API is published as an OpenAPI 3.1 document, including the webhook we send you, and every page on our website is also available as Markdown. Generate a typed client in your language, import the API into Postman, check webhook payloads against real schemas, and point your AI coding agent at docs it can actually read.
What the spec covers
The document lives at https://api2.transloadit.com/openapi.json. The same file is mirrored at
https://transloadit.com/openapi.json. It is OpenAPI 3.1.2 for version 2.0.0 of our API, and it
has 43 operations across 26 paths:
- Assemblies: create, check status, cancel, and replay. Assembly Notifications can be listed and replayed too.
- Templates, Template Credentials, and Auth Keys with their scopes.
- Resumable tus uploads, Assembly statistics, billing, and queue statistics.
POST /tokenfor OAuth 2.0 client-credentials bearer tokens. Each operation lists the scope it needs, such astemplates:read.
The request schemas include the full Assembly
Instructions. Each Step is described by the parameter schema of its
Robot. Responses list the error codes each endpoint can
return, such as TEMPLATE_LIST_ERROR. As of today, the spec's webhooks section also describes the Assembly
Notification that we POST to your notify_url.
Generate a typed client
Here is the TypeScript route, with openapi-typescript for the types and
its companion openapi-fetch for the calls:
mkdir my-app && cd my-app
npm init -y && npm pkg set type=module
npm install openapi-fetch @transloadit/utils ajv
npm install -D openapi-typescript typescript @types/node
npx openapi-typescript https://api2.transloadit.com/openapi.json \
--default-non-nullable false -o transloadit-api.d.ts
By default, openapi-typescript marks every property that has a default value as required. That
would force you to pass Robot parameters that are optional in the spec. --default-non-nullable false keeps them optional. Our tsconfig.json sets skipLibCheck, because the generated file
contains a recursive JSON-value type that TypeScript otherwise reports as an error:
{
"compilerOptions": {
"module": "nodenext",
"target": "esnext",
"strict": true,
"noEmit": true,
"skipLibCheck": true,
"allowImportingTsExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}
This list-templates.ts script lists your Templates. It
uses signature authentication, and the signParams helper from @transloadit/utils handles the
signing:
import { signParams } from '@transloadit/utils'
import createClient from 'openapi-fetch'
import type { paths } from './transloadit-api.d.ts'
const { TRANSLOADIT_KEY: key, TRANSLOADIT_SECRET: secret } = process.env
if (!key || !secret) throw new Error('Set TRANSLOADIT_KEY and TRANSLOADIT_SECRET')
const client = createClient<paths>({ baseUrl: 'https://api2.transloadit.com' })
const expires = new Date(Date.now() + 5 * 60_000).toISOString()
const params = JSON.stringify({ auth: { key, expires }, pagesize: 3 })
const signature = await signParams(params, secret)
const { data, error } = await client.GET('/templates', {
params: { query: { params, signature } },
})
if (error) throw new Error(`${error.error}: ${error.message}`)
console.log(`${data.count} Templates, showing ${data.items.length}:`)
for (const template of data.items) console.log(`- ${template.id} ${template.name}`)
npx tsc -p . type-checks the script. Node.js 22.18 and later can run the TypeScript file directly:
$ TRANSLOADIT_KEY=MY_AUTH_KEY TRANSLOADIT_SECRET=MY_SECRET_KEY node list-templates.ts
1726 Templates, showing 3:
- 1329f8… image-enhancer-v6
- d253c5… webm-to-mp4-v6
- e751d2… convert-an-image-from-avif-to-jpg-v6
The types come from the spec, so tsc stops a mistyped path such as '/templats' or a field such
as template.nmae before the request is sent. After the if (error) check, data is known to be
the success response.
Because we publish standard OpenAPI 3.1, you can use the generator for your own language instead.
Postman, Insomnia, and similar tools import the document from its URL. As a check, we ran the spec
through Postman's openapi-to-postmanv2 converter. It produced a collection with all 43 requests
in 12 folders. In an API client, bearer tokens are the easiest way to sign in: get one from
POST /token, then send it as Authorization: Bearer ….
Typed webhooks and live status events
We send each Assembly Notification to your notify_url as two form fields. transloadit holds the
Assembly Status as JSON. signature is a lowercase hex HMAC-SHA1 of that exact string, made with
your Auth Secret. The payload schema is in the spec as assemblyNotificationPayload, and it is also
published as a standalone JSON Schema. After you
verify the signature, you can check the payload against
that schema and get a typed result:
import { Ajv } from 'ajv'
import type { components } from './transloadit-api.d.ts'
type AssemblyNotification = components['schemas']['assemblyNotificationPayload']
const url = 'https://transloadit.com/api-reference/schemas/webhooks/verified-json-payload.json'
const response = await fetch(url)
if (!response.ok) throw new Error(`GET ${url} failed with HTTP ${response.status}`)
const validate = new Ajv({ strict: false }).compile<AssemblyNotification>(await response.json())
// Call this only after verifying `signature` over the raw `transloadit` field
export function parseNotification(transloadit: string): AssemblyNotification {
const payload: unknown = JSON.parse(transloadit)
if (!validate(payload)) throw new Error(`Unexpected payload: ${validate.errors?.[0]?.message}`)
return payload
}
We tested this against a real Assembly that used the
🤖 /http/import and 🤖 /image/resize
Robots. Its final status passed validation. TypeScript
then narrowed it on ok === 'ASSEMBLY_COMPLETED', which gave us access to results.resized. A
payload with a made-up ok value was rejected with must be equal to one of the allowed values.
For live progress, every Assembly Status includes an update_stream_url. Send a GET request with
Accept: text/event-stream to that URL and you receive Server-Sent Events as the Assembly runs:
assembly_upload_finished, assembly_result_finished, assembly_execution_progress,
assembly_error, and a closing assembly_finished message. The
stream reference documents each event and links a
JSON Schema for every event payload.
Every page as Markdown, and llms.txt for agents
AI coding agents write better integrations when they read clean Markdown instead of scraping HTML.
Every public page on transloadit.com now has a Markdown twin. To get it, replace the trailing
slash with .md, so /docs/api/webhooks/ becomes /docs/api/webhooks.md. You can also send
Accept: text/markdown to the regular URL. HTML responses advertise the twin in a Link header
with rel="alternate", so tools that read response headers can discover it.
$ curl -fsSL https://transloadit.com/docs/robots/image-resize.md
# Convert, resize, or watermark images
Robot: `/image/resize`
🤖/image/resize resizes, crops, changes colorization, rotation, and applies text and watermarks to images.
Stage: ga
…
For discovery, /llms.txt is a compact index. It links our
start pages, the Markdown docs for every Robot, and scoped indexes for the docs, API, Robots, SDKs,
and FAQ. It also links topic indexes for video, images, audio, documents, uploading, storage, and
troubleshooting. And it points agents to the spec:
$ curl -fsSL https://transloadit.com/llms.txt | grep -E 'OpenAPI|API endpoints'
- [Agent integration options](https://transloadit.com/mcp/): Upload, import, process, export, or retrieve files through MCP, OpenAPI, or an SDK.
- [API endpoints](https://transloadit.com/docs/api/llms.txt): Learn how you can leverage Transloadit’s file processing services most effectively
- [OpenAPI document](https://transloadit.com/openapi.json): Typed REST schema for generated clients and tools.
We still publish /llms-full.txt, a single file of about 1.5 MB. Agents usually do better when
they start from llms.txt and fetch only the pages they need. We wrote more about that approach in
Making APIs and documentation more accessible to AI tools. If you want
your agent to upload and process files itself rather than write code, use the
Transloadit MCP Server or our
agent skills. Our
AI agents guide helps you choose between them.
What to keep in mind
- With signature authentication,
paramsis a signed JSON string. TypeScript checks the request and the response, but it does not check what you put insideparams. The API validates that when you send the request. POST /assembliestakesmultipart/form-data. We found it simpler to send aFormDatabody with plainfetchand use the generated types for the response.- OpenAPI 3.1 cannot type the individual events of a stream. That is why the status stream is
documented in its reference page and event schemas, not as a regular path in
openapi.json. - For browser and mobile uploads, our SDKs remain the shortest path. They add resumable uploads, retries, and progress reporting on top of the same API.
Import https://api2.transloadit.com/openapi.json into your generator or API client, browse the
API reference, and create a free account to try it with your own Auth
Key. If a generator trips over something in the document, let us know.
