SDKs
Transcodely ships three official server-side SDKs over the same Connect-RPC + custom JSON wire format. Each SDK gives you typed resource namespaces, auto-pagination, auto-idempotency on write calls, typed error classes, and Watch streams that auto-reconnect on transient failures.
The SDKs are thin transports — wire-format codec parity is enforced by a port of internal/connect/codec.go in each repo. The behavior you read about elsewhere in these docs (HLS path templates, codec compatibility, pricing, etc.) is identical whether you call the API by SDK or by raw HTTP.
Available SDKs
| Language | Package | Min runtime | Version |
|---|---|---|---|
| JavaScript / TypeScript | @transcodely/sdk | Node.js 20+ | 0.3.7 |
| Python | transcodely | Python 3.10+ | 0.3.8 |
| Go | github.com/transcodely/transcodely-go | Go 1.23+ | 0.3.8 |
These are pre-1.0 SemVer releases — minor versions may include breaking changes until 1.0.
All three SDKs cover 100% of the public RPC surface — 74 RPCs across 11 services (Job, Video, Preset, Origin, App, APIKey, Organization, Membership, User, Health, Webhook). Anything you can do over HTTP, you can do through any SDK with native idioms.
Install and authenticate
Each SDK takes the API key explicitly so the calling code stays in control. The conventional environment variable is TRANSCODELY_API_KEY — read it once at startup and pass it in.
// $ npm install @transcodely/sdk
import { Transcodely } from "@transcodely/sdk";
const client = new Transcodely({
apiKey: process.env.TRANSCODELY_API_KEY!,
});# $ pip install transcodely
import os
from transcodely import Transcodely
with Transcodely(api_key=os.environ["TRANSCODELY_API_KEY"]) as client:
...// $ go get github.com/transcodely/transcodely-go
package main
import (
"log"
"os"
"github.com/transcodely/transcodely-go"
)
func main() {
client, err := transcodely.New(os.Getenv("TRANSCODELY_API_KEY"))
if err != nil {
log.Fatal(err)
}
_ = client
}See Authentication for the full key lifecycle and API Keys for details.
Your first job
The same Create-Job call in four ways. Each SDK accepts native types; everything is serialized to the snake_case JSON the API expects.
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/Create
-H "Authorization: Bearer {{API_KEY}}"
-H "Content-Type: application/json"
-d '{
"input_url": "https://storage.example.com/source.mp4",
"output_origin_id": "ori_x9y8z7w6v5",
"outputs": [
{
"type": "hls",
"video": [{ "codec": "h264", "resolution": "1080p" }]
}
]
}'import { Transcodely, OutputFormat, VideoCodec, Resolution } from "@transcodely/sdk";
const client = new Transcodely({ apiKey: process.env.TRANSCODELY_API_KEY! });
const job = await client.jobs.create({
inputUrl: "https://storage.example.com/source.mp4",
outputOriginId: "ori_x9y8z7w6v5",
outputs: [
{
type: OutputFormat.HLS,
video: [{ codec: VideoCodec.H264, resolution: Resolution.RESOLUTION_1080P }],
},
],
});
console.log(job.id, job.status);
// "job_a1b2c3d4e5f6" 1 (JOB_STATUS_PENDING)import os
from transcodely import Transcodely
with Transcodely(api_key=os.environ["TRANSCODELY_API_KEY"]) as client:
job = client.jobs.create(
input_url="https://storage.example.com/source.mp4",
output_origin_id="ori_x9y8z7w6v5",
outputs=[
{
"type": "hls",
"video": [{"codec": "h264", "resolution": "1080p"}],
}
],
)
print(job.id, job.status)
# "job_a1b2c3d4e5f6" 1import (
"context"
"log"
"os"
"github.com/transcodely/transcodely-go"
)
client, err := transcodely.New(os.Getenv("TRANSCODELY_API_KEY"))
if err != nil {
log.Fatal(err)
}
job, err := client.Jobs.Create(context.Background(), &transcodely.JobCreateParams{
InputUrl: "https://storage.example.com/source.mp4",
OutputOriginId: "ori_x9y8z7w6v5",
Outputs: []*transcodely.OutputSpec{{
Type: transcodely.OutputFormatHLS,
Video: []*transcodely.VideoVariant{
{Codec: transcodely.VideoCodecH264, Resolution: transcodely.Resolution1080P},
},
}},
})
if err != nil {
log.Fatal(err)
}
log.Printf("%s %s", job.GetId(), job.GetStatus())The "hls", "h264", "1080p" strings are the API’s wire format. Each SDK accepts its native enum type and serializes to the lowercase string for you.
Calendar API versioning
Every SDK pins a calendar-versioned API and sends Transcodely-Version: 2026-05-03 on every request. Non-breaking changes ship under the same date; a breaking change would ship under a new one, with requests pinned to an earlier date keeping the behavior they were written against.
Currently supported: 2026-05-03. That is the only version in the registry, and every released SDK pins it. Released versions are never removed from the registry — a client pinned to a date that worked keeps working.
Pinning is optional. Omit the header and the request is served under the current version. That is what the dashboard does, and it is a supported way to call the API rather than an oversight.
Pinning something unlisted is an error. The version you send is validated against the registry: an unknown or malformed value is rejected with invalid_argument and an error-code of invalid_api_version, naming both the value you sent and the versions that exist. Every response — including that one — carries a Transcodely-Supported-Versions header, so a client that guessed wrong can discover the right value without reading this page.
Upgrading the SDK is the cleanest way to move forward, but you can set the version per client:
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/Create
-H "Authorization: Bearer {{API_KEY}}"
-H "Content-Type: application/json"
-H "Transcodely-Version: 2026-05-03"
-d '{ "input_url": "...", "output_origin_id": "ori_...", "outputs": [...] }'new Transcodely({ apiKey, apiVersion: "2026-05-03" });Transcodely(api_key=..., api_version="2026-05-03")transcodely.New(apiKey, transcodely.WithAPIVersion("2026-05-03"))Hand-rolled clients predating the header rename may send X-API-Version instead; it is still accepted as a fallback. New clients should send Transcodely-Version.
What you get
Every SDK exposes the same Stripe-style facade:
- Lazy resource namespaces —
client.jobs,client.videos,client.presets,client.origins,client.apps,client.webhookEndpoints,client.events,client.apiKeys,client.organizations,client.memberships,client.users,client.health. Unused namespaces don’t load their generated types. - Auto-pagination — every
listreturns an iterable that walks pages for you. See Pagination. - Auto-idempotency — write methods get an auto-generated UUID v4
Idempotency-Key. The Go SDK scopes this toCreatecalls; the JS and Python SDKs cover most writes (Update,Delete,Cancel, and more). Override per-call when you need cross-process safety. See Idempotency. - Typed errors — 1 base class plus 12 concrete error types you match with
instanceof/isinstance/errors.As. See Errors. - Watch streams —
client.jobs.watch(id)returns an iterator that auto-reconnects on transient failures and filters heartbeats by default. - Signed webhooks — a one-call verifier (
constructEvent/construct_event/ConstructEvent) checks a delivery’s signature and timestamp and decodes it into a typed event. See Webhook Integration. - Request IDs — every error and the most recent response carry a
req_*ID for log correlation.
Per-language guides
Pick your language for install, authentication, and end-to-end task patterns:
Direct HTTP access
If the SDK doesn’t fit your stack, every endpoint is reachable over HTTP. All endpoints accept JSON via POST at https://api.transcodely.com/transcodely.v1.{Service}/{Method}:
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/Create
-H "Authorization: Bearer {{API_KEY}}"
-H "Content-Type: application/json"
-H "Transcodely-Version: 2026-05-03"
-d '{ "input_url": "...", "output_origin_id": "ori_...", "outputs": [...] }'See the API Reference for the full surface.