Create a job
Endpoint: POST /v2/jobs
curl https://api.coconut.co/v2/jobs \
-u your-api-key: \
-d '{
"input": {
"url": "https://s3.amazonaws.com/bucket/file.avi"
},
"storage": {
"service": "s3",
"region": "us-east-1",
"bucket": "mybucket",
"credentials": {
"access_key_id": "...",
"secret_access_key": "..."
}
},
"notification": {
"type": "http",
"url": "http://site.com/webhook"
},
"outputs": {
"mp4:720p": {
"path": "/720p/video.mp4"
},
"mp4:1080p": {
"path": "/1080p/video.mp4"
},
"httpstream": {
"hls": {
"path": "/hls"
},
"dash": {
"path": "/dash",
"hlsfmp4": true
}
}
}
}'
Parameters
Name | Type | Default | Required |
settings The job settings. See Settings. |
hash |
|
No |
input The input file URL. See Input. |
hash |
|
Yes |
storage The storage service where all the outputs will be uploaded. See Storage. |
hash |
|
Yes |
outputs The outputs. See Outputs. |
hash |
|
Yes |
notification The notification settings to get notified when the job is completed. See Notification. |
hash |
|
Yes |
Response examples
When the job is successfully submitted:
HTTP/1.1 201 Created
Server: nginx/1.4.6 (Ubuntu)
Date: Wed, 08 Oct 2014 10:25:55 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: close
{
"id": "vdq1fShawHzyz3",
"created_at": "2021-02-15 14:39:46 +0100",
"completed_at": null,
"status": "job.starting",
"progress": "0%",
"input": {
"status": "input.starting"
},
"outputs": [
{
"key": "mp4:240p",
"type": "video",
"format": "mp4:240p",
"status": "video.waiting"
}
]
}
If there is an error with the request:
HTTP/1.1 400 Bad Request
Server: nginx/1.4.6 (Ubuntu)
Date: Wed, 08 Oct 2014 14:17:27 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: close
{
"message":"The storage credentials are not correct, you must define your 'access_key_id' and 'secret_access_key'.",
"error_code":"storage_credentials_not_valid",
"status":"error"
}
You can find the list of error codes here.
Getting information about a job
Endpoint: GET /v2/jobs/:jobid
curl https://api.coconut.co/v2/jobs/zfO55hr7AfAsld -u your-api-key:
{
"id": "zfO55hr7AfAsld",
"created_at": "2021-02-15 13:43:42 +0000",
"completed_at": "2021-02-15 13:46:34 +0000",
"status": "job.completed",
"progress": "100%",
"input": {
"status": "input.transferred"
},
"outputs": [
{
"key": "mp4",
"type": "video",
"format": "mp4",
"url": "http://cdn.coconut.co/test.mp4",
"status": "video.encoded"
},
{
"key": "httpstream",
"type": "httpstream",
"format": "httpstream",
"urls": [
{
"format": "dash",
"url": "http://cdn.coconut.co/dash/master.mpd"
},
{
"format": "hls",
"url": "http://cdn.coconut.co/hls/master.m3u8"
}
],
"status": "httpstream.packaged"
},
{
"key": "jpg:320x",
"type": "image",
"format": "jpg:320x",
"urls": [
"http://cdn.coconut.co/jpg/thumbs_01.jpg",
"http://cdn.coconut.co/jpg/thumbs_02.jpg",
"http://cdn.coconut.co/jpg/thumbs_03.jpg",
"http://cdn.coconut.co/jpg/thumbs_04.jpg",
"http://cdn.coconut.co/jpg/thumbs_05.jpg",
"http://cdn.coconut.co/jpg/thumbs_06.jpg",
"http://cdn.coconut.co/jpg/thumbs_07.jpg"
],
"status": "image.created"
}
]
}
Job status
Here are the list of status you can see:
Status | Description |
job.starting |
The job has just been created and will start now. |
job.completed |
The job is completed and successful. |
job.failed |
The job is completed but contains at least one failed process. |
input.starting |
We just started the job and the input file is about to be transferred to Coconut. |
input.transferring |
The input file is transferring to Coconut. |
input.transferred |
The input file is transferred to Coconut, ready for processing all the outputs. |
input.failed |
The input file hasn't been transferred properly because of URL returning an error, or broken media file. |
video.waiting |
The output process is not enqueued yet for processing. The input file is still transferring. |
video.queued |
The output process is queued for processing and should start. |
video.encoding |
The video is encoding. |
video.encoded |
The video has been encoded and uploaded successfully. |
video.failed |
We encounter an FFmpeg error while converting the input file. |
video.skipped |
The output video has been skipped because of the output condition returned false. |
image.waiting |
The output process is not enqueued yet for processing. The input file is still transferring. |
image.queued |
The output process is queued for processing and should start. |
image.processing |
The images are being genetated. |
image.created |
The images has been created and uploaded successfully. |
image.failed |
We got an error while generating the images or we couldn't upload them to your storage. |
image.skipped |
The output image has been skipped because of the output condition returned false. |
httpstream.waiting |
The output process is not enqueued yet for processing. The input file is still transferring. |
httpstream.queued |
The output process is queued for processing and should start. |
httpstream.variants.encoding |
We are encoding the input file into multiple variants. |
httpstream.packaging |
We are currently packaging into HLS/Dash. |
httpstream.packaged |
The playlist (m3u8, mpd) and media files have been generated and uploaded successfully. |
httpstream.failed |
We got an error while packaging or we couldn't upload the media files to your storage. |
httpstream.skipped |
The output image has been skipped because of the output condition returned false. |
Conditional outputs
By using if, you can choose if an output needs to be processed or not according to a condition. If the condition returns false, then the output will be skipped.
Prevent upscaling
You won't want to convert a 720p video to 4k output, that would be a waste of time, space and money. So to avoid that, we've created those conditional outputs to help you:
{
"outputs": {
"mp4:360p::quality=4": {
"key": "mp4:360p",
"path": "/mp4/360p/video.mp4",
"if": "{{ input.width }} >= 480"
},
"mp4:480p::quality=4": {
"key": "mp4:480p",
"path": "/mp4/480p/video.mp4",
"if": "{{ input.width }} >= 720"
},
"mp4:720p::quality=4": {
"key": "mp4:720p",
"path": "/mp4/720p/video.mp4",
"if": "{{ input.width }} >= 1280"
},
"mp4:1080p::quality=4": {
"key": "mp4:1080p",
"path": "/mp4/1080p/video.mp4",
"if": "{{ input.width }} >= 1920"
},
"mp4:2160p::quality=4": {
"key": "mp4:2160p",
"path": "/mp4/2160p/video.mp4",
"if": "{{ input.width }} >= 3840"
}
}
}
Detecting portrait or landscape videos
Sometimes you want to use different resolution depending on the orientation. Here is an example for both portrait and landscape which takes into account the rotation metadata + source resolution:
{
"outputs": {
"mp4:x1024::quality=3": {
"key": "mp4"
"path": "video.mp4",
"if": "({{ input.rotation }} = 0 or {{ input.rotation }} = 180) and {{ input.width }} > {{ input.height }}"
},
"mp4:1024x::quality=3": {
"key": "mp4"
"path": "video.mp4",
"if": "(({{ input.rotation }} = 90 or {{ input.rotation }} = 270) and {{ input.width }} > {{ input.height }}) or {{ input.height }} > {{ input.width }}"
}
}
}
Same output format with different settings
There are many reasons why you would want to create multiple outputs with the same format but different settings, like generating regular thumbnails and squared ones with the same resolution, or even creating a trailer by cutting the output.
Here is an example:
{
"outputs": {
"mp4:::quality=4": [
{
"key": "mp4:trailer",
"path": "trailer.mp4",
"duration": 60
},
{
"key": "mp4",
"path": "video.mp4"
}
],
"jpg:400x": [
{
"key": "jpg:reg",
"path": "thumb_%.2d.jpg",
"number": 10
},
{
"key": "jpg:sq",
"path": "thumb_sq_%.2d.jpg",
"number": 4,
"square": true
}
]
}
}
Note that if you don't provide a key, it will be generated for you following this rule: format:index.
Ultrafast Mode
If enable, the input video is split into small chunks that are transcoded in parallel over multiple servers. The speed is greatly increased, for instance, you can expect x5 speed for 4k outputs.
We advise to use the Ultrafast mode in the following cases:
- If your videos are longer than 10 minutes
- Your job includes 1080p and 4k outputs
- Any HEVC transcoding
Note that ultrasfast only works for videos longer than a minute.
curl https://api.coconut.co/v2/jobs \
-u your-api-key: \
-d '
{
"settings": {
"ultrafast": true
},
"input": {
"url": "https://s3.amazonaws.com/bucket/4k.mp4"
},
"storage": {
"service": "s3",
"region": "us-east-1",
"bucket": "mybucket",
"credentials": {
"access_key_id": "...",
"secret_access_key": "..."
}
},
"notification": {
"type": "http",
"url": "http://site.com/webhook"
},
"outputs": {
"mp4:hevc_2160p": {
"path": "/4k/video.mp4"
},
"mp4:hevc_1080p": {
"path": "/1080p/video.mp4"
}
}
}'