API


Welcome to the Zencoder API Documentation. The Zencoder API allows you to connect your application to our encoding service and encode videos without going through the web interface. You may also benefit from one of our integration libraries for different languages.

The API is based on REST, and uses JSON or XML as the data structure.

The API base URL is https://app.zencoder.com/api.

1. Creating an Encoding Job

Encoding jobs are created by sending an HTTP POST request to https://app.zencoder.com/api/jobs. The post body must include two things – the URL of a video to process, and your API key. It may also include output settings for the job, including an output destination, notification settings, and transcoding settings.

We currently support downloading files from HTTP, S3, FTP, and SFTP.

The body of a simple new job request would look like this.

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi"
}

XML:

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
</api-request>

You can test this with cURL.

curl --data '{"api_key":"93h630j1dsyshjef620qlkavnmzui3", "input":"s3://bucket-name/file-name.avi"}' https://app.zencoder.com/api/jobs -H "Content-Type: application/json"

XML:

curl --header Content-Type:"application/xml" --data '<?xml version="1.0" encoding="UTF-8"?><api-request><api_key>93h630j1dsyshjef620qlkavnmzui3</api_key><input>s3://bucket-name/file-name.avi</input></api-request>' https://app.zencoder.com/api/jobs?format=xml

This request will create an encoding job for the account with the API key of 93h630j1dsyshjef620qlkavnmzui3, and will transcode the file at s3://bucket-name/file-name.avi to our default output.

Job Create response

When you create a new encoding job through the API, our server will immediately respond with details about the job and output files being created. Capture the IDs to track them through the encoding process.

The data will be returned in the JSON format by default. For an XML response, pass format=xml in the querystring, like https://app.zencoder.com/api/jobs?format=xml.

The previous new encoding job example would return the following, with a 201 Created status code.

{
  "id": "1234",
  "outputs": [
    {
      "id": "4321"
    }
  ]
}

Show XML Example

<api-response>
  <id>1234</id>
  <outputs type="array">
    <output>
      <id>4321</id>
    </output>
  </outputs>
</api-response>

Note that this does not mean that the job will succeed – just that it was a valid API request. The job may fail because the input file does not exist, the output location is invalid, or the file itself is not a valid video or audio file.

Test Jobs and Integration Mode

You can submit a test job by using Integration Mode, which shortens all output files to 5 seconds in length. You can do this in one of two ways.

First, you can also mark a job as a test job via the API by passing "test": 1 along with your API request, like this:

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "test": 1
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
  <test>1</test>
</api-request>

Second, you can enable Integration Mode for your entire account at http://app.zencoder.com/account. Note that your account will be in integration when you first sign up.

Input Settings

There are five input settings.

api_key: your API key.

input: a remote filename to pull in for transcoding. May be a HTTP, HTTPS, FTP, or SFTP URL. If the remote server requires authentication, include username and password in the input url string.

Examples:

  • http://example.com/path/to/input.avi
  • https://example.com/path/to/input.mov
  • ftp://example.com/path/to/input.mp3
  • sftp://example.com/path/to/input.3gp
  • https://s3.amazonaws.com/bucket-name/input.mpeg
  • s3://bucket-name/input.mpeg (shorthand for the full HTTP S3 url)

Examples (with authentication):

  • http://username:password@example.com/path/to/input.avi
  • https://username:password@example.com/path/to/input.mov
  • ftp://username:password@example.com/path/to/input.mp3
  • sftp://username:password@example.com/path/to/input.3gp

NB: if you are using a read-only S3 bucket as an input source, you will need to grant READ permissions to “aws@zencoder.com” before submitting a job.

download_connections: You can specify the number of connections to use to download a file. This may speed up download transfer times. Be aware that more connections can place a heavier load on the server. By default, Zencoder uses 5 connections. The maximum allowed is 25.

region: You can specify a region of “us”, “europe”, or “asia”. We will make our best effort to process the files on servers in the region specified. Only in rare circumstances we will utilize a server in a different region. In the same way, if passed an unsupported or non-existent region, the request will not fail, we will simply choose the region. Region support is currently in public beta.

test: enable test mode for this job.

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "download_connections": 3,
  "region": "asia"
}

Show XML Example

<api-reponse>
  <id>1234</id>
  <outputs type="array">
    <output>
      <id>4321</id>
    </output>
  </outputs>
</api-response>

2. Output Settings

Our default output is a single video file with the following settings:

H.264 video, AAC Audio, MP4 file format
Video: medium quality, scaled down to fit within 640×480 if needed
Audio: stereo, medium quality (about 112kbps), 44100 Hz

If you don’t specify an output location, the file will be temporarily hosted by Zencoder. After 24 hours the file will no longer be available.

Of course, you can control the output settings. To do this, pass an array of options in the API request, like this:

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "outputs": [
    {
      "label": "iPhone",
      "url": "s3://output-bucket/output-file-1-name.mp4",
      "width": "480",
      "height": "320"
    },
    {
      "label": "Web HD",
      "url": "s3://output-bucket/output-file-2-name.mp4",
      "width": "1280",
      "height": "720"
    }
  ]
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
  <outputs type="array">
    <output>
      <label>iPhone</label>
      <url>s3://output-bucket/output-file-1-name.mp4</url>
      <width>480</width>
      <height>320</height>
    </output>
  </outputs>
</api-request>

This example will create two output files from the original input video, with the labels iPhone and Web HD. You can create as many output files as you need from the original, without having to create additional encoding jobs.

General Settings


video_codec: the output video codec to use. Currently supported codecs are “h264” (default), “theora”, “vp6“, and “vp8″.


url: where to send the transcoded file. Currently, this must either be an S3 bucket that has granted Write permissions to aws@zencoder.com or an FTP/SFTP server. Please note that it is the S3 bucket and not the S3 folders, which are part of the key, that need Write permissions. The format should be:

s3://[bucket name]/[key or filename]

or

ftp://[user]:[password]@[ftp.url]/[filename]

Examples:
“url”: “s3://my-output-bucket/final.mp4″
“url”: “ftp://user:password@ftp.example.com/final.mp4″


base_url: determines a directory to put the output file in, but not the filename. If you do not supply a filename, we will generate a random filename plus an appropriate extension.


filename: the filename of the finished file. If you supply a filename but not a base_url, we will store the file with this filename in a S3 bucket for you to download.

label: a nickname for the output version. This is useful when sending a job with multiple output files, so you can keep track of which output file is which.


speed: a target transcoding speed. Slower transcoding allows for better file compression, while faster transcoding is possible by skipping some advanced compression features. Valid values are 1-5.

In general, we recommend either 2 or 4. 1-3 often result in similar file sizes, while 2-3 are generally about the same speed, so 2 is a good compromise. On the high end, 5 often results in significantly larger files, but is not much faster than 4.

Note that at the moment, only H.264 output has five speed levels. For VP6 content, 1-2 are a slower mode, and 3-5 are a faster mode. VP8 and Theora do not currently use the speed setting (but will soon).

“speed”: 4

Resolution Settings

width: video frame width. If no width is supplied, we will use the original width, or scale to fit the Size or Height setting.

height: video frame height. If no height is supplied, we will use the original height, or scale to fit the Size or Width setting.

size: the resolution of the output file, expressed as WxH, like 640×480 or 1280×720. The following two settings – ‘stretch’ and ‘upscale’ – affect how the video is resized.


upscale: If set to true, an input video that is smaller than the output resolution will stretch to fit the resolution. For example, if your output spec is 480×360, and someone submits a video that is 320×240, the video will be upsized to 480×360 if Upscale is true, and will remain at 320×240 up Upscale is false. Default: false.


aspect_mode: if the aspect ratio of the input does not match the requested output aspect ratio, what should the output resolution be? As an example, assume that an input file is 1280×720 (widescreen 16:9), but the target output is 640×480 (standard 4:3). There are four basic approaches to this problem, and Zencoder supports them all. aspect_mode requires that both a width and a height are provided; otherwise, if only one is provided, we’ll calculate the other dimension proportionately.

1. “preserve”: By default, Zencoder will preserve the aspect ratio of the original file, so if you submit widescreen content and ask for standard resolution, the output file will fit keep the widescreen aspect ratio, and will fit within the output size. Presumably, the player will then add black bars to fill up the frame. In our example, the output file will be 640×360 (widescreen 16×9 that fits within the 640×480 target).

2. “stretch”: When the aspect mode is “stretch”, the output video will exactly match the requested width and height, even if it distorts the image. So in our example, the output will be 640×480, but will look vertically stretched. NB: this is not the same as the “upscale” option, above, which governs whether or not a smaller video will be enlarged to a larger frame size.

3. “crop”: This option tells Zencoder to “zoom in” to the video to match the output size, by cropping pixels from the top/bottom or left/right. So if the input is widescreen 1280×720, and the output target is standard 640×480, we will crop roughly 160 pixels from the left and from the right of the input file (creating a 4:3 movie), and then resize that down to 640×480. If you’re old enough to remember non-widescreen VHS (like us), this is the old “pan and scan” option.

4. “pad”: The Pad option tells Zencoder to letterbox the video to match the output frame size exactly. Use this option if your target player doesn’t know how to pad a video; otherwise, you’re just wasting bits by including black bars in the actual file. Following our example, this option would take 1280×720 (16:9) content and convert it to 640×480 (4:3) by creating a 640×360 movie, and then placing 60 pixel black bars at the top and bottom of the movie. So the movie would be 640×480, with black bars at the top and bottom.

Valid values are “preserve”, “stretch”, “crop”, and “pad”. Default: “preserve”.

Video Bitrate Settings

There are three main settings that control video bitrate: quality (recommended), video bitrate, and bitrate cap/buffer size.


quality: the desired output video quality, from 1 to 5. Higher quality means higher bitrate and vice versa. Quality of 5 will be nearly lossless, but will result in larger files. Quality of 1 will be quite compressed, and may not look great. Higher quality encoding is also a bit slower than lower quality encoding. As a rule of thumb, lowering quality by a level will reduce file size by about 40%. Quality of 3-4 usually looks pretty good. Note that the actual bitrate will vary when using the Quality setting, depending on the type of video. Even at the same Quality setting, low-complexity video (like a screencast) will generally result in lower bitrates than high-complexity video (like a movie). Default: 3.


video_bitrate: the desired output bitrate for a video, expressed in Kbps. This results in a predictable output bitrate, but not predictable quality. For example, at 640×480, 500kbps might be enough for a video blog to look good, but an action movie at that bitrate might look bad. Similarly, it might be too high for a screencast, resulting in a file that is larger than it needs to be. Default: none.


bitrate_cap: the max peak bitrate throughout a video. A Bitrate setting of 500 will create a video with an average overall bitrate of 500, but one scene might have a bitrate of 1000 and another might have a bitrate of 200. This is fine for downloaded video, but can cause a problem for streaming. It also can cause a problem on certain devices, like the iPod. Use the Max Bitrate setting to cap the local bitrate at every stage of a file, so that it never exceeds a certain number. For an iPhone, for example, the Max Bitrate should be set to 10000. Default: none.


buffer_size: used in conjunction with Max Bitrate. This number should be determined by the settings of your streaming server, or your targeted playback device. For example, Buffer Size should be set to 10000 for an iPhone. Default: none.

onepass: by default, when encoding to a target bitrate (rather than a target quality), we use two-pass encoding. Two-pass average bitrate encoding is typically quite a bit better than a single pass. If you want to force ABR encoding to use a single pass, set “onepass” to true.

Note that if you set “onepass”, “quality”, and “video_bitrate”, we will ignore the “quality” setting and do one-pass ABR encoding with the specified video_bitrate.

Audio Settings


audio_codec: what audio codec to use. Options are MP3, AAC, and Vorbis. The default codec depends on the video codec used (if any). H.264 and VP6 video may use either AAC or MP3. VP8 and Theora video may only use the Vorbis audio codec.

Note that MP3 audio in a MP4 container is valid (alongside H.264 content), but does not play back in Quicktime.


audio_quality: a target audio quality, between 1 and 5. We recommend you use this setting instead of the audio_bitrate setting, unless you need to target an exact audio bitrate.


audio_bitrate: an output bitrate setting, in Kbps. This should be a multiple of 16, and lower than 160kbps per channel (320kbps for stereo). With 2 channel output, this is the total audio bitrate, not the bitrate of each channel, so 128kbps stereo output is encoded at 64kbps per channel. Below 48kbps per channel, quality starts to suffer.


audio_sample_rate: a sample rate in Hz. We recommend that you do not use this setting; forcing an output sample rate can reduce audio quality and cause unexpected problems. By default, the input sample rate will be used (i.e. the audio will not be resampled), though sample rates higher than 48000 will be reduced to a max of 48000.


audio_channels: the number of audio channels to use: 1 (mono) or 2 (stereo). Default: keep the input number of channels, or reduce to 2.

Advanced Settings


deinterlace: Determines whether or not to apply a deinterlacing filter. Default is “detect” – if the input file is detected as interlaced, it will be deinterlaced. Set this to “on” to force deinterlacing (which will reduce quality if the input is not interlaced), or “off” to avoid deinterlacing. Valid values: “on”, “off”, “detect”. Default: “detect”.

Note that Zencoder makes this determination based on file metadata. If interlaced content is re-encoded with an encoder that does not deinterlace the content, or flag it as interlaced, we may not be able to auto-deinterlace the content in “detect” mode.


max_frame_rate: rather than setting an exact frame rate, which may involve increase the frame rate (and therefore the bitrate) of some content, you can set a Max Frame Rate instead. This will decrease frame rates that exceed the Max Frame Rate, but won’t adjust frame rates that are below this max. So if someone uploads a video with a frame rate of 15, and you set a max frame rate of 30, the output frame rate would remain 15. Default: none.


frame_rate: the output frame rate to use, as a decimal number (e.g. 15, or 24.98). We recommend that you do not use this setting – forcing a change to the video frame rate will result in a lower-quality video. If you want to prevent frame rates above a certain level, use Max Frame Rate instead. Default: preserve original.


decimate: divide the input bitrate by the specified number. This is useful if you know you want to cut frame rate in half, but you don’t know what the input frame rate is. Given an input frame rate of 20, if you set “decimate” to 2, you’ll get an output frame rate of 10. You can still set “max_frame_rate” if you want to ensure that a decimated frame rate does not exceed a certain value.


keyframe_interval: Set the maximum number of frames between each keyframe. By default, a keyframe will be created at most every 250 frames. Specifying a different keyframe interval will allow you to create more or less keyframes in your video. A greater number of keyframes will increase the size of your output file, but will allow for more precise scrubbing in most players. Keyframe interval should be specified as a positive integer. For example, a value of 100 will create a keyframe every 100 frames. Default: 250.

“keyframe_interval”: 250

rotate: Explicitly rotate a movie. By default, Zencoder will auto-rotate rotated content (including rotated iPhone video), but you can also manually rotate a movie. If you set “rotate” to 0, we will not auto-rotate, so leave this option unset if you want auto-rotation. Valid values are 0, 90, 180, and 270. Default: null.


start_clip: create a subclip of the original video, starting at a particular time. This can either be a timecode with a format of HH:MM::SS.S, or a decimal expressing the number of seconds to start at. Note that the actual start time may not be exact, depending on the arrangement of keyframes within the video. Default: none.

“start_clip”: “00:00:10″ # ten seconds
“start_clip”: “00:03:25.7″ # three minutes, 25.7 seconds
“start_clip”: “60″ # sixty seconds


clip_length: create a subclip of a particular length. This can either be a timecode with a format of HH:MM::SS.S, or a decimal expressing the number of seconds to start at. Can be combined with Start Clip to create subclips in the middle of a video. If Start Clip is not provided, the clip will start at the beginning of the video. Note that the actual clip length may not be exact, depending on the arrangement of keyframes within the video. Default: none.

“clip_length”: “00:00:30″ # thirty seconds
“clip_length”: “00:10:00″ # ten minutes
“clip_length”: “12.5″ # twelve and a half seconds

skip_audio: if an input has an audio track, ignore it. Default: false.

“skip_audio”: 1

skip_video: if an input has an video track, ignore it. Default: false.

Watermark Settings

You can add one or more watermarks to an output video using our watermarking API.

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "http://example.com/file-name.avi",
  "output": {
    "watermark": {
      "url": "s3://bucket/watermark_file.png",
      "x": "20",
      "y": "-10%"
      "width": "32",
      "height" : "24"
    }
  }
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>http://example.com/file-name.avi</input>
  <outputs type="array">
    <output>
      <watermark>
        <url>s3://bucket/watermark_file.png</url>
        <x>20</size>
        <y>-10%</y>
        <width>32</width>
        <height>24</height>
      </watermark>
    </output>
  </outputs>
</api-request>

url: The URL of a remote image file to use as a watermark. Use the input URL syntax. Supports S3, HTTP/S, FTP, and SFTP, with or without authentication. Examples: “https://s3.amazonaws.com/bucket/img.png” or “ftp://user:pass@example.com/path/to/watermark.jpg”.

Zencoder supports watermark files in GIF, JPEG, BMP, or PNG format.

x: Where to place the watermark within the video, on the x axis (left/right). Can be a number of pixels (e.g. 100 or -20) or a percent of the video width (e.g. “25%” or “-5%”). Use a positive number to place relative to the left side of the video, and a negative number to place relative to the right side of the video. Use “-0″ (as a string) to lock to the right side. Default: -10.

y: Where to place the watermark within the video, on the y axis (top/bottom). Can be a number of pixels (e.g. 100 or -20) or a percent of the video height (e.g. “25%” or “-5%”). Use a positive number to place relative to the top of the video, and a negative number to place relative to the bottom of the video. Use “-0″ (as a string) to lock to the bottom. Default: -10.

width: The width of the watermark, expressed as a number of pixels (e.g. 64) or as a percent of the video width (e.g. “10%”). If width is provided, but not height, the watermark image will be scaled proportionately. Default: scale to height, or original image width.

height: The height of the watermark, expressed as a number of pixels (e.g. 48) or as a percent of the video height (e.g. “10%”). If height is provided, but not width, the watermark image will be scaled proportionately. Default: scale to width, or original image height.

Note: When using the VP6 codec there are some additional limitations. You may only apply one watermark to the video (if passed multiple watermarks only the first will be used). Additionally, watermark scaling is not supported.

Multiple Outputs

You can specify multiple outputs by passing more than one hash in the outputs array, like this:

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "https://user:pass@bucket-name/file-name.avi",
  "outputs": [
    {
      "label": "web",
      "url": "s3://output-bucket/web.avi",
      "size": "512x384"
    },
    {
      "label": "iphone",
      "url": "s3://output-bucket/iphone.avi",
      "size": "480x320"
    }
  ]
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>https://user:pass@bucket-name/file-name.avi</input>
  <outputs type="array">
    <output>
      <label>web</label>
      <url>s3://output-bucket/web.avi</url>
      <width>512</width>
      <height>384</height>
    </output>
    <output>
      <label>iphone</label>
      <url>s3://output-bucket/iphone.avi</url>
      <width>480</width>
      <height>320</height>
    </output>
  </outputs>
</api-request>

S3 Access Control Lists

Files in S3 can be given an access control list which grants various forms of access to users. Amazon’s S3 documentation explains the various kinds of access and to whom it may be granted. By default all output files we write will have the canned access policy ‘bucket-owner-full-control.’ You can make files publicly readable (grant READ to the AllUsers group) as well by supplying the public flag for any output file or thumbnail. Observe the use of the public flag in the sample job creations below.

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "output": [
    {
      "url": "s3://output-bucket/output-file-1-name.mp4",
      "public": 1,
      "thumbnails": {
        "number": 6
      }
    }
  ]
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
  <outputs type="array">
    <output>
      <label>web</label>
      <url>s3://output-bucket/output-file-1-name.mp4</url>
      <public>1</public>
      <thumbnails>
        <number>6</number>
      </thumbnails>
    </output>
  </outputs>
</api-request>

Permissions set on the output file will also apply for the thumbnails. In the previous example thumbnails will also be publicly readable. You can also set thumbnail permissions independently.

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "output": [
    {
      "url": "s3://output-bucket/output-file-1-name.mp4",
      "thumbnails": {
        "public": 1,
        "number": 6
      }
    }
  ]
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
  <outputs type="array">
    <output>
      <label>web</label>
      <url>s3://output-bucket/output-file-1-name.mp4</url>
      <thumbnails>
        <public>1</public>
        <number>6</number>
      </thumbnails>
    </output>
  </outputs>
</api-request>

In this example the thumbnails are publicly readable but the output file isn’t. To prevent thumbnails from becoming publicly readable when the output file is set to be publicly readable, set it to 0.

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "output": [
    {
      "url": "s3://output-bucket/output-file-1-name.mp4",
      "public": 1,
      "thumbnails": {
        "public": 0,
        "number": 6
      }
    }
  ]
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
  <outputs type="array">
    <output>
      <label>web</label>
      <url>s3://output-bucket/output-file-1-name.mp4</url>
      <public>1</public>
      <thumbnails>
        <public>0</public>
        <number>6</number>
      </thumbnails>
    </output>
  </outputs>
</api-request>

In this example the thumbnails are not publicly readable but the output file is.

The Zencoder API also allows fine-grained control of S3 permissions.

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "output": [
    {
      "url": "s3://output-bucket/output-file-1-name.mp4",
      "thumbnails": {
        "number": 1
      },
      "access_control": [
        {
          "grantee": "cdc7931a9574b1055d5b76112021d0e9",
          "permissions": ["READ", "WRITE"]
        },
        {
          "grantee": "someone@example.com",
          "permission": "FULL_CONTROL"
        },
        {
          "grantee": "http://acs.amazonaws.com/groups/global/AllUsers",
          "permission": "READ"
        }
      ]
    }
  ]
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
  <outputs type="array">
    <output>
      <label>web</label>
      <url>s3://output-bucket/output-file-1-name.mp4</url>
      <public>1</public>
      <thumbnails>
        <number>6</number>
      </thumbnails>
      <access_controls>
        <access_control>
          <grantee>cdc7931a9574b1055d5b76112021d0e9</grantee>
          <permissions>
            <permission>READ</permission>
            <permission>WRITE</permission>
          </permissions>
        </access_control>
        <access_control>
          <grantee>someone@example.com</grantee>
          <permissions>
            <permission>FULL_CONTROL</permission>
          </permissions>
        </access_control>
        <access_control>
          <grantee>http://acs.amazonaws.com/groups/global/AllUsers</grantee>
          <permissions>
            <permission>READ</permission>
          </permissions>
        </access_control>
      </access_controls>
    </output>
  </outputs>
</api-request>

In the previous example we have granted READ and WRITE to the user with AWS ID “cdc7931a9574b1055d5b76112021d0e9″, FULL_CONTROL to the user with AWS email “someone@example.com”, and READ to the AWS AllUsers group. Again, permissions set on the output file will also apply for thumbnails. Thumbnail permissions can be set independently as well.

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "output": [
    {
      "url": "s3://output-bucket/output-file-1-name.mp4",
      "thumbnails": {
        "number": 1
        "access_control": [
          {
            "grantee": "cdc7931a9574b1055d5b76112021d0e9",
            "permissions": ["READ", "WRITE"]
          },
          {
            "grantee": "someone@example.com",
            "permission": "FULL_CONTROL"
          },
          {
            "grantee": "http://acs.amazonaws.com/groups/global/AllUsers",
            "permission": "READ"
          }
        ]
      }
    }
  ]
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
  <outputs type="array">
    <output>
      <label>web</label>
      <url>s3://output-bucket/output-file-1-name.mp4</url>
      <public>1</public>
      <thumbnails>
        <number>6</number>
        <access_controls>
          <access_control>
            <grantee>cdc7931a9574b1055d5b76112021d0e9</grantee>
            <permissions>
              <permission>READ</permission>
              <permission>WRITE</permission>
            </permissions>
          </access_control>
          <access_control>
            <grantee>someone@example.com</grantee>
            <permissions>
              <permission>FULL_CONTROL</permission>
            </permissions>
          </access_control>
          <access_control>
            <grantee>http://acs.amazonaws.com/groups/global/AllUsers</grantee>
            <permissions>
              <permission>READ</permission>
            </permissions>
          </access_control>
        </access_controls>
      </thumbnails>
    </output>
  </outputs>
</api-request>

3. Getting Job Progress

Once you have the ID of the output file you can request the current status from our API, by sending a GET request to https://app.zencoder.com/api/outputs/4321/progress?api_key=93h630j1dsyshjef620qlkavnmzui3. The ID in a Job Progress request is the Output ID, not the Job ID. That way, you can get progress separately for each output if you use multiple outputs.

The return will contain one or more of the following keys: state, current_event, and progress.

{
  "state": "processing",
  "current_event": "Transcoding",
  "progress": "32.34567345"
}

For a XML response, add .xml to the action name: https://app.zencoder.com/api/outputs/4321/progress.xml?api_key=93h630j1dsyshjef620qlkavnmzui3

<api-response>
  <state>processing</state>
  <current_event>Transcoding</current_event>
  <progress>32.34567345</progress>
</api-response>

Valid states include: queued, processing, failed, finished, cancelled. Events include: Inspecting, Downloading, Transcoding, and Uploading.

The progress number is the percent complete of the current event – so if the event is Transcoding, and progress is 99.3421, then the file is almost finished transcoding, but hasn’t started Uploading yet.

If you’re getting a 404 to a Job Progress request, make sure that you’re using the output ID, not the job ID, and make sure your API key is correct. A 404 means that we didn’t find an output file with the specified ID for the account linked to the provided API key.

4. Thumbnails

For every output, you can ask for one or more thumbnails, in PNG format. Thumbnail options use the following syntax:

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "http://example.com/file-name.avi",
  "output": {
    "thumbnails": {
      "number": 6,
      "size": "160x120",
      "base_url": "s3://bucket/directory",
      "prefix": "custom"
    }
  }
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>http://example.com/file-name.avi</input>
  <outputs type="array">
    <output>
      <thumbnails>
        <number>6</number>
        <size>160x120</size>
        <base_url>s3://bucket/directory</base_url>
        <prefix>custom</prefix>
      </thumbnails>
    </output>
  </outputs>
</api-request>

Each output can have its own set of thumbnails. Size, base_url, and access_control default to the size, base_url, and access_control settings of the output video.

Number of thumbnails

You can use one of three methods to determine how many thumbnails to grab, and where they should be taken from: number, interval, or times.


number: A number of thumbnails to capture. Zencoder will grab evenly-spaced thumbnails across the whole duration of the file. So if you ask for 1 thumbnail, it will be near the middle of the file. Specifying 3 thumbnails on a 8 minute video will result in thumbnails at approximately 2, 4, and 6 minutes. This value must be a positive integer.


interval: A thumbnail interval in seconds. Zencoder will return one thumbnail for every N seconds of the file. So if you choose an interval of 60, and your input file is 12 minutes long, you’ll get back 12 thumbnails, each one on the minute. This value must be a positive number.


times: An array of times, in seconds, at which to grab a thumbnail. Decimals are OK. So setting “times” to [12.5, 25] would grab two thumbnails, one at 12.5 seconds, and one at 25 seconds. This value must be an array of positive numbers.

Thumbnail properties


size: a target resolution for the thumbnails, like “160×120″. If no size is provided, thumbnails will be the same size as the output video. By default, we will preserve aspect ratio, so if the aspect ratio of this size parameter does not match the aspect ratio of the movie, the resulting file may not exactly match this size. If Stretch is set to true for the corresponding output file, then this thumbnail will also be stretched to fill the resolution.


base_url: an output destination for thumbnails. If this is blank, we will use the output video file destination. If that is blank, we will store thumbnails in our Zencoder S3 bucket. Files stored in the Zencoder S3 bucket will no longer be available after 24 hours. Note that the filenames are not unique (e.g. “frame_0000.png” – see below), so this destination should be a unique directory or key prefix.


prefix: Thumbnail files will be exported with sequential filenames. However, you may specify a custom prefix for the thumbnail files. If no prefix is specified we’ll use frame. For example, if you use the prefix custom, the files exported would be named custom_0000.png, custom_0001.png, etc. Without a custom prefix they would be named frame_0000.png, frame_0001.png, etc.

access_control: S3 access control list settings for the thumbnail group. This setting follows the same syntax as S3 ACL for videos.

5. Notifications

After a output file is complete, you can find out about it in several ways.

  • We can send an API request to your application with the details.
  • You canĀ request your notifications using the Zencoder Fetcher gem. This is useful when you are developing locally and Zencoder can’t reach your development server.
  • We can send an email.
  • You can check the Zencoder Dashboard for job status.

To receive API or email notifications, add Notification options to your API request, like this:

{
  "api_key": "93h630j1dsyshjef620qlkavnmzui3",
  "input": "s3://bucket-name/file-name.avi",
  "outputs": [
    {
      "label": "web",
      "url": "s3://output-bucket/web.avi",
      "size": "512x384",
      "notifications": [
        "http://user:password@example.com/zencoder",
        "admin@example.com"
      ]
    },
    {
      "label": "iphone",
      "url": "s3://output-bucket/iphone.avi",
      "size": "480x320",
      "notifications": [
        {"format": "xml", "url": "http://user:password@example.com/zencoder1"},
        {"format": "json", "url": "http://user:password@example.com/zencoder2"},
        "http://example.com/zencoder3",
        "admin@example.com"
      ]
    }
  ]
}

Show XML Example

<api-request>
  <api_key>93h630j1dsyshjef620qlkavnmzui3</api_key>
  <input>s3://bucket-name/file-name.avi</input>
  <outputs type="array">
    <output>
      <label>web</label>
      <url>s3://output-bucket/web.avi</url>
      <size>512x384</size>
      <notifications type="array">
        <notification>http://user:password@example.com/zencoder</notification>
        <notification>admin@example.com</notification>
      </notifications>
    </output>
    <output>
      <label>iphone</label>
      <url>s3://output-bucket/iphone.avi</url>
      <size>480x320</size>
      <notifications type="array">
        <notification>
          <format>xml</format>
          <url>http://example.com/zencoder1</url>
        </notification>
        <notification>
          <format>xml</format>
          <url>http://example.com/zencoder2</url>
        </notification>
        <notification>http://example.com/zencoder3</notification>
        <notification>admin@example.com</notification>
      </notifications>
    </output>
  </outputs>
</api-request>

In this example, when the first output file is completed, two notifications would be sent:

  • Email to admin@example.com
  • HTTP POST to http://user:password@example.com/zencoder with no Content-Type header set

When the second output file is complete, four more notifications would be sent:

  • HTTP POST to http://example.com/zencoder1 with a Content-Type header set to ‘application/xml’
  • HTTP POST to http://example.com/zencoder2 with a Content-Type header set to ‘application/json’
  • Email to admin@example.com
  • HTTP POST to http://example.com/zencoder3 with no Content-Type header set

HTTP Notifications

The notification API request is sent from Zencoder to your server as a POST to the notification URL, and is either JSON or XML containing two or three values. The first is a Job ID. This ID matches the ID you received when you submitted the initial job request. Second is a status – either ‘finished’, ‘failed’, or ‘cancelled’. If a job contains multiple outputs, this notification also contains the output label you supplied when the job was initially created.

{"job":{"state":"finished","id":1234},"output":{"label":"web","url":"http://example.com/file.mp4","state":"finished","id":12345}}

{"job":{"state":"processing","id":1234},"output":{"label":"web","url":"http://example.com/file.mp4","state":"processing","id":12345}}

{"job":{"state":"failed","id":1234},"output":{"label":"web","url":"http://example.com/file.mp4","state":"failed","id":12345}}

6. Working with Jobs

Listing Jobs

A list of jobs can be obtained by sending an HTTP GET request to https://app.zencoder.com/api/jobs?api_key=93h630j1dsyshjef620qlkavnmzui3 (replace the api_key with your own). It will return an array of jobs similar to the example below. The list of thumbnails will be empty until the job is completed. By default, the results are paginated with 50 jobs per page and sorted by ID in descending order. You can pass two parameters to control the paging: page and per_page.

[{
  "job": {
    "created_at": "2010-01-01T00:00:00Z",
    "finished_at": "2010-01-01T00:00:00Z",
    "updated_at": "2010-01-01T00:00:00Z",
    "submitted_at": "2010-01-01T00:00:00Z",
    "pass_through": null,
    "id": 1,
    "input_media_file": {
      "format": "mpeg4",
      "created_at": "2010-01-01T00:00:00Z",
      "frame_rate": 29,
      "finished_at": "2010-01-01T00:00:00Z",
      "updated_at": "2010-01-01T00:00:00Z",
      "duration_in_ms": 24883,
      "audio_sample_rate": 48000,
      "url": "s3://bucket/test.mp4",
      "id": 1,
      "error_message": null,
      "error_class": null,
      "audio_bitrate_in_kbps": 95,
      "audio_codec": "aac",
      "height": 352,
      "file_size_bytes": 1862748,
      "video_codec": "h264",
      "test": false,
      "channels": "2",
      "width": 624,
      "video_bitrate_in_kbps": 498,
      "state": "finished"
    },
    "test": false,
    "output_media_files": [{
      "format": "mpeg4",
      "created_at": "2010-01-01T00:00:00Z",
      "frame_rate": 29,
      "finished_at": "2010-01-01T00:00:00Z",
      "updated_at": "2010-01-01T00:00:00Z",
      "duration_in_ms": 24883,
      "audio_sample_rate": 44100,
      "url": "http://s3.amazonaws.com/bucket/video.mp4",
      "id": 1,
      "error_message": null,
      "error_class": null,
      "audio_bitrate_in_kbps": 92,
      "audio_codec": "aac",
      "height": 352,
      "file_size_bytes": 1386663,
      "video_codec": "h264",
      "test": false,
      "channels": "2",
      "width": 624,
      "video_bitrate_in_kbps": 351,
      "state": "finished",
      "label": "Web"
    }],
    "thumbnails": [{
      "created_at": "2010-01-01T00:00:00Z",
      "updated_at": "2010-01-01T00:00:00Z",
      "url": "http://s3.amazonaws.com/bucket/video/frame_0000.png",
      "id": 1
    }],
    "state": "finished"
  }
}]

Show XML Example

<api-response type="array">
  <job>
    <created-at type="datetime">2010-06-23T22:37:49Z</created-at>
    <finished-at type="datetime" nil="true"></finished-at>
    <id type="integer">3529</id>
    <pass-through nil="true"></pass-through>
    <state>waiting</state>
    <submitted-at type="datetime">2010-06-23T22:37:49Z</submitted-at>
    <test type="boolean">false</test>
    <updated-at type="datetime">2010-06-23T22:37:49Z</updated-at>
    <input-media-file>
      <audio-bitrate-in-kbps type="integer">128</audio-bitrate-in-kbps>
      <audio-codec>aac</audio-codec>
      <audio-sample-rate type="integer">48000</audio-sample-rate>
      <channels>2</channels>
      <created-at type="datetime">2010-06-23T22:37:49Z</created-at>
      <duration-in-ms type="integer">60000</duration-in-ms>
      <error-class nil="true"></error-class>
      <error-message nil="true"></error-message>
      <file-size-bytes type="integer">8209138</file-size-bytes>
      <finished-at type="datetime" nil="true"></finished-at>
      <format>mp4</format>
      <frame-rate type="integer">23</frame-rate>
      <height type="integer">272</height>
      <id type="integer">4451</id>
      <state>waiting</state>
      <test type="boolean">false</test>
      <updated-at type="datetime">2010-06-23T22:37:49Z</updated-at>
      <url>http://example.com/files/1234/matrix.mov</url>
      <video-bitrate-in-kbps type="integer">829</video-bitrate-in-kbps>
      <video-codec>h.264</video-codec>
      <width type="integer">640</width>
    </input-media-file>
    <output-media-files type="array"/>
    <thumbnails type="array"/>
  </job>
  <job>
    <created-at type="datetime">2010-06-23T22:37:49Z</created-at>
    <finished-at type="datetime" nil="true"></finished-at>
    <id type="integer">3527</id>
    <pass-through nil="true"></pass-through>
    <state>waiting</state>
    <submitted-at type="datetime">2010-06-23T22:37:49Z</submitted-at>
    <test type="boolean">false</test>
    <updated-at type="datetime">2010-06-23T22:37:49Z</updated-at>
    <input-media-file>
      <audio-bitrate-in-kbps type="integer">128</audio-bitrate-in-kbps>
      <audio-codec>aac</audio-codec>
      <audio-sample-rate type="integer">48000</audio-sample-rate>
      <channels>2</channels>
      <created-at type="datetime">2010-06-23T22:37:49Z</created-at>
      <duration-in-ms type="integer">60000</duration-in-ms>
      <error-class nil="true"></error-class>
      <error-message nil="true"></error-message>
      <file-size-bytes type="integer">8209138</file-size-bytes>
      <finished-at type="datetime" nil="true"></finished-at>
      <format>mp4</format>
      <frame-rate type="integer">23</frame-rate>
      <height type="integer">272</height>
      <id type="integer">4448</id>
      <state>waiting</state>
      <test type="boolean">false</test>
      <updated-at type="datetime">2010-06-23T22:37:49Z</updated-at>
      <url>http://example.com/files/1234/matrixy.mov</url>
      <video-bitrate-in-kbps type="integer">829</video-bitrate-in-kbps>
      <video-codec>h.264</video-codec>
      <width type="integer">640</width>
    </input-media-file>
    <output-media-files type="array"/>
    <thumbnails type="array"/>
  </job>
</api-response>

Job Details

You may also retrieve the details of a single job by sending an HTTP GET request to https://app.zencoder.com/api/jobs/1234?api_key=93h630j1dsyshjef620qlkavnmzui3. It will return the results similar to the JSON referenced above.

Resubmit a Job

If a job has failed processing you may request that it be attempted again. This is useful if the job failed to process due to a correctable problem. You may resubmit a job for processing by sending a request (using any HTTP method) to https://app.zencoder.com/api/jobs/1234/resubmit?api_key=93h630j1dsyshjef620qlkavnmzui3. If resubmission succeeds you will receive a 200 OK response. Only jobs that are not in the “finished” state may be resubmitted. If you attempt to resubmit a “finished” job you will receive a 409 Conflict response.

Cancel a Job

If you wish to cancel a job that has not yet finished processing you may send a request (using any HTTP method) to https://app.zencoder.com/api/jobs/1234/cancel?api_key=93h630j1dsyshjef620qlkavnmzui3. If cancellation succeeds you will receive a 200 OK response. Only jobs that are in the “waiting” or “processing” state may be cancelled. If you attempt to cancel a job in any other state you will receive a 409 Conflict response.

Delete a Job

If you wish to delete a job entirely you may send an HTTP DELETE request to https://app.zencoder.com/api/jobs/1234?api_key=93h630j1dsyshjef620qlkavnmzui3. If deletion succeeds you will receive a 200 OK response. Only jobs that are not in the “finished” state may be deleted. If you attempt to delete a “finished” job you will receive a 409 Conflict response.

7. Working with Accounts

Create an Account

You can create accounts by issuing an HTTP POST request to https://app.zencoder.com/api/account. All that is required is an email address and an agreement to the terms of service. You can also send a password, but if you don’t one will be generated. Subscription to the Zencoder newsletter is on by default, but you may pass "newsletter": "0" to prevent subscription. Finally, if you have been assigned an affiliate code, you may pass it here to note the account.

New accounts will be created under the Test (Free) plan.

The body of a new account request looks like this:

{
  "terms_of_service": "1",
  "email": "test@example.com",
  "password": "1234",
  "affiliate_code": "asdf1234"
}

Show XML Example

<api-request>
  <terms_of_service>1</terms_of_service>
  <email>test@example.com</email>
  <password>1234</password>
  <affiliate_code>asdf123</affiliate_code>
</api-request>

The response will contain both your new API key and password (either the one sent or auto-generated):

{
  "api_key": "a123afdaf23fa231245fadcbbb",
  "password": "1234"
}

Show XML Example

<api-response>
  <api_key>a123afdaf23fa231245fadcbbb</api_key>
  <password>1234</password>
</api-response>

Account Details

Account details may be retrieved by issuing an HTTP GET to https://app.zencoder.com/api/account?api_key=93h630j1dsyshjef620qlkavnmzui3 (replace the api_key with your own). This would result in the following:

{
  "account_state": "active",
  "plan": "Growth",
  "minutes_used": 12549,
  "minutes_included": 25000,
  "billing_state": "active",
  "integration_mode":true
}

Show XML Example

<api-response>
  <plan>Growth</plan>
  <account-state>active</account-state>
  <billing-state>active</billing-state>
  <integration-mode type="boolean">true</integration-mode>
  <minutes-included type="integer">25000</minutes-included>
  <minutes-used type="integer">12549</minutes-used>
</api-response>

Account Integration Mode

Integration mode can be turned on by issuing a request (using any HTTP method) to https://app.zencoder.com/api/account/integration. It can be turned off by issuing a request (using any HTTP method) to https://app.zencoder.com/api/account/live.

FAQs

What is an API?

An application programming interface (API) is an interface between your application and ours. Our API defines a set of conventions or protocols that can be used to communicate programmatically with Zencoder.

Where do I find my API key?

You can find your API key at https://app.zencoder.com/api. You can also regenerate your API key on that page.

What is Integration Mode?

Integration Mode is a setting on your account that allows you to test your integration of Zencoder without getting charged for encoding. You can read more about it in the Test Jobs and Integration Mode section.