Skip to main content

Official Python SDK for the Tuplets transcription API — submit jobs, poll results, direct uploads, diarization, PII redaction, and analytics.

Project description

Tuplets Python SDK

Official Python client for the Tuplets API — transcribe audio, run speaker diarization, apply PII redaction, and request structured analytics from Python 3.10+.

Installation

pip install tuplets-ai

Requires Python 3.10+. The only runtime dependency is httpx.

Quick start

Transcribe a local file, wait for completion, and print the transcript:

import os

from tuplets_ai import JobCreateParams, TupletsClient

client = TupletsClient(api_key=os.environ["TUPLETS_API_KEY"])

job = client.jobs.create_from_file(
    "interview.mp3",
    params=JobCreateParams(language="en"),
)

final_job = client.jobs.wait(job.id)

if final_job.status == "completed":
    transcript = client.jobs.download_result(job.id)
    print(transcript["text"])
elif final_job.status == "failed":
    print(final_job.error_message)

Authentication

Create an API key in the Tuplets dashboard (prefix tb_) and pass it when constructing the client:

client = TupletsClient(api_key="tb_your_api_key")

Every authenticated request sends Authorization: Bearer tb_....

Client configuration

import httpx

from tuplets_ai import TupletsClient

# Custom base URL (defaults to https://api.tuplets.ai)
client = TupletsClient(
    api_key="tb_your_api_key",
    base_url="https://api.tuplets.ai",
    timeout=120.0,
)

# Reuse your own httpx client (connection pooling, proxies, retries, etc.)
http = httpx.Client(base_url="https://api.tuplets.ai", timeout=120.0)
client = TupletsClient(api_key="tb_your_api_key", http_client=http)

with client:
    ...
# or explicitly:
client.close()

Use AsyncTupletsClient the same way with httpx.AsyncClient and async with.

Submitting transcription jobs

All job submission methods return a JobAccepted object with id, status_url, cancel_url, and cancel_token.

From a local file

job = client.jobs.create_from_file(
    "call.wav",
    params=JobCreateParams(language="en", transcription_model="premium"),
)

From bytes (in memory)

from pathlib import Path

audio = Path("call.wav").read_bytes()

job = client.jobs.create_from_bytes(
    filename="call.wav",
    data=audio,
    params=JobCreateParams(language="auto"),
)

From a remote URL

Tuplets fetches the audio from a publicly reachable URL:

job = client.jobs.create_from_url(
    "https://storage.example.com/recordings/call.mp3",
    params=JobCreateParams(language="en"),
)

From a direct upload

For large files, upload to object storage first, then reference the upload when creating the job (see Direct uploads).

job = client.jobs.create_from_uploaded_audio(
    object_key=upload.object_key,
    upload_token=upload.upload_token,
    params=JobCreateParams(language="en"),
)

Job parameters

Pass options via JobCreateParams:

Parameter Type Default Description
language str "auto" BCP-47 language code or "auto" for detection
transcription_model "standard" | "premium" "standard" Accuracy/latency tier
diarization bool False Speaker attribution; when enabled, jobs fail if diarization cannot be produced
pii_processing bool False Detect and redact personally identifiable information
analytics dict None Structured post-transcription analytics (see below)
params = JobCreateParams(
    language="en",
    transcription_model="premium",
    diarization=True,
    pii_processing=True,
)

Polling, waiting, and results

Poll manually

status = client.jobs.get(job.id)

print(status.status)                 # queued | running | completed | failed
print(status.progress_percent)       # 0–100 while running
print(status.estimated_seconds_remaining)
print(status.result)                 # inline preview when completed
print(status.error_message)          # set when status == "failed"

Wait until finished

wait() polls until the job reaches completed or failed:

final_job = client.jobs.wait(
    job.id,
    poll_interval=2.0,   # seconds between polls (default: 2)
    timeout=600.0,       # optional; raises WaitTimeoutError
)

Download the full transcript

transcript = client.jobs.download_result(job.id)
print(transcript["text"])
for segment in transcript.get("segments", []):
    print(segment["start"], segment["end"], segment["text"])

When diarization=True, segments include speaker labels. Completed jobs may also include an analytics object if analytics were requested.

List and cancel jobs

recent = client.jobs.list(status="completed", limit=20)
for item in recent.items:
    print(item.id, item.status, item.created_at)

client.jobs.cancel(job.id)

# Cancel without storing the job id (uses token from JobAccepted)
client.jobs.cancel_with_token(job.cancel_token)

Direct uploads

Upload large audio files to signed storage, then create a job from the upload reference:

from pathlib import Path

from tuplets_ai import JobCreateParams, TupletsClient

client = TupletsClient(api_key="tb_your_api_key")
file_path = Path("large-audio.wav")

upload = client.uploads.create_target(
    filename=file_path.name,
    size=file_path.stat().st_size,
    content_type="audio/wav",
)

client.uploads.upload_file(upload, file_path)

job = client.jobs.create_from_uploaded_audio(
    object_key=upload.object_key,
    upload_token=upload.upload_token,
    params=JobCreateParams(language="en", transcription_model="premium"),
)

create_target returns a BrowserUploadTarget with a pre-signed upload_url, required upload_headers, and an expiry (expires_in_seconds). Upload with upload_file / upload_bytes, or PUT the bytes yourself using the signed URL.

Analytics

Request generic and custom schema-bound analytics with JobCreateParams.analytics:

job = client.jobs.create_from_file(
    "insurance-call.mp3",
    params=JobCreateParams(
        language="en",
        analytics={
            "profile": "full",
            "domain": "insurance",
            "schema": {
                "fields": [
                    {
                        "key": "call_reason",
                        "label": "Reason for call",
                        "type": "single_select",
                        "options": [
                            {"id": 1, "code": "CLAIM_STATUS", "label": "Claim status"},
                            {"id": 2, "code": "BILLING", "label": "Billing question"},
                        ],
                    }
                ]
            },
        },
    ),
)

final_job = client.jobs.wait(job.id)
if final_job.analytics:
    print(final_job.analytics["custom"]["fields"])

See tuplets.ai/docs for supported profiles, domains, and schema field types.

Async usage

The async client mirrors the sync API:

from tuplets_ai import AsyncTupletsClient, JobCreateParams

async def main() -> None:
    async with AsyncTupletsClient(api_key="tb_your_api_key") as client:
        job = await client.jobs.create_from_url(
            "https://storage.example.com/call.mp3",
            params=JobCreateParams(language="en", pii_processing=True),
        )
        final_job = await client.jobs.wait(job.id)
        if final_job.status == "completed":
            transcript = await client.jobs.download_result(job.id)
            print(transcript["text"])
        elif final_job.status == "failed":
            print(final_job.error_message)

Error handling

API failures raise typed exceptions with status_code and optional response_body:

Exception HTTP status
ValidationError 400
AuthenticationError 401
PaymentRequiredError 402
PermissionDeniedError 403
NotFoundError 404
ConflictError 409
GoneError 410
RateLimitError 429
APIStatusError other 4xx/5xx
WaitTimeoutError polling timeout (not an HTTP error)
from tuplets_ai import AuthenticationError, RateLimitError, TupletsClient

client = TupletsClient(api_key="tb_your_api_key")

try:
    client.jobs.get("job_unknown")
except AuthenticationError as exc:
    print(exc.status_code, exc.message)
except RateLimitError:
    ...

API surface

Resource Methods
client.jobs create_from_file, create_from_bytes, create_from_url, create_from_uploaded_audio, get, list, wait, cancel, cancel_with_token, download_result
client.uploads create_target, upload_file, upload_bytes
client.solutions create_inquiry (public enterprise inquiries; no API key required)

Exported types

JobCreateParams, JobAccepted, JobStatus, JobList, BrowserUploadTarget, UploadedAudioReference, SolutionsInquiryRequest, SolutionsInquirySubmission, and the exception classes above are exported from the top-level tuplets_ai package.

Support

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

tuplets_ai-0.3.0.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

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

tuplets_ai-0.3.0-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file tuplets_ai-0.3.0.tar.gz.

File metadata

  • Download URL: tuplets_ai-0.3.0.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for tuplets_ai-0.3.0.tar.gz
Algorithm Hash digest
SHA256 e872ca5a5e2771fd1243b50f8fa884003f22275c5e15b5eab69d15403eb93f5e
MD5 d49d1766611545dce8cc8de9e6c3caee
BLAKE2b-256 a8169d487a2f51c1465c1fef498aae80abd37ec8d914b3b72f3f47acba25adbe

See more details on using hashes here.

File details

Details for the file tuplets_ai-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: tuplets_ai-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 12.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for tuplets_ai-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 28f438b4f9634af8c303bb8e28f4ad6a315c22a4eaa2c69d2e37dc9f8b797f65
MD5 d62d47d8443e82ec6b6c7f37f6ca8986
BLAKE2b-256 3627729999b02d5cb0f2cf457833a3596c6a68bc3f478abbe6c7fb9823280fd0

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