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

# Auto-refresh video secure tokens

> Auto-refresh video secure tokens keep HLS and DASH URLs short-lived, rotating tokens before expiry to stop copied links from working.

A secure token embeds authentication directly in the HLS/DASH URL path:

```text theme={null}
https://cdn.example.com/videos/{id}/{token}/{expires}/master.m3u8
```

This URL is visible in browser developer tools. With a 24-hour token, a paying subscriber can share the URL and anyone with it can watch for the full 24 hours. Short-lived tokens with automatic player-side refresh eliminate the window: any copied URL remains usable only until the current token expires.

![Browser showing 410 Gone response for an expired secure token in the network panel](https://mintcdn.com/gcore/mB9xUQPpVbdf6kcA/images/docs/streaming/interaction-with-cdn/token-auto-refresh/cdn-token-protected.png?fit=max\&auto=format\&n=mB9xUQPpVbdf6kcA\&q=85\&s=6cde3265450f18b2afa39b74c87154e5)

## Token rotation flow

```text theme={null}
   Player loads          ~10 s before expiry      Fresh token received
   with 60-s URL
        │                       │                         │
   ─────┼───────────────────────┼─────────────────────────┼──────────────▶ time
        │    seamless playback  │   background fetch      │   continues
        │◄───────────────────────────────────────────────►│
```

1. The player loads with a signed URL containing a short-lived token.
2. A timer fires a few seconds before expiry.
3. The player calls the backend and receives a fresh `{ token, expires, url }` response.
4. The new `{token}/{expires}` path segments replace the old ones in every outgoing request.
5. Playback continues without visible interruption.

## Token modes

Auto-refresh works with two secure token modes:

| Mode | Description | When to use |
| - | - | - |
| Plain token | Valid from any IP. Copied URLs stop working when the token expires. | Users behind NAT, VPNs, or mobile networks where IP changes |
| IP-bound token | Tied to the viewer's IP at generation time. Copied URLs fail even within the TTL. | Desktop viewers on stable connections |

## Choosing a token lifetime

Shorter tokens reduce the time a copied URL stays usable; longer tokens give the player more time to complete a refresh on slow connections.

On a poor mobile connection, the player may need several seconds to fetch a fresh token and download the next media segment before the old token expires. If both operations do not complete in time, the CDN rejects the segment request with 403/410 and playback stalls.

| TTL | Notes |
| - | - |
| 20–60 s | Copied URLs stop working within seconds to a minute. Risk of playback stalls on slow connections. |
| 300–600 s (5–10 min) | Typical production range. Balances protection with network resilience. |
| 3600 s (1 h) | Suitable for low-risk content or wide audiences. |

Set `refreshLeadSeconds` to a value less than the token TTL. A lead of 10 seconds works for short-lived tokens (under 60 s); use 30–60 seconds for longer TTLs.

## Auto-refresh architecture

Token refresh happens on the client side — the CDN validates tokens but cannot issue new ones. Two components work together:

* A backend endpoint that generates fresh signed URLs on demand. The server holds the CDN secret key and must verify that the user is authorized before signing.
* Player-side refresh logic that calls the backend shortly before expiry and updates every outgoing URL without reloading the stream.

```text theme={null}
┌── Browser ─────────────────────────────────────────────┐
│                                                        │
│  ┌── Video Player ──────────────────────────────────┐  │
│  │                                                  │  │
│  │  ┌────────────────┐  (1) GET /api/token          │  │   ┌──────────────────┐
│  │  │ Token refresh  ├──────────────────────────────────────► Your backend    │
│  │  │ timer / plugin │◄────────────────────────────────────  • verify user    │
│  │  └───────┬────────┘  (2) { token, expires, url } │  │   │ • sign token     │
│  │          │                                       │  │   └──────────────────┘
│  │    (3) update {token}/{expires} in all URLs      │  │
│  │          │                                       │  │
│  │  ┌───────▼────────┐  (4) signed video URL        │  │   ┌──────────────────┐
│  │  │ HLS/DASH       ├─────────────────────────────────────► Gcore CDN        │
│  │  │ URL loader     │◄────────────────────────────────────  • validate token │
│  │  └────────────────┘  (5) video segments          │  │   │ • serve content  │
│  └──────────────────────────────────────────────────┘  │   └──────────────────┘
└────────────────────────────────────────────────────────┘
```

## Backend contract

The backend endpoint receives a request from the player, authenticates the user, verifies access to the requested video, and returns:

```json theme={null}
{
  "token":     "<plain token>",
  "token_ip":  "<IP-bound token>",
  "client_ip": "<viewer IP>",
  "expires":   1700000060,
  "url":       "https://cdn.example.com/videos/.../master.m3u8",
  "url_ip":    "https://cdn-ip.example.com/videos/.../master.m3u8"
}
```

A reference implementation built on [Gcore FastEdge](https://gcore.com/fastedge) is available in [Create a video token API with FastEdge](/streaming/interaction-with-cdn/token-api-fastedge). To implement the client side of this flow, [Add token auto‑refresh to a video player](/streaming/interaction-with-cdn/player-token-refresh) provides code examples for Gcore Video Player, hls.js, and dash.js.
