# Generate engagement insights

Turn viewer engagement data into plain-language insights for a Mux video with the Mux Robots API. Use the insights to learn where viewers drop off and why.

<Callout type="warning" title="Experimental">
  The `generate-engagement-insights` workflow is experimental. The API shape, parameters, behavior, and pricing may change. If we make changes to this workflow while you're using it, we'll let you know via email.
</Callout>

Generate plain-language insights from how viewers watched a video. This workflow analyzes the engagement patterns Mux Data has collected for an asset (which moments held attention and which lost it) and returns per-moment insights for the most notable moments plus an overall summary and trends. It's useful for explaining retention to non-analysts, prioritizing edits, and surfacing what's working across a library. See the <ApiRefLink href="/docs/api-reference/robots/generate-engagement-insights">Generate Engagement Insights API reference</ApiRefLink> for the full endpoint specification. See [Mux Robots pricing](/docs/pricing/overview#mux-robots-pricing) for unit costs.

<Callout type="info">
  Generate engagement insights builds on [Mux Data engagement metrics](/docs/guides/engagement-hotspots-and-heatmaps), so the asset needs accumulated viewing data before there's anything to analyze. You'll need:

  * Mux Data collecting views for the content. By using [Mux Player](/docs/guides/mux-player-web), this happens automatically with no extra setup. With a third-party or custom player, add a [Mux Data SDK](/docs/guides/track-your-video-performance) or [custom integration](/docs/guides/build-a-custom-data-integration) so views are tracked.
  * Enough completed views for Mux to aggregate engagement. Freshly published content or content without views won't have data to analyze.
</Callout>

## Create a `generate-engagement-insights` job

```bash
curl https://api.mux.com/robots/v0/jobs/generate-engagement-insights \
  -H "Content-Type: application/json" \
  -X POST \
  -d '{
    "parameters": {
      "asset_id": "YOUR_ASSET_ID"
    }
  }' \
  -u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET}
```

<Callout type="info">
  This request is **asynchronous**. The `POST` returns immediately with the job in `pending` status and does not include results. **We strongly recommend listening for the [`robots.job.generate_engagement_insights.completed` webhook](/docs/guides/robots#webhooks)**. The payload contains the full completed job, so no follow-up API call is needed. If webhooks aren't an option, you can poll `GET /robots/v0/jobs/generate-engagement-insights/{JOB_ID}` with the `id` from the response until the status is `completed`.
</Callout>

## Parameters

| Parameter | Type | Description |
| :-- | :-- | :-- |
| `asset_id` | string | **Required.** The Mux asset ID of the video to analyze engagement for. |

## Output

The `outputs` object is included in the job once its status is `completed`. You'll receive it on the [`robots.job.generate_engagement_insights.completed`](/docs/guides/robots#webhooks) webhook (recommended), or you can fetch it with `GET /robots/v0/jobs/generate-engagement-insights/{JOB_ID}`. It contains:

| Field | Type | Description |
| :-- | :-- | :-- |
| `moment_insights` | array | Per-moment engagement insights for the most notable moments. |
| `moment_insights[].start_ms` | number | Moment start time in milliseconds. |
| `moment_insights[].end_ms` | number | Moment end time in milliseconds. |
| `moment_insights[].engagement_score` | number | Normalized engagement score from `0` to `1`. |
| `moment_insights[].insight` | string | Primary insight explaining the engagement pattern for the moment. |
| `overall_insight` | object | Overall engagement analysis across the video. |
| `overall_insight.summary` | string | Summary of overall engagement patterns. |
| `overall_insight.trends` | array of strings | Key trends identified across the video. |

## Example response

This is the payload delivered to the [`robots.job.generate_engagement_insights.completed`](/docs/guides/robots#webhooks) webhook, and the same shape you get from `GET /robots/v0/jobs/generate-engagement-insights/{JOB_ID}`:

```json
{
  "data": {
    "id": "rjob_eng123",
    "workflow": "generate-engagement-insights",
    "status": "completed",
    "units_consumed": 1,
    "parameters": {
      "asset_id": "YOUR_ASSET_ID"
    },
    "outputs": {
      "moment_insights": [
        {
          "start_ms": 30000,
          "end_ms": 60000,
          "engagement_score": 0.89,
          "insight": "Viewers are highly engaged during the product demo, with minimal drop-off."
        }
      ],
      "overall_insight": {
        "summary": "Engagement peaks during hands-on demonstrations and drops during introductory segments.",
        "trends": [
          "Product demos drive the highest retention",
          "Viewers skip past the first 15 seconds of intro"
        ]
      }
    }
  }
}
```
