The Job object
A job represents a video transcoding operation. Each job takes an input video and produces one or more output renditions based on your specifications. Jobs support real-time progress tracking, delayed start with cost review, and streaming updates.
Base path: transcodely.v1.JobService Requires: X-Organization-ID header on all endpoints.
Attributes
| Attribute | Type | Description |
|---|---|---|
id | string | Unique identifier. Prefixed with job_. |
input_url | string | Input video URL (when using direct URL mode). |
input_origin | object | null | Input origin reference (when using origin mode). |
output_origin | object | null | Output origin reference. |
status | enum | Current job status. One of: pending, probing, awaiting_confirmation, processing, completed, failed, canceled, partial. |
progress | integer | Overall progress percentage (0–100). |
priority | enum | Job priority. One of: economy, standard, premium. |
input_metadata | object | null | Input file metadata, populated after probing. See Input Metadata. |
outputs | array of objects | Output renditions. See The Output Object. |
thumbnails | array of objects | Thumbnail specifications. See Thumbnails. |
total_estimated_cost | number | Estimated cost in EUR. Present after probe completes. |
total_actual_cost | number | Actual cost in EUR. Present after outputs complete. |
error_code | string | Error code if failed. |
error_message | string | Error message if failed. |
webhook_url | string | Webhook notification URL. |
metadata | object | Custom key-value metadata. |
delayed_start | boolean | Whether this job requires confirmation before encoding. |
currency | string | Currency for cost fields (e.g., EUR). |
execution | object | null | Execution timing and telemetry. See Execution Timing. |
created_at | string | ISO 8601 timestamp. |
updated_at | string | ISO 8601 timestamp. |
probed_at | string | null | When probing completed. |
started_at | string | null | When processing started. |
completed_at | string | null | When job reached terminal state. |
confirmed_at | string | null | When delayed start job was confirmed. |
{
"id": "job_a1b2c3d4e5f6",
"input_url": "gs://my-bucket/uploads/video.mp4",
"input_origin": null,
"output_origin": {
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"provider": "gcs",
"path": "",
"bucket": "acme-video-assets"
},
"status": "completed",
"progress": 100,
"priority": "standard",
"input_metadata": {
"duration_ms": 125000,
"width": 1920,
"height": 1080,
"codec": "h264",
"bitrate_kbps": 8500,
"framerate": 30,
"file_size_bytes": 132710400
},
"outputs": [
{
"id": "out_m1n2o3p4q5",
"type": "mp4",
"status": "completed",
"video": {
"codec": "h264",
"resolution": "1080p",
"quality": "standard"
},
"output_url": "gs://acme-video-assets/2025/02/28/output_h264_1080p.mp4",
"file_size_bytes": 67108864
}
],
"total_estimated_cost": 0.85,
"total_actual_cost": 0.82,
"error_code": "",
"error_message": "",
"webhook_url": "https://api.example.com/webhooks/transcodely",
"metadata": {
"source": "upload-service",
"user_id": "usr_a1b2c3d4e5"
},
"delayed_start": false,
"currency": "EUR",
"execution": {
"probe_duration_ms": 1200,
"encode_duration_ms": 45000,
"total_duration_ms": 46200
},
"created_at": "2025-02-28T10:00:00Z",
"updated_at": "2025-02-28T10:01:30Z",
"probed_at": "2025-02-28T10:00:02Z",
"started_at": "2025-02-28T10:00:03Z",
"completed_at": "2025-02-28T10:01:30Z",
"confirmed_at": null
}Statuses
| Status | Description |
|---|---|
pending | Queued and waiting to be processed. |
probing | Analyzing the input file. |
awaiting_confirmation | Delayed start job paused for cost review. Call Confirm to proceed. |
processing | Actively transcoding. |
completed | All outputs completed successfully. |
failed | Job failed with an error. |
canceled | Canceled by the user. |
partial | Some outputs completed, others failed. |
Priorities
| Priority | Price multiplier | Description |
|---|---|---|
economy | 0.75x | Cost-optimized, slower encoding. |
standard | 1.0x | Balanced speed and cost. Default. |
premium | 2.0x | Fastest encoding, highest priority. |
Create a job
Create a new transcoding job with one or more output renditions.
POST /transcodely.v1.JobService/CreateParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
input_url | string | One of | Direct URL to the input video. Supported schemes: gs://, s3://, https://. Use this or input_origin_id, not both. |
input_origin_id | string | One of | Origin ID for the input source. The origin must have read permission. |
input_path | string | No | Path within the input origin. Required when using input_origin_id. |
output_origin_id | string | Yes | Origin ID for outputs. Must have write permission. |
outputs | array | Yes | Output specifications (1–10 outputs). See Output Specification. |
priority | enum | No | economy, standard, or premium. Default: standard. |
thumbnails | array | No | Thumbnail specifications (max 5). See Thumbnails. |
webhook_url | string | No | URL for status notifications (max 2048 chars). |
idempotency_key | string | No | Idempotency key (max 128 chars). Duplicate requests return the existing job. |
metadata | object | No | Custom key-value pairs (max 20 entries, keys max 64 chars, values max 1024 chars). |
delayed_start | boolean | No | If true, pauses after probing for cost review. Default: false. |
output_path_template | string | No | Output path template. Variables: {job_id}, {output_id}, {date}, {format}, {codec}, {resolution}, {quality}. |
Output specification
Each output can be defined inline or reference a preset. For the full reference of all output fields, see Output Specification.
| Field | Type | Required | Description |
|---|---|---|---|
type | enum | Yes* | mp4, webm, mkv, mov, hls, dash, or adaptive. *Required unless using preset. |
video | array | Yes* | Video variants (1–20). *Required unless using preset. |
audio | array | No | Audio tracks for streaming outputs. Max 8 tracks. |
hls | object | No | HLS-specific configuration. |
dash | object | No | DASH-specific configuration. |
segments | object | No | Segment configuration for streaming types. |
path_template | string | No | Per-output path template (overrides job-level template). |
preset | string | No | Preset ID (e.g., pst_abc123) or slug (e.g., web_1080p_standard). |
subtitle_tracks | array | No | Subtitle track configuration (max 8). See Subtitles. |
drm | object | No | DRM encryption configuration. Streaming outputs only. See DRM & Encryption. |
content_aware | object | No | Content-aware encoding. See Content-Aware Encoding. |
VideoVariant
Each variant defines a single video encode rendition. For the full reference including codec-specific options (H264Options, H265Options, VP9Options, AV1Options) and HDR configuration, see Video Variants.
| Field | Type | Required | Description |
|---|---|---|---|
codec | enum | Yes | h264, h265, vp9, or av1. |
resolution | enum | No | 480p, 720p, 1080p, 1440p, 2160p, or 4320p. |
quality | enum | No | economy, standard, or premium. |
framerate | integer | No | Target frame rate. 0 = keep original. |
width | integer | No | Custom width in pixels (128–7680). |
height | integer | No | Custom height in pixels (128–4320). |
bitrate | integer | No | Target bitrate in kbps (100–240000). |
h264 | object | No | H.264-specific options. |
h265 | object | No | H.265-specific options. |
vp9 | object | No | VP9-specific options. |
av1 | object | No | AV1-specific options. |
hdr | object | No | HDR configuration. |
Returns
Returns a Job object.
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/Create
-H "Authorization: Bearer ak_live_abc123"
-H "X-Organization-ID: org_f6g7h8i9j0"
-H "Content-Type: application/json"
-d '{
"input_url": "gs://my-bucket/uploads/video.mp4",
"output_origin_id": "ori_x9y8z7w6v5",
"outputs": [
{
"type": "mp4",
"video": [
{"codec": "h264", "resolution": "1080p", "quality": "standard"}
]
}
],
"priority": "standard"
}'const { job } = await client.jobs.create({
input_url: "gs://my-bucket/uploads/video.mp4",
output_origin_id: "ori_x9y8z7w6v5",
outputs: [
{
type: "mp4",
video: [{ codec: "h264", resolution: "1080p", quality: "standard" }],
},
],
priority: "standard",
});job = client.jobs.create(
input_url="gs://my-bucket/uploads/video.mp4",
output_origin_id="ori_x9y8z7w6v5",
outputs=[{
"type": "mp4",
"video": [{"codec": "h264", "resolution": "1080p", "quality": "standard"}],
}],
priority="standard",
)job, err := client.Jobs.Create(ctx, &transcodely.CreateJobRequest{
InputURL: "gs://my-bucket/uploads/video.mp4",
OutputOriginID: "ori_x9y8z7w6v5",
Outputs: []transcodely.OutputSpec{{
Type: transcodely.OutputFormatMP4,
Video: []transcodely.VideoVariant{{
Codec: transcodely.VideoCodecH264,
Resolution: transcodely.Resolution1080P,
Quality: transcodely.QualityStandard,
}},
}},
Priority: transcodely.PriorityStandard,
}){
"job": {
"id": "job_a1b2c3d4e5f6",
"input_url": "gs://my-bucket/uploads/video.mp4",
"input_origin": null,
"output_origin": {
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"provider": "gcs",
"path": "",
"bucket": "acme-video-assets"
},
"status": "pending",
"progress": 0,
"priority": "standard",
"input_metadata": null,
"outputs": [],
"metadata": {},
"delayed_start": false,
"currency": "EUR",
"execution": null,
"created_at": "2025-02-28T10:00:00Z",
"updated_at": "2025-02-28T10:00:00Z"
}
}Retrieve a job
Retrieve a job by its ID.
POST /transcodely.v1.JobService/GetParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Job ID (e.g., job_a1b2c3d4e5f6). |
Returns
Returns a Job object.
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/Get
-H "Authorization: Bearer ak_live_abc123"
-H "X-Organization-ID: org_f6g7h8i9j0"
-H "Content-Type: application/json"
-d '{"id": "job_a1b2c3d4e5f6"}'const { job } = await client.jobs.get({ id: "job_a1b2c3d4e5f6" });job = client.jobs.get(id="job_a1b2c3d4e5f6")job, err := client.Jobs.Get(ctx, &transcodely.GetJobRequest{
ID: "job_a1b2c3d4e5f6",
}){
"job": {
"id": "job_a1b2c3d4e5f6",
"input_url": "gs://my-bucket/uploads/video.mp4",
"input_origin": null,
"output_origin": {
"id": "ori_x9y8z7w6v5",
"name": "Production GCS Bucket",
"provider": "gcs",
"path": "",
"bucket": "acme-video-assets"
},
"status": "completed",
"progress": 100,
"priority": "standard",
"input_metadata": {
"duration_ms": 125000,
"width": 1920,
"height": 1080,
"codec": "h264",
"bitrate_kbps": 8500,
"framerate": 30,
"file_size_bytes": 132710400
},
"outputs": [
{
"id": "out_m1n2o3p4q5",
"type": "mp4",
"status": "completed",
"video": {
"codec": "h264",
"resolution": "1080p",
"quality": "standard"
},
"output_url": "gs://acme-video-assets/2025/02/28/output_h264_1080p.mp4",
"file_size_bytes": 67108864
}
],
"total_estimated_cost": 0.85,
"total_actual_cost": 0.82,
"error_code": "",
"error_message": "",
"webhook_url": "https://api.example.com/webhooks/transcodely",
"metadata": {
"source": "upload-service",
"user_id": "usr_a1b2c3d4e5"
},
"delayed_start": false,
"currency": "EUR",
"execution": {
"probe_duration_ms": 1200,
"encode_duration_ms": 45000,
"total_duration_ms": 46200
},
"created_at": "2025-02-28T10:00:00Z",
"updated_at": "2025-02-28T10:01:30Z",
"probed_at": "2025-02-28T10:00:02Z",
"started_at": "2025-02-28T10:00:03Z",
"completed_at": "2025-02-28T10:01:30Z",
"confirmed_at": null
}
}List jobs
List jobs with optional status filtering and pagination.
POST /transcodely.v1.JobService/ListParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | enum | No | Filter by status: pending, probing, processing, completed, failed, canceled, partial, awaiting_confirmation. |
pagination | object | No | limit (default 20, max 100) and cursor for pagination. |
Returns
Returns a list of Job objects and pagination metadata.
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/List
-H "Authorization: Bearer ak_live_abc123"
-H "X-Organization-ID: org_f6g7h8i9j0"
-H "Content-Type: application/json"
-d '{"status": "processing", "pagination": {"limit": 20}}'const { jobs, pagination } = await client.jobs.list({
status: "processing",
pagination: { limit: 20 },
});response = client.jobs.list(status="processing", pagination={"limit": 20})resp, err := client.Jobs.List(ctx, &transcodely.ListJobsRequest{
Status: transcodely.JobStatusProcessing,
Pagination: &transcodely.PaginationRequest{Limit: 20},
}){
"jobs": [
{
"id": "job_a1b2c3d4e5f6",
"input_url": "gs://my-bucket/uploads/video.mp4",
"status": "processing",
"progress": 45,
"priority": "standard",
"created_at": "2025-02-28T10:00:00Z",
"updated_at": "2025-02-28T10:02:00Z"
},
{
"id": "job_b2c3d4e5f6g7",
"input_url": "gs://my-bucket/uploads/interview.mov",
"status": "processing",
"progress": 78,
"priority": "premium",
"created_at": "2025-02-28T09:45:00Z",
"updated_at": "2025-02-28T10:02:00Z"
}
],
"pagination": {
"next_cursor": "eyJpZCI6ImpvYl9iMmMzZDRlNWY2ZzcifQ",
"total_count": 42
}
}Cancel a job
Cancel a pending or running job. Completed outputs are preserved, in-progress outputs are stopped.
POST /transcodely.v1.JobService/CancelParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Job ID. |
Returns
Returns the Job object with status: "canceled".
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/Cancel
-H "Authorization: Bearer ak_live_abc123"
-H "X-Organization-ID: org_f6g7h8i9j0"
-H "Content-Type: application/json"
-d '{"id": "job_a1b2c3d4e5f6"}'const { job } = await client.jobs.cancel({ id: "job_a1b2c3d4e5f6" });job = client.jobs.cancel(id="job_a1b2c3d4e5f6")job, err := client.Jobs.Cancel(ctx, &transcodely.CancelJobRequest{
ID: "job_a1b2c3d4e5f6",
}){
"job": {
"id": "job_a1b2c3d4e5f6",
"input_url": "gs://my-bucket/uploads/video.mp4",
"status": "canceled",
"progress": 45,
"priority": "standard",
"created_at": "2025-02-28T10:00:00Z",
"updated_at": "2025-02-28T10:05:00Z",
"completed_at": "2025-02-28T10:05:00Z"
}
}Confirm a job
Confirm a delayed start job to begin encoding. Only valid when the job is in awaiting_confirmation status.
POST /transcodely.v1.JobService/ConfirmParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Job ID. |
Returns
Returns the Job object with status transitioning to processing.
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/Confirm
-H "Authorization: Bearer ak_live_abc123"
-H "X-Organization-ID: org_f6g7h8i9j0"
-H "Content-Type: application/json"
-d '{"id": "job_a1b2c3d4e5f6"}'const { job } = await client.jobs.confirm({ id: "job_a1b2c3d4e5f6" });job = client.jobs.confirm(id="job_a1b2c3d4e5f6")job, err := client.Jobs.Confirm(ctx, &transcodely.ConfirmJobRequest{
ID: "job_a1b2c3d4e5f6",
}){
"job": {
"id": "job_a1b2c3d4e5f6",
"input_url": "gs://my-bucket/uploads/video.mp4",
"status": "processing",
"progress": 0,
"priority": "standard",
"delayed_start": true,
"created_at": "2025-02-28T10:00:00Z",
"updated_at": "2025-02-28T10:05:00Z",
"confirmed_at": "2025-02-28T10:05:00Z"
}
}Watch a job
Stream real-time updates for a job. The server sends the current state immediately, then pushes updates as status or progress changes. The stream closes when the job reaches a terminal state.
This is a server-streaming RPC.
POST /transcodely.v1.JobService/WatchParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Job ID. |
Stream events
Each message in the stream contains the current Job object, an event type, and a server timestamp.
| Event | Description |
|---|---|
snapshot | Initial state sent on connection. |
progress | Progress percentage changed (debounced 200ms). |
status_change | Job status transitioned. |
completed | Terminal state reached. Stream closes after this. |
heartbeat | Keepalive every 30 seconds. |
Returns
Newline-delimited JSON stream of job state updates.
curl -X POST https://api.transcodely.com/transcodely.v1.JobService/Watch
-H "Authorization: Bearer ak_live_abc123"
-H "X-Organization-ID: org_f6g7h8i9j0"
-H "Content-Type: application/json"
-d '{"id": "job_a1b2c3d4e5f6"}'for await (const event of client.jobs.watch({ id: "job_a1b2c3d4e5f6" })) {
console.log(`${event.event}: ${event.job.progress}%`);
if (event.event === "completed") break;
}for event in client.jobs.watch(id="job_a1b2c3d4e5f6"):
print(f"{event.event}: {event.job.progress}%")
if event.event == "completed":
breakstream, err := client.Jobs.Watch(ctx, &transcodely.WatchJobRequest{
ID: "job_a1b2c3d4e5f6",
})
for event := range stream.Events() {
fmt.Printf("%s: %d%%\n", event.Event, event.Job.Progress)
if event.Event == transcodely.EventCompleted {
break
}
}{"result": {"job": {"id": "job_a1b2c3d4e5f6", "status": "processing", "progress": 45}, "event": "snapshot", "server_time": "2025-02-28T10:05:00Z"}}
{"result": {"job": {"id": "job_a1b2c3d4e5f6", "status": "processing", "progress": 85}, "event": "progress", "server_time": "2025-02-28T10:05:30Z"}}
{"result": {"job": {"id": "job_a1b2c3d4e5f6", "status": "completed", "progress": 100}, "event": "completed", "server_time": "2025-02-28T10:05:45Z"}}