---
title: "Get job status and audio URL"
method: GET
path: "/api/v1/tts/{jobId}"
tags: ["Public API v1"]
---

# Get job status and audio URL

`GET /api/v1/tts/{jobId}`

Poll this endpoint every 2–3 seconds until `status` is `completed` or `failed`. When `completed`, `audioUrl` contains a presigned S3 URL valid for 24 hours.

## Path parameters

- `jobId` string, required

## Response `200`

Current job state; `audioUrl` is present once `status` is `completed`.

- PublicTtsStatusResponseDto
  - `jobId` string, required
  - `status` 'queued' | 'processing' | 'completed' | 'failed', required
  - `audioUrl` string — Presigned S3 download URL. Only present when status=completed. Valid for 24 hours.
  - `audioUrlExpiresIn` number — Seconds until audioUrl expires.
  - `duration` number
  - `voiceId` string
  - `textLength` number
  - `createdAt` string, date-time
  - `completedAt` string, date-time
  - `queuePosition` number — Position in queue (only when status=queued).
  - `estimatedWaitSeconds` number — Estimated seconds until processing starts (only when status=queued).
  - `error` string

## Other responses

- `401` — API key missing, malformed, or revoked.
- `404` — No job with that id belongs to you. Jobs are scoped to the key’s owner — a valid key proves identity, not ownership of this job.
- `429` — Rate limit or token quota exceeded. When the limit came from the application the response carries `Retry-After` (seconds) and the `X-RateLimit-*` headers and is counted against your API key; a 429 with none of those headers came from the edge proxy and is counted against your source address, shared with every other key calling from it. Back off on either.

---

[API](https://skmtc.dev/vieneu/apis/vieneu-api.md) · [All operations](https://skmtc.dev/vieneu/apis/vieneu-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/vieneu/vieneu-api/revisions/11c8166a6c4d/schema)
