응답 API
POST https://api.uberllm.dev/v1/responses는 카탈로그에 있는 모든 챗 모델에서 OpenAI의 응답 API를 제공합니다. OpenAI SDK (client.responses.create), Codex CLI 또는 "Responses" 모드가 있는 모든 앱에서 이를 사용할 수 있습니다. 요청은 /v1/chat/completions와 동일한 라우팅, 재시도, 키 제한 및 청구 과정을 거치며, 각 호출은 비용과 함께 대시보드 → 활동에 표시됩니다.
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)
저장된 상태 없음
UberLLM은 나중에 이어서 사용할 수 있도록 응답을 저장하지 않습니다. 모든 응답에는 "store": false이(가) 있으며, 각 호출 시 input에 이전 사용자 메시지, 모델의 출력 항목, 그리고 도구 결과를 포함한 전체 대화를 보냅니다. Codex CLI는 이미 이런 방식으로 작동합니다.
다음 항목들은 필드 이름을 명시하는 400 (code: unsupported_parameter) 오류와 함께 거부됩니다:
previous_response_id및conversationbackground: trueitem_reference유형의 입력 항목- 저장된 프롬프트 템플릿 (
prompt)
GET /v1/responses/{id} 및 다른 저장된 응답 경로는 존재하지 않습니다.
요청
| 필드 | 설명 |
|---|---|
model |
모든 채팅 모델 ID, 별칭 또는 :floor / :nitro 접미사 (chat completions과 동일하게). |
input |
문자열 또는 항목 목록 (아래 참조). |
instructions |
system message로 모델에 전송됩니다. |
stream |
server-sent events를 위한 true. |
max_output_tokens |
출력 제한. |
temperature, top_p, seed, stop |
모델에 전달됩니다. |
tools, tool_choice, parallel_tool_calls |
아래 도구(Tools)를 참조하세요. |
reasoning.effort |
모델의 추론 노력으로 전달됩니다 (생각하는 모델). |
text.format |
text, json_object 또는 json_schema (구조화된 출력). |
metadata |
활동(Activity) 행에 표시되는 사용자 지정 태그 (chat completions과 동일하게). |
provider, models |
UberLLM routing options (chat completions과 동일하게) (모델 및 라우팅). |
store, include, prompt_cache_key, service_tier, truncation |
허용되지만 사용되지 않습니다. 암호화된 추론은 항상 반환됩니다. |
입력 항목
| 항목 | 변환 |
|---|---|
역할(role)이 user, assistant, system 또는 developer인 message |
채팅 메시지. developer은 system로 전송됩니다. 콘텐츠 부분 input_text, output_text, input_image (image_url: HTTPS 또는 data: URL) 및 input_file (file_data 또는 file_url). |
function_call |
순서대로 유지되는 어시스턴트의 tool call. |
function_call_output |
도구의 결과. 출력의 이미지는 다음 사용자 턴에 전송됩니다. |
custom_tool_call, custom_tool_call_output |
사용자 지정 (자유 형식) 도구 호출 및 그 결과. |
reasoning |
모델의 이전 추론으로, 다음 턴에 모델에 다시 제공됩니다. |
web_search_call 및 기타 hosted-tool records |
건너뜁니다. |
항목 id는 허용되지만 무시됩니다. file_id (업로드된 파일)은 input_image / input_file에서 지원되지 않습니다. 파일을 inline으로 또는 URL로 전송하세요.
도구
function:{"type": "function", "name", "description", "parameters", "strict"}. 모델 호출 결과는call_id,name및arguments(JSON 문자열)를 포함하는function_call항목으로 돌아옵니다. 동일한call_id을(를) 포함하는function_call_output항목으로 응답하세요.custom(Codex의apply_patch와 같은 자유 형식 입력): 모델에는 하나의 문자열 입력과 함께 도구가 제공되며,format.definition에 있는 문법이 해당 설명으로 제공됩니다. 호출 결과는 원시input를 포함하는custom_tool_call항목으로 돌아옵니다.namespace(Codex의 MCP 도구): 내부의 각 도구는 네임스페이스와 이름이 결합된 형태(mcp__github__get_issue)로 모델에 제공되며, 호출 결과는name와namespace이 다시 분할된 상태로 돌아옵니다.- 호스팅된 도구 (
web_search,file_search,code_interpreter,image_generation,computer_use,mcp)는 OpenAI 자체 서버에서 실행됩니다. 이들은 요청에서 제외되며 모델은 이들 없이 응답합니다.
tool_choice은(는) "auto", "none", "required" 또는 {"type": "function", "name": "…"}을(를) 받습니다.
응답
{
"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
}
- 모델이 추론을 반환할 때
reasoning항목이 나타납니다. 다음input에 그대로 다시 보내세요:encrypted_content는 추론을 담고 있으므로 다음 턴에 필요한 모델이 이를 얻을 수 있습니다. - 응답이
max_output_tokens(incomplete_details.reason: "max_output_tokens")에 도달했거나 콘텐츠 필터 ("content_filter")에 걸렸을 때status는incomplete입니다. usage.cost_usd는 해당 호출에 청구된 금액입니다. 스트리밍되지 않는 응답도X-UberLLM-Cost-USD헤더에 이를 포함하며, 모든 응답에는 해당 Activity 행의 ID인X-Request-Id가 있습니다.- 보내신 설정 (
instructions,tools,temperature,max_output_tokens…)은 OpenAI가 하는 것처럼 그대로 다시 반환됩니다.
스트리밍
"stream": true을(를) 사용하면, 응답은 서버 전송 이벤트(server-sent events) 형식으로 제공되며, 각 이벤트는 type과 0에서 시작하는 sequence_number를 포함합니다:
response.created,response.in_progress- 각 출력 항목에 대해:
response.output_item.added, 그 다음 델타(deltas), 그리고 완료된 항목과 함께response.output_item.done:- 텍스트:
response.content_part.added,response.output_text.delta…,response.output_text.done,response.content_part.done - 추론:
response.reasoning_text.delta…,response.reasoning_text.done - 함수 호출:
response.function_call_arguments.delta…,response.function_call_arguments.done - 사용자 지정 도구 호출:
response.custom_tool_call_input.done
- 텍스트:
- 전체 응답과
cost_usd를 포함한usage이(가) 담긴response.completed(또는response.incomplete).
느린 모델이 시작되는 동안, : ping 주석 줄이 연결을 유지합니다. 모든 SSE 클라이언트는 이들을 건너뜁니다.
오류
스트림이 시작되기 전에 거부된 요청은 채팅 완료와 동일하게 HTTP 상태 및 OpenAI의 오류 엔벨로프를 받습니다 (401, 402 크레딧 부족, 404 알 수 없는 모델, 429; 오류] 참조). 스트림이 시작된 후 무언가 실패하면 response.failed로 종료되며, 해당 response.error에는 code과 message이 있습니다. 모델이 완료되기 전에 중단된 스트림도 response.failed로 종료되며, response.completed로는 절대 종료되지 않습니다. 따라서 클라이언트는 불완전한 답변을 유지하는 대신 재시도합니다.