Using Speech Revolutions with Amazon S3

Already storing audio in S3? You don't need to download it first. Presign a short-lived GET URL for the object, hand that URL to Speech Revolutions, and write the JSON transcript straight back to a bucket. Everything runs server-side, so your AWS credentials and Speech Revolutions API key never leave your backend.

Why presign instead of making the object public

A presigned GET URL grants Speech Revolutions time-limited read access to one object without opening the bucket to the world. Give it a lifetime comfortably longer than your largest file's transcription time, then let it expire.

Transcribe an object already in S3

Presign a GET for the source object and pass the URL to Speech Revolutions — the SDK auto-detects http(s) URLs, so transcribe() streams the audio directly from S3. Then serialize result.to_dict() / result.toDict() and PutObject it back to your output bucket.

import json

import boto3
from speechrevolutions import SpeechRevolutions

s3 = boto3.client("s3")
client = SpeechRevolutions()  # SPEECHREVOLUTIONS_API_KEY

SRC_BUCKET = "my-audio"
OUT_BUCKET = "my-transcripts"


def transcribe_s3_object(key: str) -> str:
    # 1. Presign a short-lived GET so Speech Revolutions can read the object.
    audio_url = s3.generate_presigned_url(
        "get_object",
        Params={"Bucket": SRC_BUCKET, "Key": key},
        ExpiresIn=3600,  # seconds — outlast the transcription
    )

    # 2. Pass the URL straight to Speech Revolutions (auto-detected as a URL).
    result = client.transcribe(audio_url, speaker_labels=True)

    # 3. Store the JSON result back to S3.
    out_key = key.rsplit(".", 1)[0] + ".json"
    s3.put_object(
        Bucket=OUT_BUCKET,
        Key=out_key,
        Body=json.dumps(result.to_dict()).encode(),
        ContentType="application/json",
    )
    return out_key

Long files: submit() + a webhook

For large recordings, don't block on transcribe(). Presign the GET, call submit() with a callback_url, and store the result to S3 from your webhook handler once the job completes.

audio_url = s3.generate_presigned_url(
    "get_object",
    Params={"Bucket": SRC_BUCKET, "Key": key},
    ExpiresIn=3600,
)

job_id = client.submit(
    audio_url,
    speaker_labels=True,
    callback_url="https://you.example.com/webhooks/stt",
)
# In the webhook handler (after verifying X-SR-Signature):
#   result = client.get_transcript(event["job_id"])
#   s3.put_object(Bucket=OUT_BUCKET, Key=out_key,
#                 Body=json.dumps(result.to_dict()).encode())

Verify the webhook signature

The completion POST is signed with HMAC-SHA256 in the X-SR-Signature: sha256=<hex> header — always verify it against the raw request bytes before trusting download_url. The FastAPI and Next.js guides show complete receivers.

Passing a URL lets Speech Revolutions fetch the audio directly; the SDK then waits on the SSE job stream and parses the result. See the Python and JavaScript SDK pages for the full option and result surface.