Jobs

A Job is an instruction set that can be submitted to Video Toolkit. Usually such jobs consist of downloading files for processing, processing and uploading of the results. Each Job holds a collection of tasks which are one or more tool definitions.

See Concepts for the definitions of job, task, tool, region, and job_bundle. For a worked end-to-end example with curl, see Quickstart.

Endpoint and authentication

All requests in this section target https://api.vtk.castlabs.com.

All requests require a Bearer token in the Authorization header, obtained from the Castlabs identity provider:

Authorization: Bearer <token>

Most endpoints are scoped to an organization, identified by organization_urn in the URL path (for example urn:janus:organization:acme). In addition, the x-castlabs-organization header indicates which organization membership to use for authorization. In most cases both values are the same; they only differ for cross-organization access.

x-castlabs-organization: <organization_urn>

Access is controlled by IAM-style policies attached to your role. Each endpoint requires a specific vtk:* action on a resource ARN of the form arn:vtk:api::<org>:<path>. The required action is shown with every endpoint below.

Job definition

The structure of a job is a list of tasks:

{
    "tasks": [
        { "tool": "<tool1>", "parameters": { } },
        { "tool": "<tool2>", "parameters": { } }
    ]
}

AWS region selection

Define the AWS region the job shall be started in (usually a resource pool was created upfront for your organization and targeted AWS regions):

{
    "region": "aws:eu-central-1",
    "tags": ["Tag ID", "Tag ID 2"],
    "tasks": [
        { "tool": "<tool1>", "parameters": { } }
    ]
}

If region is omitted, the region is determined automatically.

Mounts (declarative read-only inputs)

Instead of downloading inputs with a storage:get task, a job can declare mounts: S3 prefixes that appear read-only inside every task’s working directory, served on demand via mountpoint-s3. Tools read directly from S3 (with a local disk cache) — nothing is downloaded up front, which matters when tasks need only parts of large files (e.g. one 10-second segment of a 50 GB master).

{
    "region": "sfn:us-east-1",
    "mounts": [
        {
            "credential_source": "https://abc123.execute-api.eu-west-1.amazonaws.com/prod/credentials",
            "prefix": "s3://acme-bucket/masters/",
            "files": ["movie.mov", "audio/en.wav"],
            "target": "input"
        }
    ],
    "tasks": [
        {
            "tool": "ffmpeg:cmd",
            "parameters": { "arguments": ["-i", "input/movie.mov", "..."] }
        }
    ]
}

Field

Description

prefix

Required. s3://bucket/key/prefix/ — the unit that gets mounted. s3://bucket/ (whole bucket) is allowed.

credential_source

Optional. URL of a credential dispenser that vends temporary credentials for the prefix. Credentials refresh automatically for the lifetime of the mount; long jobs never see expired credentials. Omitted → the worker’s own role is used.

files

Optional. Whitelist of object keys relative to prefix. Each appears at <target>/<file>; nothing else under the prefix is visible to the tools.

target

Directory inside the job working directory where the files appear. Optional in file mode (default: the working directory itself); required in directory mode.

Directory mode: omit files and the entire prefix appears as a directory at <target> — the right shape for jobs with hundreds of input files. Note this exposes everything under the prefix to the job’s tasks; the prefix is the access-control boundary.

Rules: target and files entries must be relative paths without .. segments; files, when present, must be non-empty. Mounts are read-only — task outputs are written to the working directory as usual.

Every task of the job sees the same mounts regardless of which machine it runs on, and tasks running on the same machine share one mount (and its cache) per distinct (credential_source, prefix).

Organization context

In the new API the organization is part of the URL path (/o/{organization_urn}/...) and the x-castlabs-organization header — it is no longer specified inside the job body.

Naming/Tagging jobs

Jobs don’t have names by default. Use tags to group and find jobs (for example one tag for a category and one for an asset ID as referenced in your media asset management system):

{
    "tags": ["2026-Encodings", "Metropolis_1927"],
    "tasks": [
        { "tool": "<tool1>", "parameters": { } }
    ]
}

Additional submission fields

Field

Description

tasks

Required. One or more tasks. Each task has a tool, parameters, and optionally a version.

region

Processing region (e.g. aws:eu-west-1).

mounts

Declarative read-only S3 inputs, mounted into every task. See Mounts.

tags

List of tag strings for organizing/filtering.

notify

Email address (or notification URL) used when the job completes. See Status.

priority

Integer from 1 (highest) to 10 (lowest, default).

role_arn

Role for cross-account access to input/output storage.

Jobs API

Submit a job

POST /o/{organization_urn}/jobs

Permission: vtk:CreateJob on arn:vtk:api::{organization_urn}:jobs

Creates a new video processing job with the specified tasks. If a tool version is not specified, the version pinned for your organization is used, or the latest available version.

curl -X POST https://api.vtk.castlabs.com/o/urn:janus:organization:acme/jobs \
  -H 'Authorization: Bearer <token>' \
  -H 'x-castlabs-organization: urn:janus:organization:acme' \
  -H 'Content-Type: application/json' \
  -d '{
        "tags": ["my-project"],
        "region": "aws:eu-west-1",
        "tasks": [
          { "tool": "storage:get",
            "parameters": {
              "location": "s3://{acme-aws-access-keys}@acme-bucket/in/",
              "files": ["source.mov"]
            }
          },
          { "tool": "ffmpeg:cmd",
            "parameters": {
              "arguments": [
                "-y", "-i", "source.mov",
                "-c:v", "libx264", "-b:v", "1500k",
                "-c:a", "aac", "-b:a", "128k",
                "source_720p.mp4"
              ]
            }
          },
          { "tool": "storage:put",
            "parameters": {
              "location": "s3://{acme-aws-access-keys}@acme-bucket/out/{job_id}/",
              "files": ["source_720p.mp4"]
            }
          }
        ]
      }'

A 201 Created response returns the full job, including the assigned id and the initial state of all tasks.

List jobs

GET /o/{organization_urn}/jobs

Permission: vtk:ListJobs on arn:vtk:api::{organization_urn}:jobs

Returns a paginated list of jobs for the organization.

Query parameters:

Parameter

Description

limit

Maximum number of results per page (default 50, max 200).

offset

Number of results to skip.

sort

Sort field. Prefix with - for descending (default -modified).

status

Filter by status. Comma-separated. Values: 0 Submitted, 1 In progress, 2 Completed, 3 Failed, 4 Aborted, 5 Waiting for resources.

job_bundle

Filter by job bundle name.

tag

Comma-separated tag filter; all must match (case-insensitive).

search

Search by job ID or tag name.

curl https://api.vtk.castlabs.com/o/urn:janus:organization:acme/jobs?status=1,2&limit=20 \
  -H 'Authorization: Bearer <token>' \
  -H 'x-castlabs-organization: urn:janus:organization:acme'

Get job

GET /o/{organization_urn}/jobs/{job_id}

Permission: vtk:GetJob on arn:vtk:api::{organization_urn}:jobs/{job_id}

Returns the full job details, including all tasks.

curl https://api.vtk.castlabs.com/o/urn:janus:organization:acme/jobs/abcDEFGHIjk \
  -H 'Authorization: Bearer <token>' \
  -H 'x-castlabs-organization: urn:janus:organization:acme'

Get job metrics

GET /o/{organization_urn}/jobs/{job_id}/metrics

Permission: vtk:GetJobMetrics on arn:vtk:api::{organization_urn}:jobs/{job_id}/metrics

Returns usage metrics for the job: compute units (cus), video minutes processed, and storage bytes — both at job level and per task.

{
  "id": "F8QDEYg1qos",
  "cus": 50.26,
  "video_minutes_in": 60,
  "video_minutes_out": 240,
  "gb_in": 50.05,
  "gb_out": 8.10,
  "tasks": [
    { "task_id": 12345, "tool": "video:transcode",
      "cus": 50.26, "video_minutes_in": 60, "video_minutes_out": 240,
      "gb_in": 50.05, "gb_out": 8.10 }
  ]
}

Job actions (abort, restart, resubmit)

POST /o/{organization_urn}/jobs/{job_id}?action={abort|restart|resubmit}

Permission: vtk:AbortJob | vtk:RestartJob | vtk:ResubmitJob on arn:vtk:api::{organization_urn}:jobs/{job_id}

  • abort — cancel a running or queued job.

  • restart — reset the tasks and start over under the same job ID.

  • resubmit — start the job again under a new job ID. The original job is unchanged.

curl -X POST "https://api.vtk.castlabs.com/o/urn:janus:organization:acme/jobs/2w9geAylAqq?action=restart" \
  -H 'Authorization: Bearer <token>' \
  -H 'x-castlabs-organization: urn:janus:organization:acme'

abort and restart return 200 with the updated job. resubmit returns 201 with the newly created job.

Job Bundles

Jobs can be bundled into Job Bundles for better tagging, grouping, and billing of multiple jobs. A job bundle is identified by its name, which is unique within an organization and immutable after creation.

List job bundles

GET /o/{organization_urn}/jb

Permission: vtk:ListBundles on arn:vtk:api::{organization_urn}:jb

Query parameters: limit, offset, sort (default -created), search (by name), name (exact match).

Create a job bundle

POST /o/{organization_urn}/jb

Permission: vtk:CreateBundle on arn:vtk:api::{organization_urn}:jb

{ "name": "DL_project1" }

Get job bundle details

GET /o/{organization_urn}/jb/{name}

Permission: vtk:GetBundle on arn:vtk:api::{organization_urn}:jb/{name}

Returns the bundle with aggregated statistics across all its jobs (totals for bytes in/out, execution time, and counts of completed/running/failed jobs).

List jobs in a job bundle

GET /o/{organization_urn}/jb/{name}/jobs

Permission: vtk:ListBundleJobs on arn:vtk:api::{organization_urn}:jb/{name}/jobs

Same query parameters as the top-level job listing.

Submit a job into a job bundle

POST /o/{organization_urn}/jb/{name}/jobs

Permission: vtk:CreateBundleJob on arn:vtk:api::{organization_urn}:jb/{name}/jobs

Body is a standard job submission. The job is automatically assigned to this bundle — job_bundle_id/job_bundle fields are no longer used in the request body.

Next topic: Tasks
Previous topic: Authentication