Environment
gladiaio-sdk (Python) 1.0.3 and 1.0.4 (latest) — both affected
- Python 3.13
- Region:
eu-west
Summary
When a GladiaClient is constructed with region=..., the pre-recorded (async) flow via create() + result_url is broken: the result_url returned by POST /v2/pre-recorded is malformed, and following it fails with 400 Bad Request.
Cause chain:
pre_recorded_v2() builds an HttpClient whose default query params include region, which is attached to every request — including POST /v2/pre-recorded (v2/prerecorded/client.py, network/http_client.py).
- The API appears to construct
result_url from the request URL, so the job id is appended after the query string:
https://api.gladia.io/v2/pre-recorded?region=eu-west/{id} — malformed.
- Any consumer that follows
result_url (the documented REST contract for async jobs) gets 400.
The SDK's own poll()/transcribe() mask the bug because they rebuild the poll URL from the job id ({base}/v2/pre-recorded/{id}) instead of using result_url — so this bites exactly the users driving the async flow manually via create() + result_url (e.g. storing result_url and polling from another worker).
Steps to reproduce
import os
import httpx
import gladiaio_sdk as gladia
API_KEY = os.environ["GLADIA_API_KEY"]
AUDIO = "http://files.gladia.io/example/audio-transcription/split_infinity.wav"
print("=== WITH region='eu-west' ===")
client = gladia.GladiaClient(api_key=API_KEY, region="eu-west")
prerecorded = client.pre_recorded_v2()
init = prerecorded.create({"audio_url": AUDIO})
print("result_url:", init.result_url)
resp = httpx.get(init.result_url, headers={"x-gladia-key": API_KEY})
print("GET result_url ->", resp.status_code)
print("=== CONTROL: no region ===")
client2 = gladia.GladiaClient(api_key=API_KEY)
init2 = client2.pre_recorded_v2().create({"audio_url": AUDIO})
print("result_url:", init2.result_url)
resp2 = httpx.get(init2.result_url, headers={"x-gladia-key": API_KEY})
print("GET result_url ->", resp2.status_code)
Actual output (live, 2026-07-16, sdk 1.0.3):
=== WITH region='eu-west' ===
result_url: https://api.gladia.io/v2/pre-recorded?region=eu-west/f4c62e54-d1cd-4a65-bb87-0c1681a36391
GET result_url -> 400
=== CONTROL: no region ===
result_url: https://api.gladia.io/v2/pre-recorded/1c574c82-ba8c-4ebb-8de2-56d0d3fd18a9
GET result_url -> 200
Expected
result_url should be a valid, pollable URL regardless of region, e.g.
https://api.gladia.io/v2/pre-recorded/{id}?region=eu-west (or without the param).
Impact / workaround
- Consumers following
result_url from the create response fail with 400 whenever region is set.
- Workaround: ignore
result_url and poll {base}/v2/pre-recorded/{id} built from id (what the SDK's poll() does internally).
- Fix could be server-side (build
result_url from the path only, placing query params after the id) and/or SDK-side (don't attach the default region query param in a way that ends up reflected into result_url).
Related note: silent auth behavior change 0.4.0 → 1.0.x
In 0.4.0, GladiaClient(api_key=...).options.http_headers contained the auth header, and downstream code could reuse it for raw HTTP calls. Since 1.0.x it is always {} — x-gladia-key is injected only per-request inside _merge_options(). Code that read options.http_headers now silently sends unauthenticated requests (401). If this is intended, a changelog note would help; we lost a few hours to the combination of that 401 and the malformed result_url above.
Happy to provide more details or test a fix.
Environment
gladiaio-sdk(Python) 1.0.3 and 1.0.4 (latest) — both affectedeu-westSummary
When a
GladiaClientis constructed withregion=..., the pre-recorded (async) flow viacreate()+result_urlis broken: theresult_urlreturned byPOST /v2/pre-recordedis malformed, and following it fails with 400 Bad Request.Cause chain:
pre_recorded_v2()builds anHttpClientwhose default query params includeregion, which is attached to every request — includingPOST /v2/pre-recorded(v2/prerecorded/client.py,network/http_client.py).result_urlfrom the request URL, so the job id is appended after the query string:https://api.gladia.io/v2/pre-recorded?region=eu-west/{id}— malformed.result_url(the documented REST contract for async jobs) gets 400.The SDK's own
poll()/transcribe()mask the bug because they rebuild the poll URL from the jobid({base}/v2/pre-recorded/{id}) instead of usingresult_url— so this bites exactly the users driving the async flow manually viacreate()+result_url(e.g. storingresult_urland polling from another worker).Steps to reproduce
Actual output (live, 2026-07-16, sdk 1.0.3):
Expected
result_urlshould be a valid, pollable URL regardless of region, e.g.https://api.gladia.io/v2/pre-recorded/{id}?region=eu-west(or without the param).Impact / workaround
result_urlfrom the create response fail with 400 wheneverregionis set.result_urland poll{base}/v2/pre-recorded/{id}built fromid(what the SDK'spoll()does internally).result_urlfrom the path only, placing query params after the id) and/or SDK-side (don't attach the defaultregionquery param in a way that ends up reflected intoresult_url).Related note: silent auth behavior change 0.4.0 → 1.0.x
In 0.4.0,
GladiaClient(api_key=...).options.http_headerscontained the auth header, and downstream code could reuse it for raw HTTP calls. Since 1.0.x it is always{}—x-gladia-keyis injected only per-request inside_merge_options(). Code that readoptions.http_headersnow silently sends unauthenticated requests (401). If this is intended, a changelog note would help; we lost a few hours to the combination of that 401 and the malformedresult_urlabove.Happy to provide more details or test a fix.