# AI Video Detection

> Submit a video URL for AI-generated content detection. Results are delivered asynchronously via webhook.

Submit a video URL for AI-generated content detection. The endpoint is **asynchronous** - it returns `201 Created` immediately, and the detection results are delivered to your webhook URL once processing is complete.

Authentication is required. See [Login](/reference/actions/account/login) for how to obtain a bearer token.

<Tip>
**Try it without writing code** - open the [Video Detection Playground](https://api.copyleaks.com/dashboard/playground/video-detection) to submit a sample video and inspect the webhook response in your browser.
</Tip>

<Note>
  AI Video Detection is a new endpoint and the official Copyleaks SDKs (Python, JavaScript, Java, C#, PHP, Ruby) don't yet expose a wrapper method. The code samples below call the HTTP API directly. SDK support is planned - until then, use the raw HTTP pattern.
</Note>

## Path parameters

<ParamField path="scanId" type="string" required>
  A unique scan id provided by you. We recommend using the same id in your database to represent the scan in the Copyleaks database - this helps debug incidents and avoid duplicate scans for the same file. See [criteria for creating a Scan ID](/concepts/management/choosing-scan-id).

  `>= 3 characters` &nbsp; `<= 36 characters`

  Match pattern: ``[a-z0-9] !@$^&-+%=_(){}<>';:/.",~`|``
</ParamField>

## Headers

```http
Content-Type: application/json
Authorization: Bearer YOUR_LOGIN_TOKEN
```

## Body parameters

<ParamField body="url" type="string" required>
  Publicly accessible URL of the video file to analyze.

  Example: `"https://example.com/my-video.mp4"`
</ParamField>

<ParamField body="headers" type="array">
  Optional custom headers to include when Copyleaks fetches the video from the provided `url`. Each entry is a two-element array: `["Header-Name", "Header-Value"]`.

  Example: `[["X-Custom-Auth", "my-token"]]`
</ParamField>

<ParamField body="verb" type="string">
  Describes the HTTP method that is going to be executed on the specified `url`. Supported values: `GET`, `POST`, `PUT`.
</ParamField>

<ParamField body="filename" type="string" required>
  The name of the video file including its extension.

  **Requirements:**

  - Must include a supported video extension
  - `<= 255 characters`

  **Supported extensions:** `.mp4`, `.avi`, `.mov`, `.mkv`, `.webm`, `.flv`, `.wmv`, `.mpg`, `.m4v`, `.3gp`, `.mxf`

  Example: `"my-video.mp4"`
</ParamField>

<ParamField body="model" type="string" required>
  The AI detection model to use for analysis.

  - AI Video 1 Pro: `"ai-video-1-pro"`

  Example: `"ai-video-1-pro"`
</ParamField>

<ParamField body="webhooks" type="object" required>
  Webhook configuration for receiving the async results.

  <Expandable title="properties">
    <ParamField body="webhooks.url" type="string" required>
      The URL that Copyleaks will POST the detection results to when processing is complete.

      Example: `"https://your-server.com/webhook/receive-results"`
    </ParamField>
    <ParamField body="webhooks.headers" type="array">
      Optional custom headers to include in the webhook request. Each entry is a two-element array: `["Header-Name", "Header-Value"]`.

      Example: `[["Authorization", "Bearer my-webhook-token"]]`
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="sandbox" type="boolean" default="false">
  Use sandbox mode to test your integration with the [Copyleaks API](https://copyleaks.com/api) without consuming any credits. Submit videos for AI detection and receive mock results simulating the API. Intended for development purposes only.
</ParamField>

<ParamField body="developerPayload" type="string">
  An optional string payload that Copyleaks will include in the webhook response, allowing you to correlate the callback with your internal data.

  Example: `"order-id-12345"`
</ParamField>

<Tip>
  For testing, set `"sandbox": true`. Sandbox mode is free and returns mock results.
</Tip>

### Video requirements

**Returned as `400 Bad Request` at submit (synchronous):**

- Missing or invalid `scanId`, `filename`, `url`, `model`, or `webhooks`
- Unsupported file extension
- Filename longer than 255 characters
- Invalid `verb` value

**Delivered to your webhook as an error result (asynchronous, after download):**

- Duration outside 2 seconds-1 hour → `video_too_short` (67) / `video_too_long` (68)
- File larger than 512 MiB → `file_too_large` (6)
- Resolution below 360×360 → `video_resolution_too_low` (65)
- Frame rate below 16 FPS → `fps_too_low` (66)
- Undecodable codec → `unsupported_video_codec` (71)
- Corrupt or truncated file → `video_truncated` (70)
- Generic decode failure → `video_load_failed` (72)

## Webhook payload

When processing completes, Copyleaks sends a `POST` request to your webhook URL with the detection results. See [AI Video Detection Response](/reference/data-types/ai-detector/ai-video-detection-response) for the complete field reference.

<RequestExample>

```bash title="cURL" icon="terminal"
curl --request POST \
  --url https://api.copyleaks.com/v1/ai-video-detector/my-video-scan-1/submit \
  --header 'Authorization: Bearer YOUR_LOGIN_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "url": "https://example.com/my-video.mp4",
    "filename": "my-video.mp4",
    "model": "ai-video-1-pro",
    "sandbox": true,
    "webhooks": {
      "url": "https://your-server.com/webhook/receive-results"
    }
  }'
```

```python title="Python" icon="python"
import requests

url = 'https://api.copyleaks.com/v1/ai-video-detector/my-video-scan-1/submit'
headers = {
    'Authorization': 'Bearer YOUR_LOGIN_TOKEN',
    'Content-Type': 'application/json'
}

payload = {
    'url': 'https://example.com/my-video.mp4',
    'filename': 'my-video.mp4',
    'model': 'ai-video-1-pro',
    'sandbox': True,
    'webhooks': {
        'url': 'https://your-server.com/webhook/receive-results'
    }
}

response = requests.post(url, json=payload, headers=headers)
print(f"Submission status: {response.status_code}")  # 201 Created
```

```javascript title="JavaScript" icon="square-js"
const response = await fetch(
  'https://api.copyleaks.com/v1/ai-video-detector/my-video-scan-1/submit',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_LOGIN_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      url: 'https://example.com/my-video.mp4',
      filename: 'my-video.mp4',
      model: 'ai-video-1-pro',
      sandbox: true,
      webhooks: {
        url: 'https://your-server.com/webhook/receive-results'
      }
    })
  }
);

console.log('Submission status:', response.status); // 201 Created
```

```http title="HTTP" icon="globe"
POST https://api.copyleaks.com/v1/ai-video-detector/my-video-scan-1/submit
Content-Type: application/json
Authorization: Bearer YOUR_LOGIN_TOKEN

{
  "url": "https://example.com/my-video.mp4",
  "filename": "my-video.mp4",
  "model": "ai-video-1-pro",
  "sandbox": true,
  "webhooks": {
    "url": "https://your-server.com/webhook/receive-results"
  }
}
```

</RequestExample>

<ResponseExample>

```json 201 Created
{}
```

```json 400 Bad Request
{
  "error": "Invalid request parameters."
}
```

```json 401 Unauthorized
{
  "error": "Authentication or authorization failed."
}
```

```json 402 Payment Required
{
  "error": "Insufficient credits."
}
```

```json 429 Too Many Requests
{
  "error": "Rate limit exceeded."
}
```

```json 500 Internal Server Error
{
  "error": "The server encountered an internal error."
}
```

</ResponseExample>

## Example webhook delivery

```json
{
  "model": "ai-video-1-pro",
  "audioResult": {
    "starts": [13000, 45000, 47000],
    "lengths": [14000, 1000, 8700],
    "exclude": {
      "starts": [0, 3250, 5400, 7600, 10500],
      "lengths": [2950, 1500, 1200, 650, 1050]
    }
  },
  "visualResult": {
    "starts": [11566, 29433],
    "lengths": [6134, 26267],
    "exclude": {
      "starts": [],
      "lengths": []
    }
  },
  "summary": {
    "audioAIRatio": 0.4902,
    "visualAIRatio": 0.5817,
    "overallAIRatio": 0.7487
  },
  "videoInfo": {
    "metadata": {
      "issuedTime": "2026-03-17T13:14:57+00:00",
      "issuedBy": "OpenAI",
      "appOrDeviceUsed": "Sora",
      "contentSummary": "Created using generative AI"
    },
    "duration": 55.7
  },
  "scannedVideo": {
    "scanId": "my-video-scan-1",
    "actualCredits": 1,
    "expectedCredits": 1,
    "creationTime": "2026-05-05T12:37:50Z"
  }
}
```
