---
title: "Get Event Clip Url"
method: GET
path: "/events/{event_id}/clip-url"
tags: ["events"]
---

# Get Event Clip Url

`GET /events/{event_id}/clip-url`

## Request

- Base URL: `https://api.verdun.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.verdun.ai/events/{event_id}/clip-url`
- Auth: HTTP bearer

Freshly presign the event's clip (1h). The clip object is HEAD-checked first: 404 when the event has no clip key, 409 `CLIP_UNAVAILABLE` when the key exists but the object is gone from storage (the `clips/` lifecycle). A starred event plays from its retained `starred-clips/` copy when it has one. `continued_clip_url` (same expiry) is set only once the ingestor has committed a continued clip for the alarm; `extended_clip_url` is presigned blind.

## Path parameters

- `event_id` string, required

## Response `200`

Successful Response

- GetEventClipUrlResponse
  - `clip_url` string, required: Freshly presigned URL for the event's clip
  - `expires_in` integer, required: Seconds until the presigned URL expires
  - `extended_clip_url` string, nullable: Presigned URL for the event's extended pre-roll ("Rewind") clip, valid for the same expires_in as clip_url. Null when the clip key does not derive one (demo/training/pre-cutover rows) or the presign failed. Presigned BLIND: a non-null URL does NOT mean the object exists — probe it (a 403/404 means the extended clip was never uploaded or has expired by the clips-extended/ 7-day lifecycle).
  - `continued_clip_url` string, nullable: Presigned URL for the event's continued clip (the extra seconds cut when motion was still firing after the clip's post-roll), valid for the same expires_in as clip_url. Null when the alarm has no committed continued clip (event.has_continued_clip false), when the continuation is older than the clip retention window (it has expired from storage; same window as the main clip's clips/ lifecycle) or the presign failed. Unlike extended_clip_url it is NOT blind: it is only minted after the ingestor committed the upload.
  - `continued_poster_url` string, nullable: Presigned URL for the continued clip's poster frame (JPEG), valid for the same expires_in as clip_url. Set under exactly the same conditions as continued_clip_url, else null. Presigned BLIND: the ingestor writes the poster best-effort, so the object may be absent; fall back on a load error.
  - `clip_display_rotation` integer, nullable: Display rotation (degrees CCW: 0, 90, 180 or 270) already applied by clip_url's own container tag. 0 = untagged; null = unknown (HEAD failed/timed out or stamp unreadable). Players must not turn a clip again that is tagged non-zero.
  - `extended_clip_display_rotation` integer, nullable: Same as clip_display_rotation, for extended_clip_url (Rewind). Inferred from the main clip when the camera was never rotated (not an availability signal); otherwise probed with one HEAD, and then null when the object is absent or the HEAD did not answer within 1 s. Null when there is no extended URL.
  - `continued_clip_display_rotation` integer, nullable: Same as clip_display_rotation, for continued_clip_url. Inferred from the main clip when the camera was never rotated (not an availability signal); otherwise probed with one HEAD, and then null when the object is absent or the HEAD did not answer within 1 s. Null when there is no continued clip.

## Other responses

- `409`: The clip object is gone from storage (code CLIP_UNAVAILABLE)
- `422`: Validation Error

---

[API](https://skmtc.dev/verdun/apis/verdun-api.md) - [All operations](https://skmtc.dev/verdun/apis/verdun-api/llms.txt) - [OpenAPI document](https://skmtc.dev/verdun/apis/verdun-api/revisions/35a2a6ebedda?raw)
