---
title: "Get a playback URL"
method: GET
path: "/v1/jobs/{job_id}/audio/url"
tags: ["Jobs"]
---

# Get a playback URL

`GET /v1/jobs/{job_id}/audio/url`

## Request

- Base URL: `https://whipscribe.com/api`
- URL: `https://whipscribe.com/api/v1/jobs/{job_id}/audio/url`
- Auth: API key in header `X-API-Key`

A short-lived URL for streaming the original audio, so your API key stays off the playback path.

## Path parameters

- `job_id` string, uuid, required

## Headers

- `X-Claim-Token` string

## Response `200`

Playback URL.

- PlaybackUrl
  - `url` string, required: Short-lived URL an `<audio>` element (or any client that supports Range) can stream from.
  - `expires_in` integer: Seconds until the URL expires; fetch a new one after that.
  - `storage` 'direct' | 'signed': `direct`: `url` is absolute; use it as is. `signed`: `url` is a path on this API (`/v1/jobs/{job_id}/audio?token=…`); prefix it with the API base you called (for example `https://whipscribe.com/api`).

## Other responses

- `400`: Malformed request (e.g. `BAD_ID`, `BAD_URL`, `BAD_IDEMPOTENCY_KEY`).
- `401`: Missing or invalid API key, or the job needs an ownership proof (`X-Claim-Token`).
- `404`: Unknown job id, or a job that is not yours.
- `410`: Audio retention window has passed (`AUDIO_EXPIRED`) or the audio is gone (`AUDIO_MISSING`). The transcript is still readable.
- `429`: Too many requests; retry with backoff (`RATE_LIMITED`, `QUOTA_EXCEEDED`).

---

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