Description
When calling speech_to_text.convert() with a keyterms list where every term is well under 50 characters, the API returns a 400 invalid_keyword_length error. This is a regression introduced in v2.59.0.
The cause is in elevenlabs/speech_to_text/raw_client.py — the keyterms list is now wrapped in json.dumps() before being placed in the multipart form body:
"keyterms": json.dumps(jsonable_encoder(keyterms)),
This sends a single form field whose value is the full JSON array string (e.g. '["Example1", "Example2", "Example3"]'), rather than repeated individual fields. The API then validates that entire string against the 50-character limit and rejects it.
Steps to reproduce
from elevenlabs import ElevenLabs
client = ElevenLabs(api_key="...")
with open("audio.mp3", "rb") as f:
client.speech_to_text.convert(
file=f,
model_id="scribe_v2",
keyterms=["hello", "world"], # both well under 50 characters
)
Expected behavior
Each keyterm is sent as a separate repeated form field in the multipart body, as it was in v2.56.0:
keyterms=hello
keyterms=world
Actual behavior
The entire list is serialized as a JSON string and sent as a single field:
keyterms=["hello", "world"]
The API returns:
{
"type": "validation_error",
"code": "invalid_parameters",
"message": "All keywords must be less than 50 characters.",
"status": "invalid_keyword_length",
"param": "keywords"
}
Workaround: pin to elevenlabs==2.56.0.
Code example
No response
Additional context
No response
Description
When calling
speech_to_text.convert()with a keyterms list where every term is well under 50 characters, the API returns a 400 invalid_keyword_length error. This is a regression introduced in v2.59.0.The cause is in elevenlabs/speech_to_text/raw_client.py — the keyterms list is now wrapped in json.dumps() before being placed in the multipart form body:
"keyterms": json.dumps(jsonable_encoder(keyterms)),This sends a single form field whose value is the full JSON array string (e.g. '["Example1", "Example2", "Example3"]'), rather than repeated individual fields. The API then validates that entire string against the 50-character limit and rejects it.
Steps to reproduce
Expected behavior
Each keyterm is sent as a separate repeated form field in the multipart body, as it was in v2.56.0:
Actual behavior
The entire list is serialized as a JSON string and sent as a single field:
The API returns:
Workaround: pin to elevenlabs==2.56.0.
Code example
No response
Additional context
No response