Create a Job from a URL
Create a transcription job from an audio or video file that the API can fetch by URL. The API returns a job ID right away, and you receive the transcript by webhook, as a stream, or by polling the job. To transcribe a file from your machine, upload it instead.
Endpoint
POST https://api.speechischeap.com/v2/jobs/
Authentication
Send your API key as a Bearer token:
Authorization: Bearer YOUR_API_KEY
Request
Send a JSON body with Content-Type: application/json. Only input_url is required.
| Parameter | Type | Default | Description |
|---|---|---|---|
input_url | string | Required | The URL of the audio or video file to transcribe. The API checks the URL before it creates the job. See Input Requirements for the rules. |
can_label_audio | boolean | false | When enabled, includes an audio classification label in the transcription. See Output and Add-ons for its output and pricing for its price. |
can_parse_speakers | boolean | false | When enabled, adds speaker_id to each segment based on the speaker's voice. See Output and Add-ons for its output and pricing for its price. |
can_parse_words | boolean | false | When enabled, includes a timecode for every word in the transcription. See Output and Add-ons for its output and pricing for its price. |
can_stream_output | boolean | false | When enabled, streams progress and chronological transcription segments using Server-Sent Events. See Stream Progress. |
is_private | boolean | false | When enabled, redacts the original input_url and deletes the segments 12 hours after the job completes. See Private Jobs. |
is_split_channel | boolean | false | When enabled, parses speakers from multi-channel audio by assigning one speaker per channel. Useful for multi-track recordings. See Split Channels. |
language | string | "" | A code from Supported Languages, such as en. Send it in lowercase. If you set it, the API transcribes every segment in that language. If you leave it empty, the API detects the language of each segment. An unsupported code fails the job after the API accepts it. |
minimum_confidence | number | 0.5 | Filter out segments that fall below this confidence threshold, from 0 to 1. A value outside that range fails the job after the API accepts it. See Minimum Confidence. |
output_format | string | "" | The format of the transcript sent to your webhook and of a stream: srt, vtt, or webvtt (an alias for vtt). The value is case-insensitive. Get a Job takes its own output_format. See SRT and VTT Output. |
segment_duration | number | 30 | The maximum duration of a transcription segment in seconds. The API adjusts a value outside 6 to 30 to that range. |
user_agent | string | Set by the API | The User-Agent header the API sends when it fetches input_url. |
webhook_url | string | "" | The URL that receives the job's result in a single POST request. See Webhooks. |
Example Requests
Create a Job
curl --request POST \
--url https://api.speechischeap.com/v2/jobs/ \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{"input_url": "https://example.com/audio-file.mp3"}'
Get the job until its status is COMPLETED.
Receive the Result by Webhook
curl --request POST \
--url https://api.speechischeap.com/v2/jobs/ \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"input_url": "https://example.com/audio-file.mp3",
"webhook_url": "https://your-domain.com/webhook"
}'
Stream the Result
curl --request POST \
--url https://api.speechischeap.com/v2/jobs/ \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"input_url": "https://example.com/audio-file.mp3",
"can_stream_output": true
}' \
--no-buffer
The --no-buffer option prints each event as it arrives.
Add Speakers and Word Timestamps
curl --request POST \
--url https://api.speechischeap.com/v2/jobs/ \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"input_url": "https://example.com/audio-file.mp3",
"webhook_url": "https://your-domain.com/webhook",
"can_parse_speakers": true,
"can_parse_words": true,
"language": "en"
}'
Set Every Parameter
This body turns on all three add-ons, which cost extra. Remove what you don't need.
{
"input_url": "https://example.com/audio-file.mp3",
"webhook_url": "https://your-domain.com/webhook",
"can_label_audio": true,
"can_parse_speakers": true,
"can_parse_words": true,
"can_stream_output": false,
"is_private": true,
"is_split_channel": true,
"language": "en",
"minimum_confidence": 0.3,
"output_format": "srt",
"segment_duration": 15,
"user_agent": "Mozilla/5.0"
}
Response
The API uses standard HTTP status codes to indicate the outcome of your request.
| Status Code | Description |
|---|---|
| 202 Accepted | The API created the job. Its status is PENDING. |
| 200 OK | The job was created with can_stream_output. The body is an event stream. |
| 400 Bad Request | The body isn't valid JSON, input_url is missing or unreachable, or output_format isn't srt, vtt, or webvtt. |
| 401 Unauthorized | The Authorization header is missing or malformed, or the API key is unknown, expired, or revoked. |
| 402 Payment Required | The API key is known, but its billing isn't active. |
| 500 Internal Server Error | The API couldn't start or save the job. Create it again. |
New Job Response
{
"id": "00000000-1111-7222-b333-444444444444-sic",
"output": {},
"status": "PENDING"
}
Save the id. You use it to get or cancel the job. Job IDs are unguessable, but anyone who has one can read the job. See Keep Job IDs Private.
Streaming Job Response
With can_stream_output, the response is 200 OK with Content-Type: text/event-stream. See Stream Progress for the events.
Errors
Errors have a plain-text body, and the most likely are Missing required "input_url" parameter, Input URL is not reachable, and the 401 and 402 messages for the API key. See Jobs API errors for each message, and Failures After a Job Is Accepted for problems the API finds after it returns 202.
Notes
- You pay only when a job completes. See Billing.
- Set a
webhook_urlif you need to know why a job failed. The reason reaches only the webhook. - Because
is_privatemasks theinput_url, it can limit our ability to troubleshoot a job.