Skip to content
Get API key API key

Errors and reliability

Retry a failed call when the status is temporary. Error codes lists every status. Queued requests wait for rate-limit budget instead of returning 429 immediately.

On HTTP 429, wait 2 ** attempt seconds and try again. Stop after 3 attempts. The model id is gpt-oss-120b.

Python
import time
from openai import OpenAI, RateLimitError
client = OpenAI()
def call_with_retry(messages, max_retries=3):
for attempt in range(max_retries):
try:
return client.chat.completions.create(
model="gpt-oss-120b",
messages=messages,
)
except RateLimitError:
if attempt == max_retries - 1:
raise
wait = 2 ** attempt
print(f"Rate limited. Retrying in {wait}s...")
time.sleep(wait)

On 429 the function waits and tries again. On the third failure it re-raises the RateLimitError.

max_retries is 3. The wait is 2 ** attempt seconds (1s, then 2s).

  • 429 means the rate limit was exceeded. Wait and retry with exponential backoff, or use queued requests.
  • 500 is a server-side error. Retry after a brief delay.
  • 503 means the model is temporarily unavailable. Check model status and retry.
  • 400, 401, 403, and 404 are request or credential errors. Retrying the same request will not succeed. See Error codes.

When a queued request is still over the limit after two minutes, the 429 carries a Retry-After header. See Queued requests.

The /queue endpoints work like the /v2 endpoints, with one difference: when you are over your rate limit, /v2 returns 429 Too Many Requests right away, while /queue waits up to two minutes for your limit to free up and then runs the request.

  • Within your limit: the request runs immediately.
  • Over your limit: the request waits. Limits reset every minute, so it is checked again at the start of each minute.
  • Still over your limit after two minutes: the wait is capped. The request stops waiting and you get 429 Too Many Requests with a Retry-After header telling you how many seconds to wait before retrying. The body says Queue wait limit of 120 seconds reached. The cap exists so that a starved project gets a clear answer instead of an opaque 504 Gateway Timeout from the network layer.

The cap is measured against the calendar minute, not from the moment your request arrives: the request is checked when it arrives and again at the next two minute resets, and gives up after the second one. So the actual wait is between one and two minutes, depending on when in the minute you sent the request.

Set your client timeout to at least two minutes plus the expected response time, otherwise your client may give up before the queue does. If you close the connection while waiting, the request is cancelled.

A 429 from /queue means you are sending more than your limit allows, not just a short burst. A single request with more input tokens than your per-minute token limit never fits and always times out after two minutes. Slow down, or ask for a higher limit.

  • Use /queue for batch jobs that sometimes go over the limit, so short bursts wait instead of failing.
  • Use /v2 for interactive apps, where an immediate 429 is better than waiting, and for long-running requests (use streaming).

Every standard endpoint has a /queue equivalent:

Standard EndpointQueue EndpointDescription
POST /v2/chat/completionsPOST /queue/chat/completionsChat completion
POST /v2/completionsPOST /queue/completionsText completion (/v2/completions is not available on this host at the moment; see API endpoints)
POST /v2/embeddingsPOST /queue/embeddingsEmbeddings
POST /v2/audio/transcriptionsPOST /queue/audio/transcriptionsAudio transcription
POST /v2/audio/translationsPOST /queue/audio/translationsAudio translation
POST /v2/images/generationsPOST /queue/images/generationsImage generation
POST /v2/images/editsPOST /queue/images/editsImage editing
GET /v2/modelsGET /queue/modelsList models

The request body for each queue endpoint is identical to its standard counterpart — just change the base path from /v2 to /queue.

Submit a chat completion to the queue:

Terminal
curl -X POST "https://llm-server.llmhub.t-systems.net/queue/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-oss-120b",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a detailed analysis of renewable energy trends in Europe."}
],
"max_tokens": 2000
}'

Process multiple prompts efficiently using the queue:

import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI(
base_url="https://llm-server.llmhub.t-systems.net/queue",
)
prompts = [
"Summarize the benefits of solar energy.",
"Explain how wind turbines generate electricity.",
"Describe the future of hydrogen fuel cells.",
]
async def process_prompt(prompt):
response = await client.chat.completions.create(
model="gpt-oss-120b",
messages=[{"role": "user", "content": prompt}],
max_tokens=500,
)
return response.choices[0].message.content
async def main():
tasks = [process_prompt(p) for p in prompts]
results = await asyncio.gather(*tasks)
for prompt, result in zip(prompts, results):
print(f"Prompt: {prompt[:50]}...")
print(f"Result: {result[:100]}...\n")
asyncio.run(main())
Python
from openai import OpenAI
client = OpenAI(
base_url="https://llm-server.llmhub.t-systems.net/queue",
)
response = client.embeddings.create(
model="text-embedding-bge-m3",
input="The benefits of renewable energy in Europe",
)
print(f"Embedding dimension: {len(response.data[0].embedding)}")
Python
from openai import OpenAI
client = OpenAI(
base_url="https://llm-server.llmhub.t-systems.net/queue",
)
with open("meeting_recording.mp3", "rb") as audio_file:
transcript = client.audio.transcriptions.create(
model="whisper-large-v3",
file=audio_file,
)
print(transcript.text)
Python
from openai import OpenAI
client = OpenAI(
base_url="https://llm-server.llmhub.t-systems.net/queue",
)
result = client.images.generate(
model="gpt-image-2",
prompt="A futuristic data center powered by renewable energy",
)
print(result.data[0].b64_json[:50] + "...")