Skip to main content

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, and webhookUrl. It does not use api_key, base_url, upload_concurrency, or client.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/transcribe endpoint 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 polling is configured, async calls wait until the job reaches a terminal status.
  • If polling is not configured, async calls return the upload-completion/job response. Use client.jobs.get(job_id) or client.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.Path objects.
  • bytes or bytearray.
  • 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_balance after a transcription result
  • only calls POST /v1/add-funds when the balance is below if_balance_below
  • sends {"amount": amount, "if_balance_below": if_balance_below} to the API for backend-side protection too
  • ignores billing inside exclude so the SDK can always read remaining_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_received
  • upload_started
  • upload_progress
  • upload_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,000 files.
  • Batch local upload payloads support up to 10 GB total 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 MB and about 10 minutes.
  • Multipart upload starts when the backend returns multipart upload instructions. The SDK sends size_bytes for local files at least 128 MB so the backend can choose multipart.
  • uploadConcurrency defaults to 1 and is capped at 32.
  • polling["interval"] must be at least 10 seconds.
  • Batch local uploads support mp3, mpeg, mpga, m4a, wav, and webm.
  • .mp4 is 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

transcribe_api-0.1.10.tar.gz (25.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

transcribe_api-0.1.10-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

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

Hashes for transcribe_api-0.1.10.tar.gz
Algorithm Hash digest
SHA256 39d5fc86db26f63a7d0fc8fde85daf49a8881b83a30933b5e80c5d64db64c65e
MD5 1a9fbc3625967a6fffb4890ac7d88436
BLAKE2b-256 f4fdc4b7c8a95bc6ddf61cad849ecc9d70ed835ac4e5cfcd863c98165fd4613b

See more details on using hashes here.

File details

Details for the file transcribe_api-0.1.10-py3-none-any.whl.

File metadata

File hashes

Hashes for transcribe_api-0.1.10-py3-none-any.whl
Algorithm Hash digest
SHA256 21462ce8f9cc1346c959be4196a339f9521c14db25543fc032d4fd27a797ba2c
MD5 0c8f3d0a3f88f5b0b296c6e2db11b6dc
BLAKE2b-256 162e4d9aff640c29dd3f597da1e138ad8df811776056f854c00cb85a12139f6f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page