NeuVerbinde jeden Agenten mit UberLLM: ein Schlüssel, alle Modelle, zum Listenpreis oder günstiger.
UberLLM

Responses API

POST https://api.uberllm.dev/v1/responses stellt OpenAI's Responses API für jedes Chat-Modell im Katalog bereit. Nutzen Sie es über das OpenAI SDK (client.responses.create), Codex CLI, oder jede App mit einem "Responses"-Modus. Anfragen durchlaufen dasselbe Routing, dieselben Retries, Key limits und dieselbe Abrechnung wie /v1/chat/completions, und jeder Aufruf wird in Dashboard → Activity mit seinen Kosten aufgeführt.

curl https://api.uberllm.dev/v1/responses \
  -H "Authorization: Bearer $UBERLLM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4.1-flash",
    "instructions": "Answer in one short sentence.",
    "input": "What is the capital of France?"
  }'
from openai import OpenAI

client = OpenAI(base_url="https://api.uberllm.dev/v1", api_key="ull_...")
r = client.responses.create(model="deepseek/deepseek-v4.1-flash", input="Say hi")
print(r.output_text)

Kein gespeicherter Zustand

UberLLM speichert keine Antworten, damit Sie später darauf aufbauen können. Jede Antwort hat "store": false, und Sie senden die gesamte Konversation in input bei jedem Aufruf: frühere Benutzernachrichten, die Ausgaben des Modells und Ihre Tool-Ergebnisse. Codex CLI funktioniert bereits auf diese Weise.

Diese werden mit einem 400 (code: unsupported_parameter) abgelehnt, das das Feld benennt:

  • previous_response_id und conversation
  • background: true
  • Eingabeelemente vom Typ item_reference
  • gespeicherte Prompt-Templates (prompt)

GET /v1/responses/{id} und die anderen Routen für gespeicherte Antworten existieren nicht.

Anfrage

Feld Was passiert
model Jede Chat-Modell-ID, jeder Alias oder :floor / :nitro Suffix, wie bei Chat-Completions.
input Ein String oder eine Liste von Elementen (siehe unten).
instructions Wird als Systemnachricht an das Modell gesendet.
stream true für Server-Sent Events.
max_output_tokens Die Ausgabebegrenzung.
temperature, top_p, seed, stop Werden an das Modell übergeben.
tools, tool_choice, parallel_tool_calls Siehe Tools unten.
reasoning.effort Wird als Denkaufwand des Modells (Modelle, die denken) weitergegeben.
text.format text, json_object oder json_schema (strukturierte Ausgabe).
metadata Ihre eigenen Tags, die in der Aktivitätszeile angezeigt werden, wie bei Chat-Completions.
provider, models UberLLM Routing-Optionen, wie bei Chat-Completions (Modelle & Routing).
store, include, prompt_cache_key, service_tier, truncation Akzeptiert und nicht verwendet. Verschlüsselte Denkprozesse werden immer zurückgegeben.

Eingabeelemente

Element Wird zu
message mit Rolle user, assistant, system oder developer Eine Chat-Nachricht. developer wird als system gesendet. Inhaltsteile input_text, output_text, input_image (image_url: eine https- oder data: URL) und input_file (file_data oder file_url).
function_call Der Tool-Aufruf des Assistenten, in der richtigen Reihenfolge beibehalten.
function_call_output Das Ergebnis des Tools. Bilder in einer Ausgabe werden im nächsten Benutzerzug gesendet.
custom_tool_call, custom_tool_call_output Ein Aufruf an ein benutzerdefiniertes (Freiform-) Tool und dessen Ergebnis.
reasoning Die frühere Denkweise des Modells, die dem Modell im nächsten Zug zurückgegeben wird.
web_search_call und andere Hosted-Tool-Einträge Übersprungen.

Element ids werden akzeptiert und ignoriert. file_id (hochgeladene Dateien) wird in input_image / input_file nicht unterstützt: Senden Sie die Datei inline oder per URL.

Tools

  • function: {"type": "function", "name", "description", "parameters", "strict"}. Der Aufruf des Modells kommt als function_call Element mit call_id, name und arguments (einem JSON-String) zurück. Antworten Sie mit einem function_call_output Element, das dieselbe call_id trägt.
  • custom (Freiform-Eingabe, wie z.B. Codex's apply_patch): dem Modell wird das Tool mit einer String-Eingabe und die Grammatik in format.definition als dessen Beschreibung gegeben. Der Aufruf kommt als custom_tool_call Element mit dem rohen input zurück.
  • namespace (Codex's MCP Tools): jedes darin enthaltene Tool wird dem Modell unter seinem Namespace und Namen zusammengefügt (mcp__github__get_issue) angeboten; der Aufruf kommt zurück, wobei name und namespace wieder getrennt sind.
  • Gehostete Tools (web_search, file_search, code_interpreter, image_generation, computer_use, mcp) laufen auf OpenAIs eigenen Servern. Sie werden aus der Anfrage weggelassen und das Modell antwortet ohne sie.

tool_choice akzeptiert "auto", "none", "required" oder {"type": "function", "name": "…"}.

Antwort

{
  "id": "resp_…",
  "object": "response",
  "created_at": 1793333237,
  "status": "completed",
  "model": "deepseek/deepseek-v4.1-flash",
  "output": [
    {"type": "reasoning", "id": "rs_…", "summary": [],
     "content": [{"type": "reasoning_text", "text": "…"}], "encrypted_content": "ull1:…"},
    {"type": "message", "id": "msg_…", "status": "completed", "role": "assistant",
     "content": [{"type": "output_text", "text": "Paris.", "annotations": []}]},
    {"type": "function_call", "id": "fc_…", "status": "completed",
     "call_id": "call_…", "name": "get_weather", "arguments": "{\"city\":\"Paris\"}"}
  ],
  "usage": {
    "input_tokens": 43, "input_tokens_details": {"cached_tokens": 0},
    "output_tokens": 23, "output_tokens_details": {"reasoning_tokens": 0},
    "total_tokens": 66, "cost_usd": 0.0000184
  },
  "store": false
}
  • Ein reasoning Element erscheint, wenn das Modell seine Begründung zurückgibt. Senden Sie es im nächsten input wie es ist zurück: encrypted_content enthält die Begründung, damit Modelle, die sie in der nächsten Runde benötigen, sie erhalten.
  • status ist incomplete, wenn die Antwort auf max_output_tokens (incomplete_details.reason: "max_output_tokens") oder einen content filter ("content_filter") gestoßen ist.
  • usage.cost_usd ist das, was für den Aufruf abgerechnet wurde. Nicht-streaming-Antworten enthalten es auch im X-UberLLM-Cost-USD header, und jede Antwort hat X-Request-Id, die ID ihrer Activity-Zeile.
  • Die von Ihnen gesendeten Einstellungen (instructions, tools, temperature, max_output_tokens…) werden zurückgespiegelt, wie es OpenAI tut.

Streaming

Mit "stream": true ist die Antwort Server-Sent Events, jeweils mit type und einem sequence_number, beginnend bei 0:

  1. response.created, response.in_progress
  2. Für jedes Ausgabeelement: response.output_item.added, dann seine Deltas, dann response.output_item.done mit dem fertigen Element:
    • text: response.content_part.added, response.output_text.delta…, response.output_text.done, response.content_part.done
    • reasoning: response.reasoning_text.delta…, response.reasoning_text.done
    • function call: response.function_call_arguments.delta…, response.function_call_arguments.done
    • custom tool call: response.custom_tool_call_input.done
  3. response.completed (oder response.incomplete) mit der gesamten Antwort und ihren usage, einschließlich cost_usd.

Während ein langsames Modell startet, halten : ping Kommentarzeilen die Verbindung offen. Jeder SSE-Client überspringt sie.

Fehler

Eine Anfrage, die abgelehnt wird, bevor der stream beginnt, erhält einen HTTP status und OpenAIs error envelope, genau wie bei chat completions (401, 402 kein Guthaben, 404 unbekanntes model, 429; siehe Fehler). Wenn etwas fehlschlägt, nachdem der stream begonnen hat, endet es mit response.failed, dessen response.error code und message enthält. Ein stream, der stoppt, bevor das model fertig ist, endet ebenfalls mit response.failed, niemals mit response.completed, damit clients es erneut versuchen, anstatt eine halbe Antwort zu behalten.