---
title: Serving Captions
url: https://docs.kaltura.com/docs/rich-media-cms-apis/content-management/captions-serving-captions
---

## Serving Captions


### Serve Raw

Returns the caption content in its original format (SRT, DFXP, etc.):


```bash
curl "$KALTURA_SERVICE_URL/service/caption_captionAsset/action/serve?ks=$KALTURA_KS&captionAssetId=$CAPTION_ASSET_ID"
```


| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `captionAssetId` | string | Yes | Caption asset ID to serve |

Returns a redirect to the CDN URL. Follow the redirect to get the raw content. The response Content-Type matches the caption format.

### Serve as WebVTT

Converts any caption format to WebVTT on the fly. Supports HLS segmented delivery:


```bash
# Get HLS M3U8 playlist (segmentIndex omitted or null)
curl "$KALTURA_SERVICE_URL/service/caption_captionAsset/action/serveWebVTT?ks=$KALTURA_KS&captionAssetId=$CAPTION_ASSET_ID"

# Get a specific WebVTT segment
curl "$KALTURA_SERVICE_URL/service/caption_captionAsset/action/serveWebVTT?ks=$KALTURA_KS&captionAssetId=$CAPTION_ASSET_ID&segmentIndex=0"
```


| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `captionAssetId` | string | — | Caption asset ID |
| `segmentDuration` | integer | 30 | Duration of each segment in seconds |
| `segmentIndex` | integer | null | Segment number. `null` returns M3U8 playlist (`application/x-mpegurl`). Integer returns WebVTT segment (`text/vtt`). |
| `localTimestamp` | integer | 10000 | Local timestamp offset |

**HLS delivery flow:**
1. Player requests M3U8 manifest via `serveWebVTT` (no `segmentIndex`)
2. Response is an HLS playlist with segment URLs
3. Player fetches individual WebVTT segments as needed

### Serve as JSON

Returns structured JSON with timestamps in milliseconds. Ideal for AI/LLM integrations, RAG pipelines, and programmatic caption analysis:


```bash
curl -X POST "$KALTURA_SERVICE_URL/service/caption_captionAsset/action/serveAsJson" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "captionAssetId=$CAPTION_ASSET_ID"
```


| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `captionAssetId` | string | Yes | Caption asset ID to serve as JSON |

**Response:**


```json
{
  "objects": [
    {
      "startTime": 0,
      "endTime": 5000,
      "content": [{"text": "Welcome to the presentation."}]
    },
    {
      "startTime": 5000,
      "endTime": 10000,
      "content": [{"text": "Today we cover the Kaltura API."}]
    }
  ]
}
```


Times are in milliseconds. Maximum source file size: 1 MB. For larger files, use `serve` or `serveWebVTT`.

### Serve by Entry ID

Serve the default caption for an entry without looking up the caption asset ID:


```bash
curl "$KALTURA_SERVICE_URL/service/caption_captionAsset/action/serveByEntryId?ks=$KALTURA_KS&entryId=$KALTURA_ENTRY_ID"
```


| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `entryId` | string | Yes | Media entry ID |
| `captionParamId` | integer | No | Target a specific template instead of the default |

Returns raw caption content for the entry's default caption asset. If no default caption exists, the call returns an error.

### Get Download URL


```bash
curl -X POST "$KALTURA_SERVICE_URL/service/caption_captionAsset/action/getUrl" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "id=$CAPTION_ASSET_ID"
```


| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | Caption asset ID |
| `storageId` | integer | No | Storage profile ID (for multi-CDN setups) |

**Response:** A direct CDN download URL string (JSON-encoded):


```json
"https://cfvod.kaltura.com/api_v3/service/caption_captionAsset/action/serve/captionAssetId/1_abc123de/ks/..."
```


Use `getUrl` + HTTP fetch for server-side consumption — `serve` returns a redirect which requires follow-redirect handling.
