Transcription API
The Transcription API uses AI to transcribe audio and video content. It converts spoken content into text that you can use for captions, subtitles, repurposing into text posts, or any other text-based workflow.
Submit an audio or video file for AI transcription.
Authentication
This endpoint uses API key authentication. Include your API key in the soku-api-key header.
An active Soku subscription (trialing or active) is required.
Transcription consumes AI credits from your account balance. The number of credits debited depends on the duration of the media. Check your credit balance in the Soku dashboard under Account > Credits.
| Header | Required | Description |
|---|
Content-Type | Yes | Must be application/json |
soku-api-key | Yes | Your Soku API key |
Idempotency-Key | No | A unique string to prevent duplicate transcription jobs. If you send the same Idempotency-Key within a reasonable time window, the API returns the original result instead of creating a new job. |
Rate Limit
10 requests per 60 seconds, in addition to the global tier limit. See Rate Limits.
Request Body
| Field | Type | Required | Description |
|---|
mediaId | string | Yes | The ID of the media file to transcribe. This must be a media file already uploaded to the Soku media library. |
language | string | No | The language of the audio content as an ISO 639-1 code (for example, "en", "es", "fr"). Defaults to auto-detection if omitted. |
model | string | No | The transcription model to use. Currently supported: "whisper-1". Defaults to "whisper-1". |
durationSeconds | number | No | The duration of the media in seconds. Providing this helps the API estimate credit cost before processing. |
Response
Status: 200 OK
| Field | Type | Description |
|---|
jobId | string | A unique identifier for the transcription job |
transcript | string | The transcribed text from the audio or video content |
creditsDebited | number | The number of AI credits consumed by this transcription |
likelyLyrics | boolean | Whether the transcribed content appears to be song lyrics based on heuristic analysis |
The Idempotency-Key is returned as a response header, not in the JSON body.
{
"jobId": "tj_a1b2c3d4-e5f6-7890",
"transcript": "Hello and welcome to today's episode...",
"creditsDebited": 1,
"likelyLyrics": false
}
Examples
Basic transcription
curl -X POST https://api.mysoku.io/v1/ai/transcribe \
-H "Content-Type: application/json" \
-H "soku-api-key: sk_live_your_api_key_here" \
-d '{
"mediaId": "media_f7e8d9c0b3c4",
"language": "en",
"model": "whisper-1"
}'
Response:
{
"jobId": "tj_d4e5f6a7-b8c9-0123",
"transcript": "In this video we will cover three important topics...",
"creditsDebited": 1,
"likelyLyrics": false
}
Transcription with idempotency
Use the Idempotency-Key header to prevent duplicate charges if you need to retry a request:
curl -X POST https://api.mysoku.io/v1/ai/transcribe \
-H "Content-Type: application/json" \
-H "soku-api-key: sk_live_your_api_key_here" \
-H "Idempotency-Key: unique-request-id-abc123" \
-d '{
"mediaId": "media_f7e8d9c0b3c4",
"language": "en",
"model": "whisper-1",
"durationSeconds": 120
}'
If you send the same request with the same Idempotency-Key, you receive the original result without being charged again.
Transcription with duration estimate
Providing durationSeconds helps the API estimate the credit cost:
curl -X POST https://api.mysoku.io/v1/ai/transcribe \
-H "Content-Type: application/json" \
-H "soku-api-key: sk_live_your_api_key_here" \
-d '{
"mediaId": "media_a1b2c3d4e5f6",
"language": "es",
"model": "whisper-1",
"durationSeconds": 300
}'
Credit Costs
Transcription costs vary based on the duration of the media file. Credits are debited from your account balance when the transcription completes.
Monitor your credit balance in the Soku dashboard under Account > Credits. For information on credit pricing and how to purchase more credits, see Credits System.
Idempotency
The Idempotency-Key header is strongly recommended for transcription requests. Because transcription consumes credits, accidental duplicate requests can result in unnecessary charges.
How it works:
- Include an
Idempotency-Key header with a unique value (for example, a UUID) on your first request.
- If the request succeeds, the API caches the result keyed by your idempotency key.
- If you retry with the same
Idempotency-Key, the API returns the cached result without processing the transcription again or charging additional credits.
# Both requests return the same result; credits are only charged once
curl -X POST https://api.mysoku.io/v1/ai/transcribe \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
...
curl -X POST https://api.mysoku.io/v1/ai/transcribe \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
...
Error Responses
| HTTP Status | Error Code | Description |
|---|
| 400 | validation_error | Missing or invalid mediaId or other fields |
| 401 | unauthorized | Missing or invalid API key |
| 402 | insufficient_credits | Your account does not have enough AI credits for this transcription |
| 403 | forbidden | Subscription is not active |
| 404 | not_found | The specified mediaId does not exist in your media library |
| 409 | idempotency_conflict | Same idempotency key used with a different request body |
| 429 | rate_limit_exceeded | Too many requests. See Rate Limits. |
| 500 | internal_error | An error occurred during transcription processing |
Example error response (insufficient credits):
{
"error": {
"type": "invalid_request_error",
"code": "insufficient_credits",
"message": "Your account does not have enough AI credits to complete this transcription. Estimated cost: 15 credits. Current balance: 3 credits.",
"timestamp": "2026-02-28T12:00:00.000Z",
"requestId": "req_abc123def456",
"details": {
"estimatedCost": 15,
"currentBalance": 3
}
}
}
Next Steps
| Topic | Description |
|---|
| Posts API | Publish transcribed content as posts |
| Media API | Upload media for transcription |
| Credits System | Manage your AI credit balance |
| AI Transcription | Using transcription in the dashboard |