> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.synthesia.io/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.synthesia.io/docs/_mcp/server.

# List videos

GET https://api.synthesia.io/v2/videos

You can use the List videos endpoint to get an overview of all videos created via the API or STUDIO.

Reference: https://developers.synthesia.io/docs/video-api-reference/videos/list-videos

## Authentication

- `Authorization` header (required) — API Key authentication via header

## Request

### Query parameters

- `limit` (integer, optional, default: 20) — This parameter lets you specify the amount of videos to return in your API call. The maximum amount of videos you can have returned to you via this parameter is 100.
- `offset` (integer, optional, default: 0) — Used to page through the videos. Every call to this endpoint will return the next offset value. This value is used in the offset parameter of the next call to get the next page of videos.
- `source` (list of enum, optional, default: ["workspace","shared_with_me","my_videos"]) — Filter videos by source. Possible values: `workspace`, `shared_with_me`, `my_videos`
  - Allowed values: `workspace`, `shared_with_me`, `my_videos`

## Response

### 200

OK.

- `videos` (list of VideoResponse, optional)
- `nextOffset` (integer, optional)

## Errors

### 400 Bad Request Error

Bad Request.

- `error` (string, required)
- `context` (string, optional)

### 403 Forbidden Error

Forbidden - Wrong API key.

- `error` (string, required)
- `context` (string, optional)

## Types

### VideoResponse

- `callbackId` (string, optional) — Use callback ID to link videos back to the initial request. For example, if you are making a personalized video for a customer, you could enter the customer's email as a callback ID. This way, you can tell who the video is for, once its generated..
- `createdAt` (integer, optional) — UNIX timestamp representing the time video was created.
- `ctaSettings` (CtaSettings, optional) — Settings for a call-to-action button.
- `description` (string, optional, default: ) — Description of the video to be shown on the share page.
- `test` (boolean, optional, default: false) — Test videos are free and not counted towards your quota. If you create a video in the “test” mode, we will overlay a watermark over your video.
- `download` (string, optional) — Withheld for rejected videos and videos held for moderation review.
- `duration` (string, optional)
- `id` (string, optional)
- `lastUpdatedAt` (integer, optional)
- `status` (enum, optional) — Video status. A rendered video that is still awaiting moderation review is reported as `in_progress` until the review is final.
  - Allowed values: `complete`, `deleted`, `error`, `in_progress`, `rejected`, `approved`
- `thumbnail` (VideoThumbnailTypesResponse, optional, nullable)
- `title` (string, optional, default: ) — Title of the video to be shown on the share page.
- `visibility` (enum, optional, default: private) — Public videos will be visible to anyone with a share URL. Private videos can only be downloaded via a time-limited download link. See Retrieve a video for details. Visibility can be changed also once the video is created via Update a video.
  - Allowed values: `private`, `public`
- `captions` (VideoAssetCaptionTypesResponse, optional) — Downloadable captions files. Omitted when no captions are available, and for videos that are rejected or held for moderation review.
- `contentProvenance` (ContentProvenanceResponse, optional, nullable) — Content provenance (C2PA) information for the video. Only present when the video has been signed.

### CtaSettings

- `label` (string, required) — Label for a call-to-action button.
- `url` (string, required) — URL to navigate to, when the call-to-action button is clicked.

### VideoThumbnailTypesResponse

- `image` (string, optional, nullable)
- `gif` (string, optional, nullable)

### VideoAssetCaptionTypesResponse

- `srt` (string, optional, nullable)
- `vtt` (string, optional, nullable)

### ContentProvenanceResponse

- `c2pa` (C2PAContentProvenanceResponse, optional, nullable)

### C2PAContentProvenanceResponse

- `signedAt` (string, required)
- `claimGenerator` (string, required)

## Examples

**Response**

```json
{
  "videos": [
    {
      "callbackId": "string",
      "createdAt": 1,
      "ctaSettings": {
        "label": [
          "Learn More",
          "Sign up"
        ],
        "url": [
          "https://example.com",
          "https://signup.example.com"
        ]
      },
      "description": "",
      "test": false,
      "download": "string",
      "duration": "string",
      "id": "string",
      "lastUpdatedAt": 1,
      "status": "complete",
      "thumbnail": {
        "image": "string",
        "gif": "string"
      },
      "title": "",
      "visibility": "private",
      "captions": {
        "srt": "string",
        "vtt": "string"
      },
      "contentProvenance": {
        "c2pa": {
          "signedAt": "string",
          "claimGenerator": "string"
        }
      }
    }
  ],
  "nextOffset": 1
}
```

**SDK Code**

```python
import requests

url = "https://api.synthesia.io/v2/videos"

headers = {"Authorization": "<apiKey>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.synthesia.io/v2/videos';
const options = {method: 'GET', headers: {Authorization: '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.synthesia.io/v2/videos"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.synthesia.io/v2/videos")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = '<apiKey>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.synthesia.io/v2/videos")
  .header("Authorization", "<apiKey>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.synthesia.io/v2/videos', [
  'headers' => [
    'Authorization' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.synthesia.io/v2/videos");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Authorization": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.synthesia.io/v2/videos")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```