NAV Navbar
Logo
shell JavaScript

SYNQ API Guide

Introduction

Welcome to the SYNQ Video API documentation.

You can use our API to handle all your video needs.

If you have any feedback or questions, don’t hesitate to contact us at support@synq.fm.

Note: example code will be shown here on the right side. You can select your preferred language at the top to show the examples in that language.

Note: example code will be shown in black boxes like these. You can select your preferred language from the list on the left.

Note: example code will be shown in black boxes like these. You can select your preferred language from the nav bar, opened via the button on the top left.

// Language is currently set to JavaScript
#  Language is currently set to shell

What our API can do for you

Projects and API keys

To use our API, you need to have an API key. Each API key corresponds to a project.

A project is a collection of videos, and settings regarding those videos, such as webhooks.

After registering, you can create projects from your SYNQ admin panel. It is recommended that you use a seperate project for each application you develop.

The API key is then used as a secret key that allows you to create and manage your videos through http calls.

Only share your API key internally, as anyone with your API key can upload videos in your name. And if you are using the SYNQ api from an app or a website, make sure not to put the API key in the source code. In those cases, the app or website should communicate with your servers, so you can authenticate their requests before sending http calls to SYNQ from your servers.

To obtain API keys and manage your projects, register for an account.

Essential resources

If you want to simply use our HTTP API directly, you can view our API documentation and Swagger specification here:

If you want to use one of our auto generated SDKs, you can find the repositories here:

Usage examples

SDK setup

Our SDKs are auto generated, and updated every time the spec changes. The specs version number is given by three numbers, x.y.z, where x is incremented only when API compatibility is broken, y is incremented when new features are added in a backwards-compatible fashion, and z is incremented for any change, including simple documentation updates.

Depending on what SDK you use, some dependencies may need to be installed before you can get started with the SDK.

For these examples we will be using cURL, so download it from their page, or install it through your package manager.

After downloading our JavaScript SDK, you can install all its dependencies by running npm install in its top level directory.

const synq = require('./synq/index.js');

var SYNQ_API_KEY = "...";
// The VideoApi object allows you to manipulate videos.
video = new synq.VideoApi();
export SYNQ_API_KEY="..."

Examples and documentation

Each SDK contains auto generated language specific documentation and a handwritten test suite you can use as reference.

For documentation of the raw HTTP protocol, check out the API documentation.

Check out the docs folder in the JavaScript SDK to get the API documentation.

Video objects

A video object is a collection of metadata describing one video. It contains numerous fixed fields that are the same for all videos, and a userdata field that can contain anything you desire.

By default, the video object is an almost empty json object, as seen on the right.

By default, the video object is an almost empty json object, as seen below.

By default, the video object is an almost empty json object, as seen below.

Once new information regarding the video is available, the video objects gets populated with it, such as when a video is uploaded into it, or when new userdata is supplied.

Most importantly, the video object contains URLs that point to resources on our CDNs, such as thumbnails, the video in various formats, and an embed link.

Below is a freshly created video object, without any user-specified userdata.

{
    "video_id": "4e063ab632f24992aced5c6f8983229f",
    "state": "created",
    "userdata":{
    },
    "created_at": "2016-10-09T19:30:29.981Z",
    "updated_at": "2016-10-09T19:30:29.981Z"
}

Below is a video object that has been uploaded into, and with userdata set. The transcoding for the webm version of the video is still in progress, but you can still view the video at https://synq.fm/embed/4e063ab632f24992aced5c6f8983229f where it uses the currently available transcodings.

{
    "video_id": "4e063ab632f24992aced5c6f8983229f",
    "input": {
        "url": "https://dcuu5ylopkzzf.cloudfront.net/projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/uploads/videos/4e/06/4e063ab632f24992aced5c6f8983229f.mp4",
        "width": 1920,
        "height": 1080,
        "duration": "15.926000",
        "file_size": 34404630,
        "framerate": 29.51,
        "uploaded_at": "2016-10-09T15:36:54.624-04:00"
    },
    "state": "uploaded",
    "player": {
        "views": 0,
        "embed_url": "https://player.synq.fm/embed/4e063ab632f24992aced5c6f8983229f"
    },
    "outputs": {
        "hls": {
            "url": "https://dcuu5ylopkzzf.cloudfront.net/projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/derivatives/videos/4e/06/4e063ab632f24992aced5c6f8983229f/hls/4e063ab632f24992aced5c6f8983229f_hls.m3u8",
            "state": "complete"
        },
        "mp4_360": {
            "url": "https://dcuu5ylopkzzf.cloudfront.net/projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/derivatives/videos/4e/06/4e063ab632f24992aced5c6f8983229f/mp4_360/4e063ab632f24992aced5c6f8983229f_mp4_360.mp4",
            "state": "complete"
        },
        "mp4_720": {
            "url": "https://dcuu5ylopkzzf.cloudfront.net/projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/derivatives/videos/4e/06/4e063ab632f24992aced5c6f8983229f/mp4_720/4e063ab632f24992aced5c6f8983229f_mp4_720.mp4",
            "state": "complete"
        },
        "mp4_1080": {
            "url": "https://dcuu5ylopkzzf.cloudfront.net/projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/derivatives/videos/4e/06/4e063ab632f24992aced5c6f8983229f/mp4_1080/4e063ab632f24992aced5c6f8983229f_mp4_1080.mp4",
            "state": "complete"
        },
        "webm_720": {
            "state": "progressing"
        }
    },
    "userdata": {
        "foo": "bar"
    },
    "created_at": "2016-08-01T15:41:51.555Z",
    "updated_at": "2016-10-09T19:37:10.281Z"
}

Creating a video object

/v1/video/create

When working with a video using the SYNQ API, the first step is to create a video object.

Once you’ve created a video object, you can upload a video file into it or add custom metadata to it, and organize your videos.

Also, when creating a video object, you can optionally supply arbitrary userdata.

The following command creates a new video object, with userdata attached to it.
The userdata part can be dropped, if you just want an empty video object.

curl -s https://api.synq.fm/v1/video/create \
    -F api_key=${SYNQ_API_KEY} \
    -F userdata='{"foo": "bar", "baz":"boo"}'
var userdata = '{"foo": "bar", "baz":"boo"}'
video.create(SYNQ_API_KEY, {userdata: userdata}, function(error, data, response){
    if (error) {
        console.log("Error: ", error);
    } else {
        console.log(data);
    }
});

You will get something like the following returned:

{
    "video_id": "4e063ab632f24992aced5c6f8983229f",
    "state": "created",
    "created_at": "2016-10-09T19:30:29.981Z",
    "updated_at": "2016-10-09T19:30:29.981Z",
    "userdata": {
        "foo":"bar",
        "baz":"boo"
    }
}
({
    video_id: "4e063ab632f24992aced5c6f8983229f",
    state: "created",
    created_at: "2016-10-09T19:30:29.981Z",
    updated_at: "2016-10-09T19:30:29.981Z",
    userdata: {
        foo:"bar",
        baz:"boo"
    }
})

Retrieving a video’s metadata

/v1/video/details

You can retrieve the complete metadata object for any video you want.

See also v1/video/query to find videos based on matching metadata criteria and v1/video/update to set metadata after creation.

To retrieve a video’s metadata, you can use the following:

curl -s https://api.synq.fm/v1/video/details \
    -F api_key=${SYNQ_API_KEY} \
    -F video_id="4e063ab632f24992aced5c6f8983229f" \
var video_id = "4e063ab632f24992aced5c6f8983229f";
video.details( SYNQ_API_KEY, video_id, function(error, data, response){
    if (error) {
        console.log("Error: ",error);
    } else {
        console.log(data);
    }
});

You will get a video object returned.

Updating a video’s metadata

/v1/video/update

Once you have created a video object, you can start populating the userdata field with any information you want.

This is done by sending a JavaScript code snippet that modifies the video object.

From within the JavaScript code, you have access to an object called video, which represents the video object that you are updating. You can modify the video object however you want, though only changes to the userdata field is applied to the actual video object.

To set userdata in a video, you can use the following:
This will set the baz variable inside userdata to "bar"

curl -s https://api.synq.fm/v1/video/update \
    -F api_key=${SYNQ_API_KEY} \
    -F video_id ="4e063ab632f24992aced5c6f8983229f"
    -F source='video.userdata.baz = "boo"'
var video_id = "4e063ab632f24992aced5c6f8983229f";
var source = 'video.userdata.baz = "boo"';
video.update(SYNQ_API_KEY,video_id,source,function(error,data,response){
    if (error) {
        console.log("Error!");
    } else {
        console.log(data);
    }
});

Assuming you started out with an empty object, you will get the following returned:

{
    "video_id": "4e063ab632f24992aced5c6f8983229f",
    "state": "created",
    "created_at": "2016-10-09T19:30:29.981Z",
    "updated_at": "2016-10-09T19:30:29.981Z",
    "userdata": {
        "baz":"boo"
    }
}
({
    video_id: "4e063ab632f24992aced5c6f8983229f",
    state: "created",
    created_at: "2016-10-09T19:30:29.981Z",
    updated_at: "2016-10-09T19:30:29.981Z",
    userdata: {
        baz:"boo"
    }
})

You can also use values from elsewhere in the video object.
The following source copies the embed url into the userdata.

if (video.player != null){
    video.userdata.player = video.player.embed_url
}

Query against the metadata

/v1/video/query

You can query existing videos for matching metadata by performing a JavaScript query. This allows you to run an arbitrary JavaScript function to analyze your video objects, and return any desirable information. The JavaScript function is run against each video object in your project, and can return results in any format you want.

This can be used to check if a metadata has a certain value, perform fuzzy searching, matching against a range, or anything else.

From within the filter, you have access to an object called video, which represents a video object. You can perform tests on it, and return values contained within it.

Basic usage example, which returns all videos in your project.

curl -s https://api.synq.fm/v1/video/query \
    -F api_key=${SYNQ_API_KEY} \
    -F filter='return video'
query = `return video`
video.query(SYNQ_API_KEY,query,query,function(error,data,response){
    if (error) {
        console.log("Error!");
    } else {
        console.log(data);
    }
})

This simply returns a list of video objects.

A more complex example. The following filter returns userdata.foo if the video has over 300 views, but only if userdata.foo exists.

curl -s https://api.synq.fm/v1/video/query \
    -F api_key=${SYNQ_API_KEY} \
    -F filter='
    if (video.views > 300) {
        return video.userdata.foo
    }
    '
query = `
if (video.views > 300) {
    return video.userdata.foo
}
`
video.query(SYNQ_API_KEY,query,query,function(error,data,response){
    if (error) {
        console.log("Error!");
    } else {
        console.log(data);
    }
})

This will return a list like this. Notice how it’s an array of just strings.

[
    "bar",
    "baz"
]

You can also return the entire video object using return video, or only certain keys using the built-in video.pick() and video.omit() functions.
Here is a filter that uses video.pick to return all video_ids and player information, if the video has over 500 views.

if(video.player != undefined && video.player.views > 500){
    return video.pick("video_id","player")
}

We also fully support using moment.js within the filter, to perform calculations on times and dates.
The following filter returns the video_id of all videos created this month:

if(moment(video.created_at) >= moment().startOf("month")) return video.video_id;

In addition to moment.js, we also support lodash for additional utility and ease of use.

Finally, you can throw errors from within the filter. When throwing an error, the execution is stopped, and only that one error is returned.
The below filter throws an error if any video has a userdata foo that doesn’t equal "bar", or that doesn’t have a foo userdata at all:

if(video.userdata.foo != "boo") throw video.pick("video_id","userdata");

You will get something like the following returned:
more info can be found under Errors.

{
    "name": "javascript_query",
    "message": "An error occurred while processing your JavaScript query.",
    "url": "https://docs.synq.fm/api/v1/errors/javascript_query",
    "details": {
        "type": "runtime",
        "error": {
            "video_id": "4e063ab632f24992aced5c6f8983229f",
            "userdata": {"foo":"bar", "baz":"boo"}
        },
        "line": "if(video.userdata.foo != \"bar\") throw video.pick(\"video_id\",\"userdata\");",
        "line_number": 1
    }
}

Uploading a video

/v1/video/upload

This function is for returning upload information, to implement your own uploading mechanism. If you want a simple drag-and-drop/file-selection uploading widget, check out the v1/video/uploader.

Uploading a video happens in two steps: First, you make a v1/video/upload request to our service, which will return all the necessary parameters to upload the video. Second, you make a multipart POST request where you use these parameters to perform the uploading of the video to the Amazon servers.

The reason for this is so that the information can be used by the end-client, to upload directly to Amazon, without having to go through your servers. This also ensures the fastest upload time.

When the video’s uploaded, you can receive webhook events to be notified when uploading and transcoding of the video has finished. Additionally, you can use v1/video/details to retrieve information about the video such as the embed and file URL.

To upload the video, we use the upload function to get the parameters we require.

curl -s https://api.synq.fm/v1/video/upload \
    -F api_key=${SYNQ_API_KEY} \
    -F video_id="4e063ab632f24992aced5c6f8983229f"
var video_id = "4e063ab632f24992aced5c6f8983229f";
video.upload(SYNQ_API_KEY, video_id, function(error, data, response){
    if (error) {
        console.log("Error: ", error);
    } else {
        parameters = data;
        console.log(parameters);
    }
});

You’ll get something like the following returned. These are the parameters needed to upload the video directly to Amazon S3.

{
    "acl": "public-read",
    "key": "projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/uploads/videos/4e/06/4e063ab632f24992aced5c6f8983229f.mp4",
    "Policy": "eyJjb25kaXRpb25zIjogW3siYnVja2V0IjogInN5bnFmbSJ9LCB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LCBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAicHJvamVjdHMvMWMvZDcvMWNkNzQ5NGI5ZTg3NDFlMjg1MjA1NWU5ODQ4NmJjNDYvdXBsb2Fkcy92aWRlb3MvNDMvMGEvNDMwYWU1MTEwZTVjNDMxOTk3NWQ3ODQ4NzA4NjA4MmMubXA0Il0sIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICJ2aWRlby9tcDQiXSwgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIDEwOTk1MTE2Mjc3NzZdXSwgImV4cGlyYXRpb24iOiAiMjAxNi0wOC0wMlQxNTo1MzoxOS4yMTZaIn0=",
    "action": "https://synqfm.s3.amazonaws.com",
    "Signature": "Rwilcb1jl4xrLYbOxsL2xsA7g3o=",
    "Content-Type": "video/mp4",
    "AWSAccessKeyId": "AKIAIP77Y7MMX3ITZMFA"
}
({
    acl: "public-read",
    key: "projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/uploads/videos/4e/06/4e063ab632f24992aced5c6f8983229f.mp4",
    Policy: "eyJjb25kaXRpb25zIjogW3siYnVja2V0IjogInN5bnFmbSJ9LCB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LCBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAicHJvamVjdHMvMWMvZDcvMWNkNzQ5NGI5ZTg3NDFlMjg1MjA1NWU5ODQ4NmJjNDYvdXBsb2Fkcy92aWRlb3MvNDMvMGEvNDMwYWU1MTEwZTVjNDMxOTk3NWQ3ODQ4NzA4NjA4MmMubXA0Il0sIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICJ2aWRlby9tcDQiXSwgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIDEwOTk1MTE2Mjc3NzZdXSwgImV4cGlyYXRpb24iOiAiMjAxNi0wOC0wMlQxNTo1MzoxOS4yMTZaIn0=",
    action: "https://synqfm.s3.amazonaws.com",
    Signature: "Rwilcb1jl4xrLYbOxsL2xsA7g3o=",
    "Content-Type": "video/mp4",
    AWSAccessKeyId: "AKIAIP77Y7MMX3ITZMFA"
})

After you have retrieved these parameters, you can forward them to the client that is actually going to perform the upload. The information can then be used on client-side to upload directly from their end to Amazon S3. This ensures the fastest upload time, and least amount of load on your servers.

curl -s https://synqfm.s3.amazonaws.com \
    -F AWSAccessKeyId="AKIAIP77Y7MMX3ITZMFA" \
    -F Content-Type="video/mp4" \
    -F Policy="eyJjb25kaXRpb25zIjogW3siYnVja2V0IjogInN5bnFmbSJ9LCB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LCBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAicHJvamVjdHMvMWMvZDcvMWNkNzQ5NGI5ZTg3NDFlMjg1MjA1NWU5ODQ4NmJjNDYvdXBsb2Fkcy92aWRlb3MvNDMvMGEvNDMwYWU1MTEwZTVjNDMxOTk3NWQ3ODQ4NzA4NjA4MmMubXA0Il0sIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICJ2aWRlby9tcDQiXSwgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIDEwOTk1MTE2Mjc3NzZdXSwgImV4cGlyYXRpb24iOiAiMjAxNi0wOC0wMlQxNTo1MzoxOS4yMTZaIn0=" \
    -F Signature="Rwilcb1jl4xrLYbOxsL2xsA7g3o=" \
    -F acl="public-read" \
    -F key="projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/uploads/videos/4e/06/4e063ab632f24992aced5c6f8983229f.mp4" \
    -F file="@BigBuckBunny.mp4"

For this example, we will be using therequest library to perform a multipart POST request. It can be installed through npm.
We also need fs to load in the file.

const request = require('request');
const fs = require('fs');

var file = fs.createReadStream('BigBuckBunny.mp4');
var url = parameters["action"];
upload_parameters = {
    "AWSAccessKeyId" : parameters['AWSAccessKeyId'],
    "Content-Type": parameters['Content-Type'],
    "Policy": parameters['Policy'],
    "Signature": parameters['Signature'],
    "acl": parameters['acl'],
    "key": parameters['key'],
    "file": file
}
request.post({url : url, formData: upload_parameters}, function(error, response, body){
    if (error) {
        console.log("Error: ", error);
    } else {
        console.log("File upload accepted");
    }
});

You can then check if the file was uploaded. The “file_state” metadata should be set to ‘uploaded’.
You can also be notified of this through a webhook!

curl -s https://api.synq.fm/v1/video/details \
    -F api_key=${SYNQ_API_KEY} \
    -F video_id="4e063ab632f24992aced5c6f8983229f"
video.details(SYNQ_API_KEY, "4e063ab632f24992aced5c6f8983229f", function (error, data, reponse){
    if (error) {
        console.log("Error: ", error)
    } else {
        console.log(data);
    }
});

You should get something like the following in return if the upload was successful.
The state might be ‘uploading’ if the upload hasn’t finished yet.

{
    "video_id": "4e063ab632f24992aced5c6f8983229f",
    "state": "uploaded",
    "input": {
        "url": "https://dcuu5ylopkzzf.cloudfront.net/projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/uploads/videos/4e/06/4e063ab632f24992aced5c6f8983229f.mp4",
        "width": 1920,
        "height": 1080,
        "duration": "15.926000",
        "file_size": 34404630,
        "framerate": 29.51,
        "uploaded_at": "2016-10-09T15:36:54.624-04:00"
    },
    "player": {
        "views": 0,
        "embed_url": "https://player.synq.fm/embed/4e063ab632f24992aced5c6f8983229f"
    },
    "outputs": {
        "hls": {
            "state": "progressing"
        },
        "mp4_360": {
            "state": "progressing"
        },
        "mp4_720": {
            "state": "progressing"
        },
        "mp4_1080": {
            "state": "progressing"
        },
        "webm_720": {
            "state": "progressing"
        }
    },
    "created_at": "2016-08-01T15:41:51.555Z",
    "updated_at": "2016-10-09T19:37:10.281Z"
}
({
    input: {
        url:
"https://dcuu5ylopkzzf.cloudfront.net/projects/1c/d7/1cd7494b9e8741e2852055e98486bc46/uploads/videos/4e/06/4e063ab632f24992aced5c6f8983229f.mp4",
        width: 1920,
        height: 1080,
        duration: "15.926000",
        file_size: 34404630,
        framerate: 29.51,
        uploaded_at: "2016-10-09T15:36:54.624-04:00"
    },
    state: "uploaded",
    player: {
        views: 0,
        embed_url: "https://player.synq.fm/embed/4e063ab632f24992aced5c6f8983229f"
    },
    outputs: {
        hls: {
            state: "progressing"
        },
        mp4_360: {
            state: "progressing"
        },
        mp4_720: {
            state: "progressing"
        },
        mp4_1080: {
            state: "progressing"
        },
        webm_720: {
            state: "progressing"
        }
    },
    video_id: "4e063ab632f24992aced5c6f8983229f",
    created_at: "2016-08-01T15:41:51.555Z",
    updated_at: "2016-10-09T19:37:10.281Z"
})

Embeddable uploader widget

/v1/video/uploader

For ease of use, we offer an embeddable uploading widget that you can use as part of your webpage or webapp.

This widget works on all platforms, and comes with many features, such as an upload progress indicator, retrying an upload, canceling an upload, resuming an upload, uploading directly from your phone’s camera, and more.

Customization

The uploader_url returned by the API call can be further modified to customize the look of the uploader widget.

Parameter Function Type Default Note
skin.background Set the color of the uploader widget’s background. Hex color 4E565E You have to leave out the ‘#’ at the beginning of the hex color.
skin.text Set the color of the uploader widget’s text. Hex color FFFFFF You have to leave out the ‘#’ at the beginning of the hex color.
skin.progress Set the color of the uploader widget’s progress-bar. Hex color 43BFA7 You have to leave out the ‘#’ at the beginning of the hex color.
skin.success Set the color of the uploader widget’s success icon. Hex color 43BFA7 You have to leave out the ‘#’ at the beginning of the hex color.
skin.error Set the color of the uploader widget’s error icon. Hex color D44747 You have to leave out the ‘#’ at the beginning of the hex color.

Below is an example of how to generate the url to an embeddable uploader page that is valid for 3 hours.

curl -s https://api.synq.fm/v1/video/uploader \
    -F api_key=${SYNQ_API_KEY} \
    -F video_id="4e063ab632f24992aced5c6f8983229f"
    -F timeout="3 hours"
var video_id = "4e063ab632f24992aced5c6f8983229f";
video.uploader(SYNQ_API_KEY, video_id, {timeout:'3 hours'}, function(error, data, response){
    if (error) {
        console.log("Error: ", error);
    } else {
        parameters = data;
        console.log(parameters);
    }
});

The timeout is optional. If you don’t set it, it’s set to '2 hours'. Also, any timeout value greater than '2 days' gets set to '2 days'.

This returns an object with a url in it, like so:

{
    "uploader_url": "https://synq.fm/uploader/4e063ab632f24992aced5c6f8983229f?token=692996dd57684aa484bdf0a81dbb1ec2"
}
({
    uploader_url: "https://synq.fm/uploader/4e063ab632f24992aced5c6f8983229f?token=692996dd57684aa484bdf0a81dbb1ec2"
})

This url can then be embedded into your page using an iframe.

<iframe src="https://synq.fm/uploader/4e063ab632f24992aced5c6f8983229f?token=692996dd57684aa484bdf0a81dbb1ec2" style="border-radius:20px;"> </iframe>

Below is an example iframe with embedded uploader widget.

Note: This example uploader widget is for demonstration only, and does not actually allow for uploading a file.

We can also modify the look of the uploader widget by adding further query parameters to the url string.
For example, the link below gives the uploader a black background, and a purple progress-bar.

    <iframe src="https://synq.fm/uploader/4e063ab632f24992aced5c6f8983229f?token=692996dd57684aa484bdf0a81dbb1ec2&skin.background=000000&skin.progress=4E579E"></iframe>

Errors

Error objects

If an error occurs when performing any of our API calls, you will get http status 400 returned, together with an error object.

The error object is a simple json Object with the following 3 or 4 fields:

Field Description
url Error identifier, unique to the error. Also doubles a webpage link you can follow to get a more detailed description of the error.
name Error name, unique to the error.
message A lengthy description of the error.
details Optional additional information about what went wrong in this API call.

Example error object, returned if you use a wrong API key:

{
  "url": "https://docs.synq.fm/api/v1/errors/not_found_api_key",
  "name": "not_found_api_key",
  "message": "API key not found."
}

List of all possible errors

Name Message
conflict_video_state Video is in the wrong state for this action.
conflict_video_stream_already_uploading Uploading of this video has already started. You may upload a video file, or stream the video, but not both.
invalid_json Invalid JSON.
invalid_json_object Invalid JSON object.
invalid_timestamptz Invalid timestamptz.
invalid_uuid Invalid uuid.
missing_parameter A parameter required for this function was missing from the request.
not_found_api_key API key not found.
not_found_video Video not found.
http_not_found Not found.
javascript_query An error occurred while processing your JavaScript query.

Embedded video player

Whenever you upload a video to our servers, an embed link is generated, called embed_url in the metadata.

This links to a page that shows the video in the browser, and can also be embedded into other pages.

To the right you can see an example of an embedded version of a video uploaded through the SYNQ API.

Below you can see an example of an embedded version of a video uploaded through the SYNQ API.

Below you can see an example of an embedded version of a video uploaded through the SYNQ API.

Embedding your video

To embed a video in your page, simply use an iframe tag with src set to a valid embed link. You also need to give the iframe an allowFullScreen attribute if you want the video to be able to go fullscreen.

The following is a minimal html snippet to embed a video:

<iframe allowFullScreen
src="https://player.synq.fm/embed/4e063ab632f24992aced5c6f8983229f"></iframe>

If you are using jQuery, you can put the following javascript snippet in your page’s header to ensure that the iframes always have a 16:9 ratio:

<script>
    $(document).ready(function() {
        $("iframe").each(function(){
            $(this).height($(this).width()*9/16);
        });
        window.addEventListener("resize", function() {
            $("iframe").each(function(){
                $(this).height($(this).width()*9/16);
            });
        });
    });
</script>

Parameters

You can also modify the player’s behavior by adding parameters to the embed link’s query string.

Parameter Function Type Default Note
autostart Automatically start the video when the user enters the webpage. Boolean false Does not work on mobile devices.
mute Start the video with no audio volume. Boolean false The user can still unmute the video through the volume controls.
repeat Automatically replay the video once it’s over. Boolean false  
autofullscreen Automatically fullscreen the player when the user first starts the video. Boolean false Does not work together with autostart.
seek Set the starting point of the video, in seconds. Number 0  
preload Start buffering the video before the user starts playing it. Boolean true Preload functionality can vary from browser to browser.
skin.background Set the color of the video controls’ background. Hex color 000000 You have to leave out the ‘#’ at the beginning of the hex color.
skin.inactive Set the color of the video controls’ non-highlighted elements. Hex color FFFFFF You have to leave out the ‘#’ at the beginning of the hex color.
skin.active Set the color of the video controls’ highlighted elements. Hex color 43BFA7 You have to leave out the ‘#’ at the beginning of the hex color.

For example, the following code will create a video that plays automatically when the site is loaded, without sound, and restarts once it’s finished. It also changes the color of highlighted items in the controls to a purple color.

<iframe allowFullScreen
src="https://player.synq.fm/embed/4e063ab632f24992aced5c6f8983229f?autostart=true&mute=true&repeat=true&skin.active=4E579E"></iframe>

Webhooks

Synq allows for using webhooks to signal events. Through webhooks, we send your server an http post request whenever anything interesting occurs. You can decide what events you are interested in monitoring, on your project page, by setting a JavaScript webhook execution code to fire a webhook whenever anything interesting occurs.

Webhook JavaScript code

On your project page, you can write custom webhook execution code in JavaScript, that we will run on our servers. Within these code snippets, you can fire a webhook to your server, as well as to other APIs.

You can set three different webhook functions. on_video_create, on_video_ update and on__video_delete.

All three functions take two parameters. The first one represents the video object before the change, and the second one represents the video object after the change. These can be used together to analyze if new interesting data has been added to the video object, or if an interesting state-change has occured.

Example on_video_update function, which sends a webhook to https://your.website/synq/thumbnail, containing the thumbnail url, whenever a thumbnail is generated for any of your videos.

function on_video_update(oldVideo, newVideo) {
  if(
    oldVideo.get("player.thumbnail_url") == undefined
    &&
    newVideo.get("player.thumbnail_url") != undefined
  ){
    v1.http.POST({
      "url": "https://your.website/synq/thumbnail",
      "headers": {
        "video-url": newVideo.player.thumbnail_url
      }
    });
  }
}

Example on_video_update webhook that sends a webhook to https://your.website/synq/webhook-endpoint whenever a video has finished uploading, and whenever a video has finished transcoding.
It sends different body data, depending on the event, in the application/x-www-form-urlencoded format.

function on_video_update(oldVideo, newVideo) {

  // Set the url we want to send the webhook to
  url = "https://your.website/synq/webhook-endpoint"

  // Check for upload complete
  if(
    oldVideo.state != "uploaded"
    &&
    newVideo.state == "uploaded"
  ){
    v1.http.POST({
      "url": url,
      "rawBody": "event=video_upload&video_id=" + newVideo.video_id
    });
  }

  // Check for transcode complete
  if(
    (oldVideo.get("outputs.hls.state") != "complete"
    || oldVideo.get("outputs.mp4_360.state") != "complete"
    || oldVideo.get("outputs.mp4_720.state") != "complete"
    || oldVideo.get("outputs.mp4_1080.state") != "complete"
    || oldVideo.get("outputs.webm_720.state") != "complete")
    &&
    (newVideo.get("outputs.hls.state") == "complete"
    && newVideo.get("outputs.mp4_360.state") == "complete"
    && newVideo.get("outputs.mp4_720.state") == "complete"
    && newVideo.get("outputs.mp4_1080.state") == "complete"
    && newVideo.get("outputs.webm_720.state") == "complete")
  ){
    v1.http.POST({
      "url": url,
      "rawBody": "event=transcode_complete&video_id=" + newVideo.video_id
    });
  }
}

Replying to a webhook

When a webhook post request is sent to your server, we wait for a successful response, with status code 200. If the post request fails, or your server returns any other status code, the HTTP post request is considered failed, and will be retried after a while.

JavaScript execution

Many of our features make use of JavaScript code executions, such as updates, queries and webhooks.

For this, we allow you to execute arbitrary JavaScript code on our servers.

We support all basic V8 functionality, as well as the additional libraries moment.js and lodash.