Markdown to Video API

Our Markdown to Video API allows you to automatically generate video from visual and audio assets, and realistic text to speech in 90 languages, with 700 voices. You can batch-produce video files, automate video documentation building into your continuous delivery pipeline, and a lot more.

This page explains how to use our API to create video files.

NOTE: The easiest way to automate the process is to use our command-line utility. This page contains information for people who want to build their own integration.

Getting an API key

To use the API, you will need a Narakeet API key. For information on how to get a key, check out our guide on Managing API Keys.

A simple way to get started is to copy and modify one of the example projects we published to GitHub. Check out the list below for popular languages.

Narakeet Video API Java Example

For a simple example of how to automate video build workflow in Java, check out

Narakeet Video API CSharp Example

For a simple example of how to automate video build workflow in CSharp/.NET Core, check out

Narakeet Video API Python Example

For a simple example of how to automate video build workflows in Python, check out

Narakeet Video API PHP Example

For a simple example of how to automate video build workflows in PHP, check out

Video Build Workflow

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 24 hours, where you can download the video.
  • poster: the poster image for the video
  • message: if the task failed, a string value detailing the error
  • durationInSeconds: id the task succeeded, a numeric value with the duration of the generated video in seconds, rounded up to the nearest second.

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

For general API limitations and pricing, see Automating video production.