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

# Generate Highlights from Transcription Job

> Generate AI-powered video highlights from a completed transcription job

## Overview

Generate concise video highlights from a completed transcription job using AI-powered extraction. This endpoint analyzes the transcript from your transcription job and identifies the most important segments to create a summary of your desired duration.

**What you will accomplish:**

* Extract key highlights from completed transcription jobs
* Generate summaries of specific durations
* Receive webhook notifications when processing completes
* Create engaging short-form content from long videos

<Note>
  You need a valid API key to use this endpoint. Get your API key from the [API Access page](https://app.pictory.ai/api-access) in your Pictory dashboard.
</Note>

<Note>
  This endpoint requires a completed transcription job. First use the [Video Transcription API](/api-reference/transcription/video-transcription) to generate a transcript, then use the returned `jobId` with this endpoint.
</Note>

***

## Request Headers

<ParamField header="Authorization" type="string" required>
  API key for authentication

  ```
  Authorization: YOUR_API_KEY
  ```
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be set to `application/json`

  ```
  Content-Type: application/json
  ```
</ParamField>

***

## Path Parameters

<ParamField path="jobId" type="string" required>
  The unique identifier of the transcription job. This is the job ID returned from the [Video Transcription API](/api-reference/transcription/video-transcription).

  Example: `95333422-8e76-4962-812b-5b6d7276451a`
</ParamField>

***

## Body Parameters

<ParamField body="highlight_duration" type="integer" optional>
  Target duration for the video summary in seconds. The AI will select highlights that fit within this duration.

  Example: `30` for a 30-second summary, `60` for a 1-minute summary
</ParamField>

<ParamField body="webhook" type="string" optional>
  Webhook URL where the summary results will be posted when processing completes. The webhook will receive a POST request with the summary data.

  Example: `https://your-domain.com/api/webhooks/highlights`
</ParamField>

<ParamField body="language" type="string" optional default="en">
  Language code for the transcript content.

  Supported values: `en` (English), `es` (Spanish), `fr` (French), `de` (German), `it` (Italian), `pt` (Portuguese), `ja` (Japanese), `ko` (Korean), `zh` (Chinese), `ar` (Arabic), `hi` (Hindi), `ru` (Russian), and more.

  Example: `en` for English, `es` for Spanish
</ParamField>

***

## Response

<ResponseField name="success" type="boolean">
  Indicates whether the request was successfully queued for processing
</ResponseField>

<ResponseField name="data" type="object">
  Contains the job information

  <Expandable title="data properties">
    <ResponseField name="jobId" type="string">
      Unique identifier for the highlights generation job. Use this ID to track the job status via the [Get Job by ID API](/api-reference/jobs/get-transcription-job-by-id).
    </ResponseField>
  </Expandable>
</ResponseField>

***

## Response Examples

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "success": true,
    "data": {
      "jobId": "bbd75639-c3cb-4add-bf7b-e4e39cffb3b0"
    }
  }
  ```

  ```json 400 - Transcription Not Ready theme={null}
  {
    "success": false,
    "data": {
      "error_code": "4004",
      "error_message": "Highlights could not be generated as transcription is still in-progress or not found."
    }
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
    "message": "Unauthorized"
  }
  ```
</ResponseExample>

### Job Status Response (via Get Job API)

While the highlights job is processing:

```json theme={null}
{
  "job_id": "bbd75639-c3cb-4add-bf7b-e4e39cffb3b0",
  "success": true,
  "data": {
    "status": "in-progress"
  }
}
```

When the highlights job completes, you will receive the full result with highlight markers via webhook or by polling the [Get Job by ID API](/api-reference/jobs/get-transcription-job-by-id).

***

## Code Examples

<Tip>
  Replace `YOUR_API_KEY` with your actual API key and `YOUR_JOB_ID` with the transcription job ID.
</Tip>

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.pictory.ai/pictoryapis/v2/transcription/YOUR_JOB_ID/highlights \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "highlight_duration": 30,
      "webhook": "https://your-domain.com/api/webhooks/highlights",
      "language": "en"
    }'
  ```

  ```python Python theme={null}
  import requests

  job_id = "95333422-8e76-4962-812b-5b6d7276451a"  # Transcription job ID
  url = f"https://api.pictory.ai/pictoryapis/v2/transcription/{job_id}/highlights"
  headers = {
      "Authorization": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  payload = {
      "highlight_duration": 30,
      "language": "en",
      "webhook": "https://your-domain.com/api/webhooks/highlights"
  }

  response = requests.post(url, json=payload, headers=headers)
  data = response.json()

  if data.get("success"):
      print(f"Highlights Job ID: {data['data']['jobId']}")
      print("Highlights generation started successfully")
  else:
      print(f"Error: {data.get('message', 'Unknown error')}")
  ```

  ```javascript JavaScript theme={null}
  const jobId = '95333422-8e76-4962-812b-5b6d7276451a'; // Transcription job ID
  const response = await fetch(
    `https://api.pictory.ai/pictoryapis/v2/transcription/${jobId}/highlights`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        highlight_duration: 30,
        language: 'en',
        webhook: 'https://your-domain.com/api/webhooks/highlights'
      })
    }
  );

  const data = await response.json();

  if (data.success) {
    console.log(`Highlights Job ID: ${data.data.jobId}`);
    console.log('Highlights generation started successfully');
  } else {
    console.log(`Error: ${data.message || 'Unknown error'}`);
  }
  ```

  ```php PHP theme={null}
  <?php
  $jobId = "95333422-8e76-4962-812b-5b6d7276451a"; // Transcription job ID
  $url = "https://api.pictory.ai/pictoryapis/v2/transcription/{$jobId}/highlights";

  $payload = [
      'highlight_duration' => 30,
      'language' => 'en',
      'webhook' => 'https://your-domain.com/api/webhooks/highlights'
  ];

  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: YOUR_API_KEY',
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

  $response = curl_exec($ch);
  $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  $data = json_decode($response, true);

  if ($httpCode === 200 && $data['success']) {
      echo "Highlights Job ID: " . $data['data']['jobId'] . "\n";
      echo "Highlights generation started successfully\n";
  } else {
      echo "Error: " . ($data['message'] ?? 'Unknown error') . "\n";
  }
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io"
      "net/http"
  )

  func main() {
      jobId := "95333422-8e76-4962-812b-5b6d7276451a" // Transcription job ID
      url := fmt.Sprintf("https://api.pictory.ai/pictoryapis/v2/transcription/%s/highlights", jobId)

      payload := map[string]interface{}{
          "highlight_duration": 30,
          "language":          "en",
          "webhook":           "https://your-domain.com/api/webhooks/highlights",
      }

      jsonData, _ := json.Marshal(payload)

      req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
      req.Header.Set("Authorization", "YOUR_API_KEY")
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          fmt.Println("Error:", err)
          return
      }
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)
      var result map[string]interface{}
      json.Unmarshal(body, &result)

      if result["success"].(bool) {
          data := result["data"].(map[string]interface{})
          fmt.Printf("Highlights Job ID: %s\n", data["jobId"])
          fmt.Println("Highlights generation started successfully")
      } else {
          fmt.Printf("Error: %s\n", result["message"])
      }
  }
  ```
</CodeGroup>

***

## Usage Notes

<Note>
  **Async Processing**: This endpoint processes highlights asynchronously. You will receive a `jobId` immediately, and the actual highlights will be generated in the background.
</Note>

<Tip>
  **Webhook Notifications**: Provide a webhook URL to receive the completed highlights automatically when processing finishes. This is the recommended approach rather than polling.
</Tip>

<Warning>
  **Transcription Must Be Complete**: The transcription job must be fully complete before you can generate highlights. If the transcription is still processing, you will receive a 4004 error.
</Warning>

***

## Best Practices

1. **Wait for Transcription**: Always check that the transcription job status is "completed" before calling this endpoint
2. **Webhook Implementation**: Use webhooks instead of polling for better performance and user experience
3. **Duration Selection**: Choose highlight duration based on your target platform (e.g., 15-30s for TikTok, 60s for YouTube Shorts)
4. **Error Handling**: Implement retry logic for 4004 errors if the transcription is still processing

***

## Related Endpoints

* [Video Transcription API](/api-reference/transcription/video-transcription) - Generate the transcription job first
* [Generate Highlights from Custom Transcript](/api-reference/transcription/generate-highlights-from-transcript) - Use edited transcript instead
* [Get Job by ID](/api-reference/jobs/get-transcription-job-by-id) - Check job status and retrieve results
