Skip to main content
Sync STT is a single request/response: your application sends audio to /transcribe and gets the transcript back in the same HTTP exchange. That makes connection setup part of your latency budget — if the HTTPS connection isn’t open yet, the very first thing your request does is negotiate one, and your audio doesn’t start uploading until that negotiation finishes. The GET /warm endpoint exists to take that setup off the critical path. Calling it as soon as you know audio is coming — typically the moment recording starts — establishes the connection in the background, so the eventual /transcribe request starts uploading audio immediately.

What a cold request pays for

Before an HTTPS client can send the first byte of a request to a host it isn’t connected to, three things happen in sequence:
  1. DNS resolution — the client resolves sync.assemblyai.com to an IP address. Usually fast (often cached), but a cold resolver lookup adds a round trip of its own.
  2. TCP handshake — the client and server exchange SYN / SYN-ACK / ACK to open the socket. This costs one network round trip.
  3. TLS handshake — the encrypted session is negotiated on top of the socket. The client sends a ClientHello with its supported cipher suites and key share; the server responds with its certificate and its own key share; the client verifies the certificate chain and both sides derive the session keys. On TLS 1.3 this costs one additional round trip (TLS 1.2 needs two).
Only after all three complete does the actual POST /transcribe — headers, then audio — go on the wire. None of this work depends on your audio; it’s pure connection plumbing, but it sits in front of every cold request. The cost scales directly with your network distance to the endpoint: each step is measured in round trips, so the farther you are from the serving region, the more the handshake costs. For a client near the serving region the total is typically a few tens of milliseconds; for a distant or intercontinental client it can add well over 100 ms — a meaningful fraction of the transcription itself for short clips.

How /warm works

GET /warm is an unauthenticated no-op:
The response body is irrelevant — the value of the call is entirely on the wire. Making any request forces your HTTP client to resolve DNS, open the TCP socket, and complete the TLS handshake. The resulting connection goes into your client’s connection pool, and a /transcribe request sent shortly afterward through the same client reuses it as-is: no DNS, no TCP handshake, no TLS handshake — the request headers and audio bytes start flowing immediately. Include the same X-AAI-Model header you’ll use for transcription, so the warmed path matches the one your /transcribe request will take. No API key is required.

Why “right before” matters

Pooled connections don’t live forever:
  • Client-side pool expiry — HTTP clients evict idle connections from their pool, some aggressively (for example, httpx drops idle connections after 5 seconds by default).
  • Server-side idle timeout — the endpoint closes connections that stay idle for a few minutes.
If the connection has been evicted or closed by the time you call /transcribe, the request silently opens a fresh one and pays the full handshake anyway — the warm-up bought nothing. So the ideal moment to call /warm is when you know audio is coming but don’t have it yet — in a voice application, that’s the moment the user starts speaking. The handshake then runs concurrently with recording, and by the time the utterance ends the connection is open and fresh. /warm is idempotent and extremely cheap, so calling it again to refresh an aging connection is fine.
Pre-warming only helps if the /warm and /transcribe requests share a connection pool. Use the same client object (a requests.Session in Python, the same process in Node.js) for both calls, and the same base URL — a connection warmed against one endpoint doesn’t help a request sent to another.

How to use it

The Python SDK exposes this directly as SyncTranscriber.warm() — call it when recording starts, then call transcribe() as usual on the same transcriber.