# Strapi v5 – api.video plugin

<p align="center">
  <a href="https://www.npmjs.com/package/@strawbinary-io/api-video-strapi-5-plugin">
    <img src="https://img.shields.io/npm/v/%40strawbinary-io%2Fapi-video-strapi-5-plugin" alt="NPM Version" />
  </a>
</p>

A powerful Strapi plugin to easily manage your videos and integrate them in your project.

**Core Contributor**: [Strawbinary](https://github.com/Strawbinary)  
**Follow** [@strawbinary](https://www.linkedin.com/company/strawbinary-gbr/)

**About this Plugin:**
This plugin is a fork of [Strapi v4 - api.video uploader](https://github.com/apivideo/api.video-strapi-plugin/tree/main),
originally developed by the api.video team under the MIT license.

This version updates the plugin for Strapi 5 and introduces several improvements.

---

![Plugin UI Preview](public/assets/preview_dark.png)

## ✨ Features

- **Upload videos** directly from your Strapi admin via file picker to [api.video](https://api.video)
- **Manage assets** with a responsive grid and built-in pagination
- **Search** your library by title or tags
- **Preview** with the embedded api.video player ([api.video-player-react](https://github.com/apivideo/api.video-react-player))
- **Delete** assets (removes on both Strapi and api.video sides)

## ⏳ Installation

This plugin is published on npm. You can install it with your preferred package manager—npm, yarn, or pnpm.

```bash
# Using npm (recommended)
npm install @strawbinary-io/api-video-strapi-5-plugin@latest

# Or with yarn
yarn add @strawbinary-io/api-video-strapi-5-plugin@latest

# Or with pnpm
pnpm add @strawbinary-io/api-video-strapi-5-plugin@latest
```

After installation, rebuild your Strapi admin:

```bash
npm run build
npm run develop
```

Once Strapi is up, the **API.VIDEO** plugin will in the sidebar.

## 🖐 Requirements

- **api.video**
  - An [api.video](https://api.video) account
  - An API key from the [api.video Dashboard](https://dashboard.api.video/apikeys)
- **Node.js**
  - Version: 20.x – 24.x
- **Strapi**
  - Strapi v5 only (not compatible with v4 or earlier)

## 🔧 Configuration

Before using the plugin, you must supply your api.video API key in Strapi’s settings panel.

1. In Strapi Admin, go to **Settings** → **API.VIDEO Plugin**.
2. Enter your API key and click **Save**.

### Daily sync cron

The plugin registers a daily cron job that imports api.video assets missing in Strapi.
It runs at `03:00` server time by default.

To override the schedule or disable the job, configure the plugin in your app’s `config/plugins.ts`:

```ts
export default {
  'api-video-strapi-5-plugin': {
    enabled: true,
    config: {
      cron: {
        enabled: true,
        rule: '0 3 * * *',
      },
    },
  },
};
```

Strapi cron jobs must also be enabled globally in your app’s `config/server.ts` file.

### Content Security Policy

To allow thumbnails, embeds and the player to load correctly, update your `config/middlewares.ts` file with the following security entry:

```ts
export default [
  'strapi::logger',
  'strapi::errors',
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': ["'self'", 'data:', 'blob:', 'embed.api.video', 'cdn.api.video/vod/'],
          'script-src': ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
          'frame-src': ["'self'", 'data:', 'blob:', 'embed.api.video'],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
];
```

## 👤 Permissions

Configure fine-grained permissions under **Roles & Permissions** → **Plugins**.

## 💾 Metadata

By default, uploads carry an `uploadSource` metadata field set to `"Strapi"`. This cannot be changed.

## 🔔 Webhook

The plugin exposes a webhook endpoint to update the video `duration` once encoding finishes.

1. In the api.video Dashboard, create a webhook for the event `video.encoding.quality.completed`.
2. Set the webhook URL to your Strapi instance (default Content API prefix):
   `POST https://<your-strapi-host>/api/api-video-strapi-5-plugin/api-video-asset/webhook`

When the webhook is received and verified, the plugin fetches the video status from api.video and updates the
`duration` field for the matching asset in Strapi.

## 🧭 Migrations

This plugin runs **one-time migrations** during Strapi bootstrap. The migration state is stored
in the Strapi plugin store so each migration runs only once per environment.

- **Storage key:** `migrations` (plugin store for `api-video-strapi-5-plugin`)
- **State format:** A map of migration IDs with timestamps and result metadata
- **Re-run a migration:** Delete the entry from the plugin store (or remove the whole `migrations` key)

### Current migrations

- **2026-01-29-backfill-duration-from-status**  
  Backfills the `duration` field for existing videos by calling `client.videos.getStatus(videoId)` and
  reading `metadata.duration` from the status response.

## 🤝 Contributing

We welcome contributions, issues and feature requests!

- Report bugs or request features in the [issue tracker](https://github.com/Strawbinary/api.video-strapi-5-plugin/issues)

## 📚 References

- [api.video Documentation](https://docs.api.video/docs/apivideo-api-reference)
- [Strapi Documentation](https://docs.strapi.io)
