> ## Documentation Index
> Fetch the complete documentation index at: https://api-tools.memories.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Configure webhook endpoints to receive async task results

## Overview

Many MAVI API endpoints process tasks asynchronously. When you call an async endpoint, it immediately returns a `task_id`. Once processing completes, the API sends the results to your configured webhook URL via an HTTP POST request.

<Warning>
  You **must** configure a webhook endpoint before using any async API. Without a webhook, you will not receive processing results.
</Warning>

## Setup

### Step 1: Open the Webhooks Settings

Go to the [Webhooks Settings](https://api-platform.memories.ai/webhooks) page in the MAVI Console.

### Step 2: Add Your Webhook URL

Enter your callback URL. It must be:

* A publicly accessible HTTPS endpoint
* Able to accept POST requests with JSON body
* Returns a `2xx` status code on success

### Step 3: Save

After saving, all async task results will be automatically delivered to your configured URL.

<Note>
  Webhook configuration is a **one-time setup**. Once configured, all async tasks across all API endpoints will send results to the same URL.
</Note>

## Async Endpoints That Require Webhooks

The following endpoints are asynchronous — they return a `task_id` on call and deliver results via webhook callback:

| Endpoint                                            | Description                        |
| --------------------------------------------------- | ---------------------------------- |
| `POST /video/extract-frames`                        | Extract frames from a video        |
| `POST /video/clip`                                  | Detect scene boundaries in a video |
| `POST /video/split`                                 | Split a video into segments        |
| `POST /video/edit`                                  | AI-powered video editing           |
| `POST /transcriptions/async-generate-audio`         | Async audio transcription          |
| `POST /transcriptions/async-generate-video`         | Async video description            |
| `POST /transcriptions/async-generate-speaker`       | Async speaker diarization          |
| `POST /transcriptions/async-generate-multi-speaker` | Multimodal speaker recognition     |
| `POST /transcriptions/async-summary`                | Async summary generation           |

## How Async Tasks Work

```
Step 1: Configure webhook (one-time setup)
         → https://api-platform.memories.ai/webhooks

Step 2: Call an async endpoint
         → Returns { "data": { "task_id": "abc123" } }

Step 3: Wait for webhook callback
         → MAVI POSTs results to your webhook URL

Step 4: Match task_id to correlate request and response
         → callback body contains the same task_id
```

### Example Flow

**1. Call an async endpoint:**

```bash theme={null}
curl --request POST \
  --url https://mavi-backend.memories.ai/serve/api/v2/video/extract-frames \
  --header 'Authorization: sk-mavi-...' \
  --header 'Content-Type: application/json' \
  --data '{ "asset_id": "re_657739295220518912" }'
```

**2. Receive immediate response with task\_id:**

```json theme={null}
{
  "code": 200,
  "msg": "success",
  "data": {
    "task_id": "1e8ae1075e054e8abb58e7598c53cbf1"
  },
  "success": true,
  "failed": false
}
```

**3. Receive webhook callback when processing completes:**

Your webhook URL will receive a POST request with the results. The `task_id` in the callback matches the one from step 2.

## Callback Payload Format

All webhook callbacks follow this general structure:

```json theme={null}
{
  "code": 200,
  "message": "SUCCESS",
  "data": {
    // Result data varies by endpoint — see each endpoint's
    // "Callback Response" section for details
  },
  "task_id": "1e8ae1075e054e8abb58e7598c53cbf1"
}
```

| Field     | Type    | Description                                                                                |
| --------- | ------- | ------------------------------------------------------------------------------------------ |
| `code`    | integer | Status code. `200` indicates success.                                                      |
| `message` | string  | Status message (e.g., `"SUCCESS"`).                                                        |
| `data`    | object  | The processing result. Structure varies by endpoint.                                       |
| `task_id` | string  | The task ID from the original async request. Use this to match callbacks to your requests. |

## Handling Webhook Callbacks

Here is an example webhook handler:

<CodeGroup>
  ```python Python (Flask) theme={null}
  from flask import Flask, request, jsonify

  app = Flask(__name__)

  @app.route("/webhook", methods=["POST"])
  def handle_webhook():
      payload = request.get_json()

      task_id = payload.get("task_id")
      code = payload.get("code")
      data = payload.get("data")

      if code == 200:
          print(f"Task {task_id} completed successfully")
          # Process the result data
      else:
          print(f"Task {task_id} failed with code {code}")

      return jsonify({"status": "ok"}), 200
  ```

  ```javascript Node.js (Express) theme={null}
  const express = require('express');
  const app = express();
  app.use(express.json());

  app.post('/webhook', (req, res) => {
    const { task_id, code, data } = req.body;

    if (code === 200) {
      console.log(`Task ${task_id} completed successfully`);
      // Process the result data
    } else {
      console.log(`Task ${task_id} failed with code ${code}`);
    }

    res.status(200).json({ status: 'ok' });
  });

  app.listen(3000, () => console.log('Webhook server running on port 3000'));
  ```
</CodeGroup>

## Important Notes

* Your webhook URL must be a **publicly accessible HTTPS endpoint**
* The callback request method is always **POST** with a JSON body
* Return a `2xx` status code to acknowledge receipt; non-2xx responses may trigger retries
* You can view callback history and debug failed deliveries at [Webhooks Settings](https://api-platform.memories.ai/webhooks)
* Use the `task_id` field to correlate callbacks with your original requests
