Building videos using the REST API

Narakeet has a REST API that enables you to integrate video builds into your own software, or programmable flows.

NOTE: The easiest way to build Narakeet projects from files on your disk, or integrate video builds into simple workflows, is to use our command-line utility. Unless you want to program your own interactions for some reason, it’s better to use the command-line client instead.

This page explains how to implement your own client. Our command-line client is opensource, and if you plan to program your own client flows, it might be a good idea to use our existing code as a starting point. See narakeet/api-client for more information.

API Endpoint

The public REST API endpoint is


To use the API, you will need a Narakeet API key. Send an email to to request your key.

Authenticating requests

You should provide the API key as a header to all requests to the public REST endpoint. Use the x-api-key header for that.

Requests to storage endpoints (for file uploads and downloads and result polling) do not require this header. The storage URLs provided to you by the REST API will already be pre-signed with authentication tokens. Do not include your API key as a separate header when performing those requests.

Running audio projects

Audio projects are significantly faster and simpler than video builds, but they are more limited (a script can be up to 100 KB size, and you cannot include external files). With the audio project type, you do not have to separately upload the script or create project archives.

See the Text to Speech API page for more information.

Running video projects

To create a video, you will need to execute the following steps

  1. create a zip archive containing the video script file and all the related assets
  2. upload the zip to Narakeet, or to your own artifact repository (must be accessible to Narakeet services hosted in AWS)
  3. trigger the build request, which will provide you with a status URL
  4. poll the status URL periodically until the build finishes. this will provide you with a URL of the video file, valid for 24 hours
  5. download the video from the URL, or somehow else consume the result (for example, send the URL to another service).

Step 1: Create a zip archive

Pack your script (.md or .txt) and all the project assets (images, audio files, video clips) into a ZIP archive.

To make things simple, avoid creating directories in the zip, and then the script can just reference assets by file name.

If you want to create a package with directories, the script should reference the assets by relative path from the directory containing the script.

Do not include symbolic links in the zip – include files directly.

To get started quickly, you can download the example project zip. This contains the files from the Hello World project on GitHub.

Step 2: Uploading the achive

There are two options for uploading:

a. upload to Narakeet directly using our API b. upload to some other host, where the zip can be accessible to Narakeet using a public URL

The first option is better for local builds. It has a slightly more complicated workflow, but it does not require you to host the files somewhere separately.

The second option might be better for builds in the cloud, if your software is already preparing the build artifacts in a way that can be easily retrieved from the Internet.

Option 2.a – Upload to Narakeet

To upload a file, you will first need to obtain an upload token using the API, and then send the binary data using the upload token.

Obtaining an upload token

Send a request to

  • use the GET HTTP method
  • include your API key as the x-api-key header
  • do not specify anything in the body

The result will be a JSON object, containing the following keys:

  • repository - the repository key you will need to pass to the build request later
  • repositoryType - the repository type you will need to pass to the build request later
  • url - a pre-signed URL to upload your content
  • contentType - the content type you must use when uploading the content

Below is a CURL example that requests an upload token, and uses jq to extract important result fields.

RESP=$(curl -X GET -H "x-api-key: $APIKEY"

REPOSITORY=$(echo $RESP | jq -r .repository)
REPOSITORY_TYPE=$(echo $RESP | jq -r .repositoryType)
CONTENT_TYPE=$(echo $RESP | jq -r .contentType)
API_POST_URL=$(echo $RESP | jq -r .url)
Uploading the file

Send a request to the URL contained as url in the upload token.

  • use the PUT HTTP method
  • include the value from the contentType field in the upload token as the Content-Type header
  • provide the size of the uploaded file in bytes as the Content-Length header
  • provide the binary content of the file in the request body.
  • do not provide the API key in the headers for this request, as it’s going directly to our storage and not the API.

Below is a CURL command line that uploads the file ($FILE) using environment variables extracted by the previous example. Note that CURL automatically adds the content length header.

curl -T $FILE -H "Content-Type: $CONTENT_TYPE" $API_POST_URL

Option 2.b – Uploading to your own host

Publish your ZIP somewhere accessible using https from the Internet. Narakeet API servers are in the AWS us-east-1 region, so the URL must be accessible from there. For example, you can upload the archive to AWS S3 and create a temporary pre-signed GET URL.

You do not need to obtain an upload token from Narakeet API. Instead, for the following step, you will need to use the following:

  • repositoryType - should be zip-url, all lowercase
  • repository - this will be the publicly accessible URL for your archive

Step 3: Trigger the build request

Once your archive is uploaded (either to Narakeet storage or your own host), trigger the video build.

Sending a request to

  • Use the POST HTTP method
  • Set the Content Type to application/json
  • Provide your API key in the x-api-key header
  • In the request body, provide a utf-8 encoded JSON object with the following properties:
    • repositoryType: the value repositoryType from the upload token, or zip-url for files hosted by you
    • repository: the repository value from the upload token, or the URL for files hosted by you
    • source: path to the main video script inside your ZIP file

The response will be a JSON structure containing the field statusUrl. This is the URL where you can periodically poll for results.

The snippet below will trigger the build using CURL, providing the values extracted by the example in the previous step 1.a, and extract the status URL:

BODY="{"source\": \"$SOURCE\", \"repository\": \"$REPOSITORY\", \"repositoryType\": \"$REPOSITORY_TYPE\"}"

API_RESPONSE=$(curl -d $BODY -H "Content-Type: application/json" -H "x-api-key: $APIKEY"

STATUS_URL=$(echo $API_RESPONSE | jq -r .statusUrl)

Step 4: Poll for results

To get the status of your build job, poll the status URL returned by the previous step periodically. We recommend polling every 5-10 seconds.

  • Use the GET HTTP method
  • Do not provide the API key in the headers. The URL already has all appropriate authorisations

The status URL will contain the build job status as a JSON object, with following properties:

  • finished: boolean value (true/false) signalling if the video build completed. The value true means you should stop polling.
  • percent: numerical value between 0 and 100, signalling the progress of the video build.
  • succeeded: once the task is finished, a boolean value (true/false) signalling if the video was built, or if there was an error. The value true means that you can download the result video.
  • result : if the task succeeded, a string value with a secure URL, valid for 10 minutes, where you can download the video.
  • message: if the task failed, a string value detailing the error

Step 5: Download the video

Once the status URL contains finished value true, and succeeded value true, you will find the URL to the resulting video in the result field. This is a secure, temporary URL that expires quickly, so you should download the video or immediately process it somehow else.

More information