Create and manage captions

You can create and manage captions in multiple languages for your videos and live streams. You may have one caption file per language. All caption files are VTT files with proper formatting that you can add using the dashboard or programmatically.

Choose an api.video client

The clients offered by api.video include:

Installation

To install your selected client, do the following:

go get github.com/apivideo/api.video-go-client
composer require api-video/php-api-client
npm install @api.video/nodejs-client --save

...or with yarn: 
  
yarn add @api.video/nodejs-client
pip install api.video
Using Nuget
  
Install-Package ApiVideo

Retrieve your API key

You'll need your API key to get started. You can sign up for one here: Get your api.video API key!. Then do the following:

  1. Log in to the api.video dashboard.
  2. From the list of choices on the left, make sure you are on API Keys
  3. You will always be able to choose to use your Sandbox API key. If you want to use the Production API key instead, enter your credit card information.
  4. Grab the key you want, and you're ready to get started!

Create a VTT file

You must have a VTT file available for upload. You can create your own if you like, or you can get help from a captioning service. We have several tutorials that can guide you through this process:

📘

NOTE:

You can't live caption with api.video directly. You'll have to check out the WebSpeech API tutorial listed above to learn more about adding captions to your live streams. The rest of this tutorial will focus on adding captions to videos and completed recordings of live streams.

When you have your .VTT file, you're ready to continue!

Upload a caption

You need the unique video ID you want to upload to upload a caption. Include that in the URL, and then place the path to your file in the body. You should also include the language in BCP 47 format. This is placed in the URL and tells the API video what language you want the file to be included. If you already have a file added for that language, the upload replaces the file with the new one.

curl --request POST \
     --url https://ws.api.video/videos/vi4KskJ1PHvO2WB2d0gscmmS/captions/en \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI4MTQxNDUuMjE2Mzc2LCJuYmYiOjE2NDI4MTQxNDUuMjE2Mzc2LCJleHAiOjE2NDI4MTc3NDUuMjE2Mzc2LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.GSDqqMzBxo-wOwl9IVbOnzevm8A6LSyaR5kxCWUdkEneSU0kIdoNfhwmXZBq5QWpVa-0GIT8JR59W6npNO-ayhaXmV3LA6EQpvv0mHd_dAhg3N8T96eC0ps0YIrkmw0_Oe6iRgEDI-wJ9nc6tQWi9ybbMHi1LDBjxW4rbFlq7G59C1QZGabd14QO7uqAUUSNqHC1l42z_m7BTK1AhFiBEXmMcfW7X0VmGcaEUy7NiNda8rmq_nrdvkxgN8KHguXzxMsw_4GE_d0eQwHcZvS1q-FebI6b8AoqpoltFOZvUACCrfXH_D_UPshHuJM3apXbD2dg_zQicc8oWBHVGiobLQ' \
     --header 'Content-Type: multipart/form-data' \
     --form [email protected]
package main

import (
    "context"
    "fmt"
    "os"
    apivideosdk "github.com/apivideo/api.video-go-client"
)

func main() {
    client := apivideosdk.ClientBuilder("YOUR_API_TOKEN").Build()
    // if you rather like to use the sandbox environment:
    // client := apivideosdk.SandboxClientBuilder("YOU_SANDBOX_API_TOKEN").Build()
        
    videoId := "vi4k0jvEUuaTdRAEjQ4Prklg" // string | The unique identifier for the video you want to add a caption to.
    language := "en" // string | A valid BCP 47 language representation.
    file := os.NewFile(1234, "some_file") // *os.File | The video text track (VTT) you want to upload.

    
    res, err := client.Captions.UploadFile(videoId, language, file)

    // you can also use a Reader instead of a File:
    // client.Captions.Upload(videoId, language, fileName, fileReader)

    if err != nil {
        fmt.Fprintf(os.Stderr, "Error when calling `Captions.Upload``: %v\n", err)
    }
    // response from `Upload`: Caption
    fmt.Fprintf(os.Stdout, "Response from `Captions.Upload`: %v\n", res)
}
<?php
require __DIR__ .'/vendor/autoload.php';

use Symfony\Component\HttpClient\Psr18Client;
use ApiVideo\Client\Client;
use ApiVideo\Client\Model\CaptionsApi;

$apiKey = 'your API key';
$apiVideoEndpoint = 'https://ws.api.video';

$httpClient = new \Symfony\Component\HttpClient\Psr18Client();
$client = new ApiVideo\Client\Client(
    $apiVideoEndpoint,
    $apiKey,
    $httpClient
);

$captions = $client->captions()->upload('video ID here', 'en', new \SplFileObject('Caption_File.vtt'));
print($captions);
const ApiVideoClient = require('@api.video/nodejs-client');

(async () => {
    try {
        const client = new ApiVideoClient({ apiKey: "YOUR_API_TOKEN" });

        const videoId = 'vi4k0jvEUuaTdRAEjQ4Prklg'; // The unique identifier for the video you want to add a caption to.
        const language = 'en'; // A valid BCP 47 language representation.
        const file = 'BINARY_DATA_HERE'; // The video text track (VTT) you want to upload.

        // Caption
        const result = await client.captions.upload(videoId, language, file);
        console.log(result);
    } catch (e) {
        console.error(e);
    }
})();
# Add a caption VTT file to your video. The file should be in the same folder as your code.
import apivideo
from apivideo.apis import CaptionsApi
from apivideo.exceptions import ApiAuthException

api_key = "your api key here"
video_id = "video ID for the video you want to add a caption to"

client = apivideo.AuthenticatedApiClient(api_key)

# If you'd rather use the sandbox environment:
# client = apivideo.AuthenticatedApiClient(api_key, production=False)

client.connect()

captions_api = CaptionsApi(client)

# Set up payload to send 
language = "en-GB"
file = open("doug_en-GB.vtt", "rb")

response = captions_api.upload(video_id, language, file)
print(response)

Upload a caption using the dashboard

To upload caption files for a video using the dashboard, do the following:

  1. Log in to your api.video dashboard.

  2. From the menu on the left, click Videos.

  3. Click on the video you want to work on. A pop-up with a few details about the video appears.

  4. From the upper right part of the pop-up, click See details. The full details for the video appear.

  5. At the top of the screen, click the Captions tab. You'll see all available captions information for your video.

  6. Click Upload a caption file to open the Upload a new caption pop up.

  7. Click Choose file to open the VTT caption file you want to upload. Browse and select the file.

  8. Using the drop-down on the Upload a new caption pop up. Choose the language you want the caption.

  9. Click Upload. Your caption file is now associated with your video.

List captions for a video

If you need to see what languages you've included captions for, you can list all captions to see what you have. You can only ever have one caption file per language.

curl --request GET \
     --url 'https://ws.api.video/videos/vi4KskJ1PHvO2WB2d0gscmmS/captions?currentPage=1&pageSize=25' \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI4MTQxNDUuMjE2Mzc2LCJuYmYiOjE2NDI4MTQxNDUuMjE2Mzc2LCJleHAiOjE2NDI4MTc3NDUuMjE2Mzc2LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.GSDqqMzBxo-wOwl9IVbOnzevm8A6LSyaR5kxCWUdkEneSU0kIdoNfhwmXZBq5QWpVa-0GIT8JR59W6npNO-ayhaXmV3LA6EQpvv0mHd_dAhg3N8T96eC0ps0YIrkmw0_Oe6iRgEDI-wJ9nc6tQWi9ybbMHi1LDBjxW4rbFlq7G59C1QZGabd14QO7uqAUUSNqHC1l42z_m7BTK1AhFiBEXmMcfW7X0VmGcaEUy7NiNda8rmq_nrdvkxgN8KHguXzxMsw_4GE_d0eQwHcZvS1q-FebI6b8AoqpoltFOZvUACCrfXH_D_UPshHuJM3apXbD2dg_zQicc8oWBHVGiobLQ'
package main

import (
    "context"
    "fmt"
    "os"
    apivideosdk "github.com/apivideo/api.video-go-client"
)

func main() {
    client := apivideosdk.ClientBuilder("YOUR_API_TOKEN").Build()
    // if you rather like to use the sandbox environment:
    // client := apivideosdk.SandboxClientBuilder("YOU_SANDBOX_API_TOKEN").Build()
    req := apivideosdk.CaptionsApiListRequest{}
    
    req.VideoId("vi4k0jvEUuaTdRAEjQ4Prklg") // string | The unique identifier for the video you want to retrieve a list of captions for.
    req.CurrentPage(int32(2)) // int32 | Choose the number of search results to return per page. Minimum value: 1 (default to 1)
    req.PageSize(int32(30)) // int32 | Results per page. Allowed values 1-100, default is 25. (default to 25)

    res, err := client.Captions.List(videoId string, req)
    

    if err != nil {
        fmt.Fprintf(os.Stderr, "Error when calling `Captions.List``: %v\n", err)
    }
    // response from `List`: CaptionsListResponse
    fmt.Fprintf(os.Stdout, "Response from `Captions.List`: %v\n", res)
}
<?php
require __DIR__ .'/vendor/autoload.php';

use Symfony\Component\HttpClient\Psr18Client;
use ApiVideo\Client\Client;
use ApiVideo\Client\Model\CaptionsApi;

$apiKey = 'your API key here';
$apiVideoEndpoint = 'https://ws.api.video';

$httpClient = new \Symfony\Component\HttpClient\Psr18Client();
$client = new ApiVideo\Client\Client(
    $apiVideoEndpoint,
    $apiKey,
    $httpClient
);

$captions = $client->captions()->list('video ID here');
print($captions);
const ApiVideoClient = require('@api.video/nodejs-client');

(async () => {
    try {
        const client = new ApiVideoClient({ apiKey: "YOUR_API_TOKEN" });

        const videoId = 'vi4k0jvEUuaTdRAEjQ4Prklg'; // The unique identifier for the video you want to retrieve a list of captions for.
        const currentPage = '2'; // Choose the number of search results to return per page. Minimum value: 1
        const pageSize = '30'; // Results per page. Allowed values 1-100, default is 25.

        // CaptionsListResponse
        const result = await client.captions.list({ videoId, currentPage, pageSize })
        console.log(result);
    } catch (e) {
        console.error(e);
    }
})();
# List all available captions for a video ID
import apivideo
from apivideo.apis import CaptionsApi
from apivideo.exceptions import ApiAuthException

api_key = "your api key here"
video_id = "your video ID here" 

client = apivideo.AuthenticatedApiClient(api_key)

# If you'd rather use the sandbox environment:
# client = apivideo.AuthenticatedApiClient(api_key, production=False)
client.connect()

captions_api = CaptionsApi(client)

# List all captions for the video ID
response = captions_api.list(video_id)
print(response)

List captions for a video in the dashboard

To see a list of captions for a specific video in the dashboard, do the following:

  1. Log in to your api.video dashboard.

  2. From the menu on the left, click Videos.

  3. Click on the video you want to work with. A pop-up with a few details about the video appears.

  4. From the upper right part of the pop-up, click See details. The full details for the video appear.

  5. At the top of the screen, click the Captions tab. You'll see all available captions information for your video.

Update a caption

When you update a caption, it means to change its setting as the default caption. Send a valid BCP 47 representation of the language associated with your caption. You can set the default parameter to true or false. If the default parameter is true, it means the caption will play as the default language when someone looks at your video. If you set the default parameter to false, the caption is still available, but the viewer must choose it from the caption options.

curl --request PATCH \
     --url https://ws.api.video/videos/vi4KskJ1PHvO2WB2d0gscmmS/captions/en \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI4MjQzMTkuMDk2NjY1LCJuYmYiOjE2NDI4MjQzMTkuMDk2NjY1LCJleHAiOjE2NDI4Mjc5MTkuMDk2NjY1LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.rfchf3btbMTzSukcwhUS0u4fNY4Q3g1JpoMeIz_Dls1ADmqDdKw7yBOE893C7cagb0lpuvUJvhuhgusLStsJ4nqzTveDeM2oPBQBNJjzwaJZNrImTPD4mif7Tzgxvn1_jQJA5L4gQhjd7frCIJW1yAwywrtiDPbxiWNp8fVl7r_QILjZZfslxy-kblPrHJ20Zix9VURqkGIORY5G_457nHSV9Atks1sUlt49E8b_g3jORja3MnznXBS0-0dksz2K62-QMe1_dk78V9JwbLeydqcr15M1jDLA3H6qFGI7GTsTDdZ5jKLhg5OR6yeSHFysqr3kOteTqAGdp3JuTrpZIA' \
     --header 'Content-Type: application/json' \
     --data '{"default":true}'
package main

import (
    "context"
    "fmt"
    "os"
    apivideosdk "github.com/apivideo/api.video-go-client"
)

func main() {
    client := apivideosdk.ClientBuilder("YOUR_API_TOKEN").Build()
    // if you rather like to use the sandbox environment:
    // client := apivideosdk.SandboxClientBuilder("YOU_SANDBOX_API_TOKEN").Build()
        
    videoId := "vi4k0jvEUuaTdRAEjQ4Prklg" // string | The unique identifier for the video you want to have automatic captions for.
    language := "en" // string | A valid [BCP 47](https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers) language representation.
    captionsUpdatePayload := *apivideosdk.NewCaptionsUpdatePayload() // CaptionsUpdatePayload | 

    
    res, err := client.Captions.Update(videoId, language, captionsUpdatePayload)

    if err != nil {
        fmt.Fprintf(os.Stderr, "Error when calling `Captions.Update``: %v\n", err)
    }
    // response from `Update`: Caption
    fmt.Fprintf(os.Stdout, "Response from `Captions.Update`: %v\n", res)
}
const ApiVideoClient = require('@api.video/nodejs-client');

(async () => {
    try {
        const client = new ApiVideoClient({ apiKey: "YOUR_API_TOKEN" });

        const videoId = 'vi4k0jvEUuaTdRAEjQ4Prklg'; // The unique identifier for the video you want to have automatic captions for.
        const language = 'en'; // A valid [BCP 47](https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers) language representation.
        const captionsUpdatePayload = {
            _default: true,
        }; 

        // Caption
        const result = await client.captions.update(videoId, language, captionsUpdatePayload);
        console.log(result);
    } catch (e) {
        console.error(e);
    }
})();
# You can set whether captions are automatically turned on or not and for what
# language they are turned on or not. 
import apivideo
from apivideo.apis import CaptionsApi
from apivideo.exceptions import ApiAuthException

api_key = "your api key here"
video_id = "your video ID here"

client = apivideo.AuthenticatedApiClient(api_key)

# If you'd rather use the sandbox environment:
# client = apivideo.AuthenticatedApiClient(api_key, production=False)
client.connect()

captions_api = CaptionsApi(client)

# Set up payload to send 
language = "en-GB"
captions_update_payload = {"default": True}

response = captions_api.update(video_id, language, captions_update_payload)
print(response)

Update a caption using the dashboard

To update a caption from the dashboard, do the following:

  1. Log in to your api.video dashboard.

  2. From the menu on the left, click Videos.

  3. Click on the video you want to work with. A pop-up with a few details about the video appears.

  4. From the upper right part of the pop-up, click See details. The full details for the video appear.

  5. At the top of the screen, click the Captions tab. You'll see all available captions information for your video.

  6. Click Set default next to a caption to change whether it will be the default caption for the video or not. Clicking this button overrides whatever the other default was.

Show a caption

You can list details for a single caption by sending a request that includes the video ID for which you want to retrieve a caption and the BCP 47 language tag associated with the caption. The response will show you the language tag, whether the caption is the default choice, and provide a link to the source file.

curl --request GET \
     --url https://ws.api.video/videos/vi4KskJ1PHvO2WB2d0gscmmS/captions/en \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI4MjQzMTkuMDk2NjY1LCJuYmYiOjE2NDI4MjQzMTkuMDk2NjY1LCJleHAiOjE2NDI4Mjc5MTkuMDk2NjY1LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.rfchf3btbMTzSukcwhUS0u4fNY4Q3g1JpoMeIz_Dls1ADmqDdKw7yBOE893C7cagb0lpuvUJvhuhgusLStsJ4nqzTveDeM2oPBQBNJjzwaJZNrImTPD4mif7Tzgxvn1_jQJA5L4gQhjd7frCIJW1yAwywrtiDPbxiWNp8fVl7r_QILjZZfslxy-kblPrHJ20Zix9VURqkGIORY5G_457nHSV9Atks1sUlt49E8b_g3jORja3MnznXBS0-0dksz2K62-QMe1_dk78V9JwbLeydqcr15M1jDLA3H6qFGI7GTsTDdZ5jKLhg5OR6yeSHFysqr3kOteTqAGdp3JuTrpZIA'
package main

import (
    "context"
    "fmt"
    "os"
    apivideosdk "github.com/apivideo/api.video-go-client"
)

func main() {
    client := apivideosdk.ClientBuilder("YOUR_API_TOKEN").Build()
    // if you rather like to use the sandbox environment:
    // client := apivideosdk.SandboxClientBuilder("YOU_SANDBOX_API_TOKEN").Build()
        
    videoId := "vi4k0jvEUuaTdRAEjQ4Prklg" // string | The unique identifier for the video you want captions for.
    language := "en" // string | A valid [BCP 47](https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers) language representation

    
    res, err := client.Captions.Get(videoId, language)

    if err != nil {
        fmt.Fprintf(os.Stderr, "Error when calling `Captions.Get``: %v\n", err)
    }
    // response from `Get`: Caption
    fmt.Fprintf(os.Stdout, "Response from `Captions.Get`: %v\n", res)
}
const ApiVideoClient = require('@api.video/nodejs-client');

(async () => {
    try {
        const client = new ApiVideoClient({ apiKey: "YOUR_API_TOKEN" });

        const videoId = 'vi4k0jvEUuaTdRAEjQ4Prklg'; // The unique identifier for the video you want captions for.
        const language = 'en'; // A valid [BCP 47](https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers) language representation

        // Caption
        const result = await client.captions.get(videoId, language);
        console.log(result);
    } catch (e) {
        console.error(e);
    }
})();
# You can retrieve details about captions available for an ID.
import apivideo
from apivideo.apis import CaptionsApi
from apivideo.exceptions import ApiAuthException

api_key = "your api key here"
video_id = "your video ID here" 

client = apivideo.AuthenticatedApiClient(api_key)

# If you'd rather use the sandbox environment:
# client = apivideo.AuthenticatedApiClient(api_key, production=False)
client.connect()

captions_api = CaptionsApi(client)

# Set up language you want to see captions for
language = "en-GB"

response = captions_api.get(video_id, language)
print(response)

Show a caption in the dashboard

To show a specific caption in the dashboard, you complete the same steps as for listing captions. You can filter for the particular caption you want if you don't see it immediately.

Delete a caption

If you want to replace a caption altogether, you must delete it before uploading a new caption to the same language tag.

curl --request DELETE \
     --url https://ws.api.video/videos/vi4KskJ1PHvO2WB2d0gscmmS/captions/en \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI4MjQzMTkuMDk2NjY1LCJuYmYiOjE2NDI4MjQzMTkuMDk2NjY1LCJleHAiOjE2NDI4Mjc5MTkuMDk2NjY1LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.rfchf3btbMTzSukcwhUS0u4fNY4Q3g1JpoMeIz_Dls1ADmqDdKw7yBOE893C7cagb0lpuvUJvhuhgusLStsJ4nqzTveDeM2oPBQBNJjzwaJZNrImTPD4mif7Tzgxvn1_jQJA5L4gQhjd7frCIJW1yAwywrtiDPbxiWNp8fVl7r_QILjZZfslxy-kblPrHJ20Zix9VURqkGIORY5G_457nHSV9Atks1sUlt49E8b_g3jORja3MnznXBS0-0dksz2K62-QMe1_dk78V9JwbLeydqcr15M1jDLA3H6qFGI7GTsTDdZ5jKLhg5OR6yeSHFysqr3kOteTqAGdp3JuTrpZIA'
package main

import (
    "context"
    "fmt"
    "os"
    apivideosdk "github.com/apivideo/api.video-go-client"
)

func main() {
    client := apivideosdk.ClientBuilder("YOUR_API_TOKEN").Build()
    // if you rather like to use the sandbox environment:
    // client := apivideosdk.SandboxClientBuilder("YOU_SANDBOX_API_TOKEN").Build()
        
    videoId := "vi4k0jvEUuaTdRAEjQ4Prklgc" // string | The unique identifier for the video you want to delete a caption from.
    language := "en" // string | A valid [BCP 47](https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers) language representation.

    
    err := client.Captions.Delete(videoId, language)

    if err != nil {
        fmt.Fprintf(os.Stderr, "Error when calling `Captions.Delete``: %v\n", err)
    }
}
const ApiVideoClient = require('@api.video/nodejs-client');

(async () => {
    try {
        const client = new ApiVideoClient({ apiKey: "YOUR_API_TOKEN" });

        const videoId = 'vi4k0jvEUuaTdRAEjQ4Prklgc'; // The unique identifier for the video you want to delete a caption from.
        const language = 'en'; // A valid [BCP 47](https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers) language representation.

        // void
        const result = await client.captions.delete(videoId, language);
        console.log(result);
    } catch (e) {
        console.error(e);
    }
})();
# Delete a caption in a specified language.
import apivideo
from apivideo.apis import CaptionsApi
from apivideo.exceptions import ApiAuthException

api_key = "your api key here"
video_id = "your video ID here" 

client = apivideo.AuthenticatedApiClient(api_key)

# If you'd rather use the sandbox environment:
# client = apivideo.AuthenticatedApiClient(api_key, production=False)
client.connect()

captions_api = CaptionsApi(client)

language = "en-GB"

# List all captions for the video ID
response = captions_api.delete(video_id, language)
print(response)

Delete a caption from the dashboard

To delete a caption from the dashboard:

  1. Log in to your api.video dashboard.

  2. From the menu on the left, click Videos.

  3. Click on the video you want to work with. A pop-up with a few details about the video appears.

  4. From the upper right part of the pop-up, click See details. The full details for the video appear.

  5. At the top of the screen, click the Captions tab. You'll see all available captions information for your video.