Official Python SDK for Transcribe API.
Project description
Transcribe API Python SDK
Official Python SDK for Transcribe API.
Use this SDK to send one file, many files, local uploads, remote audio URLs, webhook jobs, and large multipart uploads to the Transcribe API from Python.
Installation
pip install transcribe-api
Import
from transcribe_api import TranscribeAPI, TranscribeAPIError
Quick start
import os
from transcribe_api import TranscribeAPI
client = TranscribeAPI(
apiKey=os.environ["TRANSCRIBE_API_KEY"],
polling={
"interval": 10,
"timeout": 15 * 60,
},
)
result = client.transcribe(
language="en",
files=[
{"reference_id": "meeting_001", "file": "./meeting.mp3"},
],
)
print(result)
client.transcribe(files=[...]) is the main API for both single-file and multi-file transcription.
Important: the current SDK uses camelCase option names such as
apiKey,baseUrl,uploadConcurrency,showLogs, andwebhookUrl. It does not useapi_key,base_url,upload_concurrency, orclient.batch.transcribe(...).
How transcribe routes work
The SDK automatically chooses the right API flow:
- One small local file is sent through the direct synchronous upload path.
- One remote URL is sent through the direct
/v1/transcribeendpoint and the API decides whether it can finish immediately or should continue as an async job. - Multiple files, files larger than 30 MB, and files estimated over 10 minutes are sent through the async job flow.
- Large local async uploads use signed R2 upload URLs returned by the API.
- Multipart upload is used automatically when the backend returns multipart upload instructions.
- If
pollingis configured, async calls wait until the job reaches a terminal status. - If
pollingis not configured, async calls return the upload-completion/job response. Useclient.jobs.get(job_id)orclient.waitForJobCompletion(job_id, ...)to check later.
Terminal job statuses are completed, failed, and insufficient_funds. Completed job responses include result_url when the API has a result file ready.
Client options
client = TranscribeAPI(
apiKey="YOUR_API_KEY",
baseUrl="https://api.transcribeapi.com/v1",
uploadConcurrency=4,
autoReload={
"amount": 10,
"if_balance_below": 20,
},
showLogs=True,
logger=print,
polling={
"interval": 10,
"timeout": 15 * 60,
},
)
| Option | Description |
|---|---|
apiKey |
Required. Your Transcribe API key. |
baseUrl |
Optional. Defaults to https://api.transcribeapi.com/v1. |
uploadConcurrency |
Optional. Number of in-flight upload PUTs. Defaults to 1 and is capped at 32. |
autoReload |
Optional. Automatically calls POST /v1/add-funds after a transcription result when remaining_balance is below if_balance_below. |
showLogs |
Optional. Prints upload progress, upload completion, polling status, and final result info. |
logger |
Optional. Callable or logger-like object. Defaults to print. |
polling |
Optional. {"interval": 10, "timeout": 900} in seconds. interval must be at least 10. Omit or set to None/False to disable automatic polling. |
File inputs
Each item in files must be a dictionary with either file or url:
{"reference_id": "episode_1", "file": "./episode.mp3"}
{"reference_id": "episode_2", "url": "https://example.com/signed-audio-url.mp3"}
Supported local/upload inputs:
- Local path strings, such as
"./audio.mp3". pathlib.Pathobjects.bytesorbytearray.- File-like objects with a
.read()method.
Supported remote inputs:
- Public or signed URLs using
{"url": "https://..."}.
Do not include both file and url in the same item.
Local path inputs are streamed from disk. bytes, bytearray, and file-like inputs are read into memory by the SDK.
Single local file
result = client.transcribe(
files=[
{"reference_id": "call_001", "file": "./call.mp3"},
],
language="en",
)
For one small local file, this usually uses the direct upload path. Larger files automatically become async jobs.
File-like objects and bytes
with open("./meeting.wav", "rb") as audio:
result = client.transcribe(
files=[
{"reference_id": "meeting", "file": audio},
],
language="en",
)
audio_bytes = Path("./clip.mp3").read_bytes()
result = client.transcribe(
files=[
{"reference_id": "clip", "file": audio_bytes},
],
)
When the SDK receives raw bytes, it uses the fallback filename audio.mp3. For best content-type detection, prefer passing a path or file-like object with a useful .name.
Remote URL transcription
job = client.transcribe(
files=[
{"reference_id": "remote_001", "url": "https://example.com/audio.mp3"},
],
language="en",
)
For one remote URL, the SDK submits the request to the direct /v1/transcribe endpoint and lets the API decide the final route. Small remote files may complete immediately, while larger or longer remote files automatically fall back to the async job flow.
Batch and mixed input transcription
job = client.transcribe(
language="en",
uploadConcurrency=8,
files=[
{"reference_id": "episode_1", "file": "./episode-1.mp3"},
{"reference_id": "episode_2", "file": "./episode-2.wav"},
{"reference_id": "episode_3", "url": "https://example.com/episode-3.m4a"},
],
)
Local files and remote URLs can be mixed in the same batch. Provide a unique reference_id for every item so uploads and results can be matched reliably.
Per-file language
Set language at the top level to apply a default to the whole job. Set language on a file item to override the default for that file.
job = client.transcribe(
language="en",
files=[
{"reference_id": "intro", "file": "./intro.mp3"},
{"reference_id": "french_segment", "file": "./segment.m4a", "language": "fr"},
],
)
language must be a supported language code such as en, fr, or yue. Omit it, pass an empty value, or pass "auto" to avoid sending an explicit language.
Excluding outputs or features
Use exclude to pass API exclusions. Lists are joined with commas before sending. Valid values are only vtt, segments, metadata, billing, and detected_language.
result = client.transcribe(
files=[
{"reference_id": "meeting", "file": "./meeting.mp3"},
],
exclude=["vtt", "segments"],
)
You can also pass a comma-separated string:
exclude="metadata,billing"
For single-file outputs, if exclude leaves only one transcript field and removes metadata, billing, and detected language, the API returns that remaining value directly instead of a JSON object. Text-only responses return a plain string, VTT-only responses return a plain string, and segments-only responses return a list. Multi-file outputs still return JSON so each result stays associated with its reference_id.
If autoReload is enabled, the SDK always keeps billing in the request even if you included billing in exclude. It needs remaining_balance to decide whether to call POST /v1/add-funds.
Auto reload
client = TranscribeAPI(
apiKey="YOUR_API_KEY",
autoReload={
"amount": 10,
"if_balance_below": 20,
},
)
When autoReload is enabled, the SDK:
- checks
remaining_balanceafter a transcription result - only calls
POST /v1/add-fundswhen the balance is belowif_balance_below - sends
{"amount": amount, "if_balance_below": if_balance_below}to the API for backend-side protection too - ignores
billinginsideexcludeso the SDK can always readremaining_balance
Auto reload only runs when the transcription result returned to the SDK includes remaining_balance. If you disable polling for async jobs, immediate non-terminal async responses do not have enough billing data for the SDK to auto reload yet.
Manual add_funds for webhooks
When using webhooks with batch jobs, the transcription result goes to your webhook URL instead of the SDK. The autoReload config won't fire because the SDK never sees the result. Call client.add_funds() inside your webhook handler instead:
# Webhook handler (Flask example)
@app.route('/webhook', methods=['POST'])
def webhook():
payload = request.get_json()
remaining_balance = payload.get('remaining_balance', 0)
if remaining_balance < 20:
client = TranscribeAPI(apiKey=os.environ['TRANSCRIBE_API_KEY'])
client.add_funds(10, if_balance_below=20)
return '', 200
add_funds(amount, *, if_balance_below=None) calls POST /v1/add-funds:
amount— whole dollar amount from 5 to 100.if_balance_below— server-side guard. The API only charges if your current balance is actually below this threshold, making it safe against duplicate webhook deliveries.
Webhooks
job = client.transcribe(
webhookUrl="https://example.com/transcribe-webhook",
files=[
{"reference_id": "upload_001", "file": "./long-audio.mp3"},
],
)
For a single file or URL, webhookUrl is sent through the direct /v1/transcribe endpoint and the API decides whether it can finish immediately or should continue as a job. Multi-file requests still use the async batch flow.
Progress and logs
Use onProgress to receive structured progress events:
def on_progress(event):
print(event)
job = client.transcribe(
files=[
{"reference_id": "episode_1", "file": "./episode-1.mp3"},
{"reference_id": "episode_2", "file": "./episode-2.mp3"},
],
uploadConcurrency=4,
onProgress=on_progress,
)
Common event names:
upload_urls_receivedupload_startedupload_progressupload_completed
Progress events may include jobId, jobStatus, referenceId, loaded, total, fileLoaded, fileTotal, batchLoaded, batchTotal, uploadType, partNumber, totalParts, and multipartConcurrency.
Set showLogs=True on the client or on a single call to print built-in progress and polling logs:
client = TranscribeAPI(
apiKey=os.environ["TRANSCRIBE_API_KEY"],
showLogs=True,
)
Manual async jobs
transcribe uploads automatically. Use createBatchJob when you want to separate job creation from upload.
job = client.createBatchJob(
language="en",
files=[
{"reference_id": "part_1", "file": "./part-1.mp3"},
{"reference_id": "part_2", "url": "https://example.com/part-2.mp3"},
],
)
print(job.jobId)
completion = job.upload()
print(completion)
For a single large local file, you can also use createBigFileJob:
job = client.createBigFileJob(
file={"reference_id": "large_001", "file": "./large.wav"},
)
completion = job.upload()
Job helpers
job = client.jobs.get("job_id_here")
same_job = client.jobs.result("job_id_here")
final_job = client.waitForJobCompletion(
"job_id_here",
polling={"interval": 10, "timeout": 15 * 60},
)
Available job helpers:
| Method | Description |
|---|---|
client.jobs.get(jobId) |
Fetches GET /v1/transcribe/{job_id}. |
client.jobs.result(jobId) |
Alias for jobs.get. |
client.jobs.uploadCompleted(jobId) |
Calls POST /v1/transcribe/{job_id}/upload-completed. |
client.jobs.complete(jobId) |
Alias for jobs.uploadCompleted. |
client.jobs.createBatch(options) |
Creates a batch job and returns a BatchJob. |
client.jobs.createBigFile(options) |
Creates a one-file async upload job and returns a BatchJob. |
client.waitForJobCompletion(jobId, options) |
Polls until a terminal job status or timeout. |
Direct upload method
Most applications should use client.transcribe(files=[...]). If you specifically need to force the direct upload endpoint for one file, use transcribeDirect:
result = client.transcribeDirect(
file="./short.mp3",
referenceId="short_001",
language="en",
)
Limits and validation
- Batch jobs support up to
10,000files. - Batch local upload payloads support up to
10 GBtotal local file size and 50 hours total batch duration. - Per file up to 10 GB and up to 10 hours duration.
- Direct sync routing is used only for one local file up to
30 MBand about10 minutes. - Multipart upload starts when the backend returns multipart upload instructions. The SDK sends
size_bytesfor local files at least128 MBso the backend can choose multipart. uploadConcurrencydefaults to1and is capped at32.polling["interval"]must be at least10seconds.- Batch local uploads support
mp3,mpeg,mpga,m4a,wav, andwebm. .mp4is not supported.
Error handling
try:
result = client.transcribe(
files=[
{"reference_id": "bad_file", "file": "./missing.mp3"},
],
)
print(result)
except TranscribeAPIError as error:
print(str(error))
print(error.code)
print(error.status)
print(error.response)
print(error.to_json())
TranscribeAPIError includes message, code, status, response, and any extra fields returned by the API or generated by the SDK.
CLI
The package exposes a small CLI entrypoint:
transcribe-api --version
At the moment, the CLI only prints the package version or a basic placeholder message. Use the Python SDK for transcription work.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file transcribe_api-0.1.10.tar.gz.
File metadata
- Download URL: transcribe_api-0.1.10.tar.gz
- Upload date:
- Size: 25.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39d5fc86db26f63a7d0fc8fde85daf49a8881b83a30933b5e80c5d64db64c65e
|
|
| MD5 |
1a9fbc3625967a6fffb4890ac7d88436
|
|
| BLAKE2b-256 |
f4fdc4b7c8a95bc6ddf61cad849ecc9d70ed835ac4e5cfcd863c98165fd4613b
|
File details
Details for the file transcribe_api-0.1.10-py3-none-any.whl.
File metadata
- Download URL: transcribe_api-0.1.10-py3-none-any.whl
- Upload date:
- Size: 20.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21462ce8f9cc1346c959be4196a339f9521c14db25543fc032d4fd27a797ba2c
|
|
| MD5 |
0c8f3d0a3f88f5b0b296c6e2db11b6dc
|
|
| BLAKE2b-256 |
162e4d9aff640c29dd3f597da1e138ad8df811776056f854c00cb85a12139f6f
|