Create Job

View Markdown
POST /jobs

Creates a job that processes a media file through a pipeline: probe → import → encode → export. This is the main way to process media — send a URL, pick a kind, and Ittybit handles the rest. For the CLI equivalent, see ittybit jobs create.

Request body

FieldTypeRequiredDescription
inputstringyesInput URL (http://, https://, or s3://)
kindstringyesvideo · audio · image · animation · adaptive_video
optionsobjectnoProcessing options
outputstringnoS3 destination (s3://bucket/key)
metadataobjectnoArbitrary key-value pairs

Options

video

OptionTypeValues
formatstringmp4 · webm · mov
codecstringh264 · h265 · vp9 · av1
qualitystringvery_low · low · medium · high · very_high
widthint or stringPixels or "50%"
heightint or stringPixels or "50%"
fitstringcontain · cover · fill
positionstringcenter · top · bottom · left · right etc.
backgroundstringHex color (e.g. "#000000") — only with fit: contain
fpsnumber1–60
bitrateinteger300,000–60,000,000 bps
startnumberSeconds
endnumberSeconds

audio

OptionTypeValues
formatstringmp3 · aac · ogg · opus · wav · flac
qualitystringvery_low · low · medium · high · very_high
bitrateinteger32,000–320,000 bps
startnumberSeconds
endnumberSeconds

image

OptionTypeValues
formatstringjpeg · png · webp · avif
qualitystringvery_low · low · medium · high · very_high
widthint or stringPixels or "50%"
heightint or stringPixels or "50%"
fitstringcontain · cover · fill
positionstringcenter · top · bottom · left · right etc.
backgroundstringHex color (e.g. "#000000") — only with fit: contain
startnumberFrame time in seconds (video input)

animation

OptionTypeValues
formatstringgif · webp
qualitystringvery_low · low · medium · high · very_high
widthint or stringPixels or "50%"
heightint or stringPixels or "50%"
fitstringcontain · cover · fill
positionstringcenter · top · bottom · left · right etc.
backgroundstringHex color (e.g. "#000000") — only with fit: contain
startnumberSeconds
endnumberSeconds (required)
fpsnumber1–60

adaptive_video

OptionTypeValues
formatstringhls
qualitystringvery_low · low · medium · high · very_high
widthint or stringPixels or "50%"
heightint or stringPixels or "50%"
fitstringcontain · cover · fill
positionstringcenter · top · bottom · left · right etc.
backgroundstringHex color (e.g. "#000000") — only with fit: contain
startnumberSeconds
endnumberSeconds

Examples

Video

Convert and resize a video. Smaller files mean faster page loads and lower CDN costs.

ittybit video \
  -i https://example.com/upload.mov \
  --width 1280 \
  --height 720 \
  --format mp4 \
  --quality high \
const task = {
  input: 'https://example.com/upload.mov',
  kind: 'video',
  options: {
    width: 1280,
    height: 720,
    format: 'mp4',
    quality: 'high',
  },
};

const res = await fetch('https://api.ittybit.com/jobs', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(task),
});
const data = await res.json();
import requests

task = {
    "input": "https://example.com/upload.mov",
    "kind": "video",
    "options": {
        "width": 1280,
        "height": 720,
        "format": "mp4",
        "quality": "high",
    },
}

res = requests.post(
    "https://api.ittybit.com/jobs",
    headers={"Authorization": f"Bearer {api_key}"},
    json=task,
)
data = res.json()
JOB='{
  "input": "https://example.com/upload.mov",
  "kind": "video",
  "options": {
    "width": 1280,
    "height": 720,
    "format": "mp4",
    "quality": "high"
  }
}'

curl -X POST https://api.ittybit.com/jobs \
  -H "Authorization: Bearer $ITTYBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$JOB"

Audio

Extract an audio track from a video file.

ittybit audio \
  -i https://example.com/interview.mp4 \
  --format mp3 \
  --quality high \
const job = {
  input: 'https://example.com/interview.mp4',
  kind: 'audio',
  options: {
    format: 'mp3',
    quality: 'high',
  },
};

const res = await fetch('https://api.ittybit.com/jobs', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(job),
});
const data = await res.json();
import requests

job = {
    "input": "https://example.com/interview.mp4",
    "kind": "audio",
    "options": {
        "format": "mp3",
        "quality": "high",
    },
}

res = requests.post(
    "https://api.ittybit.com/jobs",
    headers={"Authorization": f"Bearer {api_key}"},
    json=job,
)
data = res.json()
JOB='{
  "input": "https://example.com/interview.mp4",
  "kind": "audio",
  "options": {
    "format": "mp3",
    "quality": "high"
  }
}'

curl -X POST https://api.ittybit.com/jobs \
  -H "Authorization: Bearer $ITTYBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$JOB"

Image

Extract a poster frame from a video at the 5-second mark.

ittybit image \
  -i https://example.com/video.mp4 \
  --start 5 \
  --format webp \
  --width 640 \
const job = {
  input: 'https://example.com/video.mp4',
  kind: 'image',
  options: {
    start: 5,
    format: 'webp',
    width: 640,
  },
};

const res = await fetch('https://api.ittybit.com/jobs', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(job),
});
const data = await res.json();
import requests

job = {
    "input": "https://example.com/video.mp4",
    "kind": "image",
    "options": {
        "start": 5,
        "format": "webp",
        "width": 640,
    },
}

res = requests.post(
    "https://api.ittybit.com/jobs",
    headers={"Authorization": f"Bearer {api_key}"},
    json=job,
)
data = res.json()
JOB='{
  "input": "https://example.com/video.mp4",
  "kind": "image",
  "options": {
    "start": 5,
    "format": "webp",
    "width": 640
  }
}'

curl -X POST https://api.ittybit.com/jobs \
  -H "Authorization: Bearer $ITTYBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$JOB"

Adaptive video

Create an HLS stream so players can switch quality based on viewer bandwidth. Adaptive streams prevent buffering for users on slow connections.

ittybit adaptive \
  -i https://example.com/video.mp4 \
  --format hls \
  --quality high \
const job = {
  input: 'https://example.com/video.mp4',
  kind: 'adaptive_video',
  options: {
    format: 'hls',
    quality: 'high',
  },
};

const res = await fetch('https://api.ittybit.com/jobs', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(job),
});
const data = await res.json();
import requests

job = {
    "input": "https://example.com/video.mp4",
    "kind": "adaptive_video",
    "options": {
        "format": "hls",
        "quality": "high",
    },
}

res = requests.post(
    "https://api.ittybit.com/jobs",
    headers={"Authorization": f"Bearer {api_key}"},
    json=job,
)
data = res.json()
JOB='{
  "input": "https://example.com/video.mp4",
  "kind": "adaptive_video",
  "options": {
    "format": "hls",
    "quality": "high"
  }
}'

curl -X POST https://api.ittybit.com/jobs \
  -H "Authorization: Bearer $ITTYBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$JOB"

Output to S3

Send processed media to your own storage instead of Ittybit-managed storage. Requires a connection.

ittybit video \
  -i https://example.com/upload.mov \
  -o s3://my-bucket/processed/video.mp4 \
const job = {
  input: 'https://example.com/upload.mov',
  kind: 'video',
  output: 's3://my-bucket/processed/video.mp4',
};

const res = await fetch('https://api.ittybit.com/jobs', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ITTYBIT_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(job),
});
const data = await res.json();
import requests

job = {
    "input": "https://example.com/upload.mov",
    "kind": "video",
    "output": "s3://my-bucket/processed/video.mp4",
}

res = requests.post(
    "https://api.ittybit.com/jobs",
    headers={"Authorization": f"Bearer {api_key}"},
    json=job,
)
data = res.json()
JOB='{
  "input": "https://example.com/upload.mov",
  "kind": "video",
  "output": "s3://my-bucket/processed/video.mp4"
}'

curl -X POST https://api.ittybit.com/jobs \
  -H "Authorization: Bearer $ITTYBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$JOB"

Response 201

{
  "id": "job_abc123",
  "object": "job",
  "kind": "video",
  "input": "https://example.com/upload.mov",
  "output": null,
  "options": { "width": 1280, "height": 720, "format": "mp4", "quality": "high" },
  "metadata": {},
  "status": "queued",
  "error": null,
  "tasks": [
    {
      "id": "task_001",
      "object": "task",
      "kind": "probe",
      "input": null,
      "options": {},
      "output": null,
      "status": "waiting",
      "progress": null,
      "error": null,
      "created_at": 1711900000000,
      "started_at": null,
      "finished_at": null,
      "updated_at": 1711900000000
    },
    {
      "id": "task_002",
      "object": "task",
      "kind": "import",
      "input": null,
      "options": {},
      "output": null,
      "status": "waiting",
      "progress": null,
      "error": null,
      "created_at": 1711900000000,
      "started_at": null,
      "finished_at": null,
      "updated_at": 1711900000000
    },
    {
      "id": "task_003",
      "object": "task",
      "kind": "video",
      "input": null,
      "options": {},
      "output": null,
      "status": "waiting",
      "progress": null,
      "error": null,
      "created_at": 1711900000000,
      "started_at": null,
      "finished_at": null,
      "updated_at": 1711900000000
    },
    {
      "id": "task_004",
      "object": "task",
      "kind": "export",
      "input": null,
      "options": {},
      "output": null,
      "status": "waiting",
      "progress": null,
      "error": null,
      "created_at": 1711900000000,
      "started_at": null,
      "finished_at": null,
      "updated_at": 1711900000000
    }
  ],
  "created_at": 1711900000000,
  "started_at": null,
  "finished_at": null,
  "updated_at": 1711900000000
}

Errors

StatusKindCause
400input_requiredMissing input
400invalid_inputBad URL scheme
400invalid_formatUnknown format for kind
400invalid_codecCodec incompatible with container
401token_missingNo Authorization header
401token_invalidBad API key

See also