Soniox
SDKsPython

Handling webhooks with Python SDK

Use webhooks to receive transcription results with the Soniox Python SDK

Python SDK provides helper functions to work with Webhooks.

Configure webhook delivery

If webhook is enabled during transcription creation, Soniox will send a POST request to your webhook URL with the transcription status result.

from soniox import SonioxClient
from soniox.types import CreateTranscriptionConfig

client = SonioxClient()

config = CreateTranscriptionConfig(
    webhook_url="https://your-server.com/webhooks/soniox",
    webhook_auth_header_name="X-Webhook-Secret",
    webhook_auth_header_value="your-secret",
)

transcription = client.stt.transcribe(
    audio_url="https://soniox.com/media/examples/coffee_shop.mp3",
    config=config,
)

For transcribe, you must pass webhook_auth_header_name and webhook_auth_header_value explicitly in the config. Environment variables (SONIOX_API_WEBHOOK_HEADER and SONIOX_API_WEBHOOK_SECRET) are only used by webhook helpers and verification (see below).

You can also append additional metadata as query parameters:

config = CreateTranscriptionConfig(
    webhook_url="https://your-server.com/webhooks/soniox?request_id=abc-123",
)

If you are uploading a local file, you can also use the convenience helper (reads webhook secret and header automatically from environment if present):

from soniox import SonioxClient
from soniox.types import WebhookAuthConfig

client = SonioxClient()

transcription = client.stt.transcribe_file_with_webhook(
    model="stt-async-v4",
    file="audio.mp3",
    webhook_url="https://your-server.com/webhooks/soniox",
)

Example (FastAPI + ngrok)

Expose your local server (for example with ngrok), then create a transcription that points to the public ngrok URL and verify the webhook payload on your FastAPI server:

from fastapi import FastAPI, Request
from soniox import SonioxClient
from soniox.errors import InvalidWebhookSignatureError
from soniox.types import CreateTranscriptionConfig, WebhookAuthConfig

app = FastAPI()
client = SonioxClient()

# Replace with your public ngrok URL.
NGROK_URL = "https://your-subdomain.ngrok-free.app"
WEBHOOK_SECRET_NAME = "X-Webhook-Secret"
WEBHOOK_SECRET_VALUE = "your-secret"

# When creating transcript you must provide correct webhook secret name and value
# config = CreateTranscriptionConfig(
#     webhook_url=f"{NGROK_URL}/webhooks/soniox",
#     webhook_auth_header_name=WEBHOOK_SECRET_NAME,
#     webhook_auth_header_value=WEBHOOK_SECRET_VALUE,
# )
# client.stt.transcribe(
#     model="stt-async-v4",
#     audio_url="https://soniox.com/media/examples/coffee_shop.mp3",
#     config=config,
# )

@app.post("/webhooks/soniox")
async def soniox_webhook(request: Request):
    payload = await request.body()
    headers = dict(request.headers)

    try:
        event = client.webhooks.unwrap(
            payload, 
            headers,
            # This can be omitted if you have set env variables SONOIX_API_WEBHOOK_SECRET and SONIOX_API_WEBHOOK_HEADER
            auth=WebhookAuthConfig(
                name=WEBHOOK_SECRET_NAME,
                value=WEBHOOK_SECRET_VALUE,
            ),
        )
    except InvalidWebhookSignatureError:
        print("InvalidWebhookSignatureError")
        return

    if event.status == "completed":
        transcript = client.stt.get_transcript(event.id)
        print(transcript.text)

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8080)

Webhook verification

Verify webhook signatures to ensure the request really came from Soniox (and not a third party posting to your endpoint).

You can verify signatures manually:

from soniox import SonioxClient
from soniox.types import WebhookAuthConfig

client = SonioxClient()

client.webhooks.verify_signature(
    headers={"X-Webhook-Secret": "your-secret"},
)

Or rely on unwrap to validate and parse in one step:

from soniox import SonioxClient
from soniox.types import WebhookAuthConfig

client = SonioxClient()

event = client.webhooks.unwrap(
    payload=request_body,
    headers={"X-Webhook-Secret": "your-secret"},
)
print(event.id, event.status)

If you prefer, you can also use client.stt.transcribe_file_with_webhook and client.webhooks with SONIOX_API_WEBHOOK_HEADER and SONIOX_API_WEBHOOK_SECRET set in your environment.