Текстовая генерация
Responses
POST /api/v1/responses — Responses API: элементы вывода, инструменты, поток событий
POST
/
api
/
v1
/
responses
Responses API
curl --request POST \
--url https://speshu.ai/api/v1/responses \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "gpt-4o",
"input": "<string>",
"stream": false,
"instructions": "<string>",
"max_output_tokens": 123,
"max_tool_calls": 123,
"temperature": 123,
"top_p": 123,
"text": {},
"tools": [
{}
],
"parallel_tool_calls": true,
"reasoning": {
"summary": "<string>",
"max_tokens": 123
},
"previous_response_id": "<string>",
"conversation": {},
"include": [
"<string>"
],
"store": true,
"metadata": {}
}
'import requests
url = "https://speshu.ai/api/v1/responses"
payload = {
"model": "gpt-4o",
"input": "<string>",
"stream": False,
"instructions": "<string>",
"max_output_tokens": 123,
"max_tool_calls": 123,
"temperature": 123,
"top_p": 123,
"text": {},
"tools": [{}],
"parallel_tool_calls": True,
"reasoning": {
"summary": "<string>",
"max_tokens": 123
},
"previous_response_id": "<string>",
"conversation": {},
"include": ["<string>"],
"store": True,
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'gpt-4o',
input: '<string>',
stream: false,
instructions: '<string>',
max_output_tokens: 123,
max_tool_calls: 123,
temperature: 123,
top_p: 123,
text: {},
tools: [{}],
parallel_tool_calls: true,
reasoning: {summary: '<string>', max_tokens: 123},
previous_response_id: '<string>',
conversation: {},
include: ['<string>'],
store: true,
metadata: {}
})
};
fetch('https://speshu.ai/api/v1/responses', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://speshu.ai/api/v1/responses",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'gpt-4o',
'input' => '<string>',
'stream' => false,
'instructions' => '<string>',
'max_output_tokens' => 123,
'max_tool_calls' => 123,
'temperature' => 123,
'top_p' => 123,
'text' => [
],
'tools' => [
[
]
],
'parallel_tool_calls' => true,
'reasoning' => [
'summary' => '<string>',
'max_tokens' => 123
],
'previous_response_id' => '<string>',
'conversation' => [
],
'include' => [
'<string>'
],
'store' => true,
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://speshu.ai/api/v1/responses"
payload := strings.NewReader("{\n \"model\": \"gpt-4o\",\n \"input\": \"<string>\",\n \"stream\": false,\n \"instructions\": \"<string>\",\n \"max_output_tokens\": 123,\n \"max_tool_calls\": 123,\n \"temperature\": 123,\n \"top_p\": 123,\n \"text\": {},\n \"tools\": [\n {}\n ],\n \"parallel_tool_calls\": true,\n \"reasoning\": {\n \"summary\": \"<string>\",\n \"max_tokens\": 123\n },\n \"previous_response_id\": \"<string>\",\n \"conversation\": {},\n \"include\": [\n \"<string>\"\n ],\n \"store\": true,\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://speshu.ai/api/v1/responses")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"gpt-4o\",\n \"input\": \"<string>\",\n \"stream\": false,\n \"instructions\": \"<string>\",\n \"max_output_tokens\": 123,\n \"max_tool_calls\": 123,\n \"temperature\": 123,\n \"top_p\": 123,\n \"text\": {},\n \"tools\": [\n {}\n ],\n \"parallel_tool_calls\": true,\n \"reasoning\": {\n \"summary\": \"<string>\",\n \"max_tokens\": 123\n },\n \"previous_response_id\": \"<string>\",\n \"conversation\": {},\n \"include\": [\n \"<string>\"\n ],\n \"store\": true,\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://speshu.ai/api/v1/responses")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"gpt-4o\",\n \"input\": \"<string>\",\n \"stream\": false,\n \"instructions\": \"<string>\",\n \"max_output_tokens\": 123,\n \"max_tool_calls\": 123,\n \"temperature\": 123,\n \"top_p\": 123,\n \"text\": {},\n \"tools\": [\n {}\n ],\n \"parallel_tool_calls\": true,\n \"reasoning\": {\n \"summary\": \"<string>\",\n \"max_tokens\": 123\n },\n \"previous_response_id\": \"<string>\",\n \"conversation\": {},\n \"include\": [\n \"<string>\"\n ],\n \"store\": true,\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"object": "response",
"model": "<string>",
"output": [
{
"id": "<string>",
"type": "<string>",
"status": "<string>",
"role": "<string>",
"content": [
{}
]
}
],
"created_at": 123,
"completed_at": 123,
"status": "completed",
"error": {},
"usage": {
"total_tokens": 123,
"input_tokens": 123,
"output_tokens": 123,
"input_tokens_details": {
"cached_tokens": 123,
"text_tokens": 123,
"image_tokens": 123
},
"output_tokens_details": {
"reasoning_tokens": 123,
"text_tokens": 123
},
"cost": {
"input_cost": 123,
"output_cost": 123,
"total_cost": 123
}
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}Совместим с OpenAI Responses API: официальный SDK работает без изменений — достаточно поменять
Поддерживаемые
Поле
Элементы вывода и их части:
Текст:
Инструменты:
Рассуждения:
Каждое событие несёт
Если провайдер оборвал поток, в середине придёт событие
Обрабатывайте неизвестные типы событий без ошибки: новые события появляются без изменения основного контракта.
Полная таблица кодов — на странице Ошибки.
base_url. В отличие от Chat Completions, ответ собирается в плоский список output — сообщения, вызовы функций и вызовы встроенных инструментов лежат в одном массиве и различаются по полю type.
Если вам не нужен список элементов вывода, используйте Запрос чату — формат проще, а цены и тарификация те же.
Минимальный запрос
curl https://speshu.ai/api/v1/responses \
-H "Authorization: Bearer $SPESHU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"input": "Привет!"
}'
from openai import OpenAI
client = OpenAI(base_url="https://speshu.ai/api/v1", api_key="sk-...")
response = client.responses.create(
model="gpt-4o",
input="Привет!",
)
print(response.output_text)
print(response.usage.cost.total_cost, "₽")
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://speshu.ai/api/v1",
apiKey: "sk-...",
});
const response = await client.responses.create({
model: "gpt-4o",
input: "Привет!",
});
console.log(response.output_text);
Идентификатор модели нужно взять из
GET /api/v1/models и подставить как есть. Если модель неизвестна, придёт 404 с кодом model_not_found. Идентификатор в примерах ниже конкретный, чтобы их можно было скопировать; в рабочем коде получайте его из каталога — состав моделей меняется.Поля запроса
Обязательные
| Поле | Тип | Описание |
|---|---|---|
model | string | Идентификатор из GET /api/v1/models |
input | string | array | Строка с запросом либо массив сообщений |
stream | boolean | Потоковая передача через SSE |
Если
input не передан или равен пустой строке, придёт 400 input is required. instructions не заменяет input — хотя бы одно из них всегда нужно.input как массив — это обычные сообщения с role и content. Поддерживаются роли user, assistant, system, developer.
Генерация
| Поле | Тип | Описание |
|---|---|---|
instructions | string | Системная инструкция к текущему ответу |
max_output_tokens | integer | Потолок выходных токенов |
temperature | number | |
top_p | number | |
top_logprobs | integer | Сколько альтернативных токенов возвращать в логвероятностях |
truncation | string | auto или disabled |
service_tier | string | auto, default, flex, priority |
metadata | object | Произвольные данные «ключ → значение» |
store | boolean | |
background | boolean | |
conversation | object | Привязка к диалогу вместо previous_response_id |
previous_response_id | string | Продолжение предыдущего ответа |
max_tool_calls | integer | Потолок числа вызовов инструментов |
stream_options | object |
Структурированный вывод
Полеtext задаёт формат ответа и подробность (поле verbosity):
{
"text": {
"format": {
"type": "json_schema",
"name": "order",
"description": "Заказ клиента",
"schema": {
"type": "object",
"properties": {
"sku": { "type": "string" },
"qty": { "type": "integer" }
},
"required": ["sku", "qty"]
},
"strict": true
},
"verbosity": "low"
}
}
format.type — text, json_object или json_schema. Для json_schema обязательны name и schema; description и strict необязательны.
Инструменты
{
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "Погода в городе",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
],
"tool_choice": "auto"
}
| Поле | Тип | Описание |
|---|---|---|
tool_choice | string | object | none, auto, required, any либо объект с конкретным инструментом |
parallel_tool_calls | boolean | Разрешить несколько вызовов за один шаг |
type в tools[]:
| Тип | Что это |
|---|---|
function | Ваша функция |
custom | Ваш инструмент произвольного вида |
file_search | Поиск по загруженным файлам |
code_interpreter | Выполнение кода |
web_search, web_search_2025_08_26, web_search_preview, x_search | Веб-поиск и поиск по X |
computer_use_preview | Управление браузером |
mcp | Внешний MCP-сервер |
image_generation | Генерация изображений |
local_shell | Локальный шелл |
tool_search | Поиск по доступным инструментам |
Рассуждения
{
"reasoning": {
"effort": "high",
"summary": "auto",
"max_tokens": 2048
}
}
effort — none, minimal, low, medium, high, xhigh, max. Значение, отличное от none, включает рассуждение. Текст рассуждений приходит событиями response.reasoning_summary_text.delta и попадает в output_tokens_details.reasoning_tokens.
Включить в ответ дополнительные поля
include — массив строк. Например:
{ "include": ["web_search_call.action.sources", "message.output_text.logprobs", "reasoning.encrypted_content"] }
Ответ
{
"id": "resp_...",
"object": "response",
"created_at": 1756800000,
"completed_at": 1756800004,
"status": "completed",
"error": null,
"incomplete_details": null,
"model": "gpt-4o",
"instructions": null,
"max_output_tokens": null,
"output": [
{
"id": "msg_...",
"type": "message",
"status": "completed",
"role": "assistant",
"content": [
{ "type": "output_text", "text": "Привет! Чем помочь?", "annotations": [] }
]
}
],
"usage": {
"input_tokens": 9,
"output_tokens": 7,
"total_tokens": 16,
"input_tokens_details": { "cached_tokens": 0, "text_tokens": 9, "image_tokens": 0 },
"output_tokens_details": { "reasoning_tokens": 0, "text_tokens": 7 },
"cost": { "input_cost": 0.0002, "output_cost": 0.0006, "total_cost": 0.0008 }
}
}
model повторяет запрошенный идентификатор. status — одно из completed, in_progress, incomplete, failed, cancelled, queued.
Текст ответа лежит не на верхнем уровне, а внутри
output. Обычно это output[0].content[0].text, но элемент с вызовом функции тоже может стоять первым — ищите текст перебором всех элементов, а не по индексу. В SDK за это отвечает response.output_text.Стоимость
usage.cost.total_cost — сумма, списанная с вашего кошелька в рублях, а не себестоимость у провайдера. Именно она совпадает с cost_context и cost_completion из GET /api/v1/models.
Потоковая передача
Приstream: true приходит поток SSE. Каждый кадр — безымянное событие data:; отдельного поля event: сервер не пишет, поэтому клиенты, разбирающие поток по event:, работать не будут. Тип события лежит в поле type самого объекта.
data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_...","object":"response","status":"in_progress","output":[]}}
data: {"type":"response.output_item.added","sequence_number":1,"output_index":0,"item":{"id":"msg_...","type":"message","status":"in_progress","role":"assistant","content":[]}}
data: {"type":"response.output_text.delta","sequence_number":2,"output_index":0,"content_index":0,"item_id":"msg_...","delta":"Привет"}
data: {"type":"response.output_text.delta","sequence_number":3,"output_index":0,"content_index":0,"item_id":"msg_...","delta":"!"}
data: {"type":"response.output_text.done","sequence_number":4,"output_index":0,"content_index":0,"item_id":"msg_...","text":"Привет!"}
data: {"type":"response.output_item.done","sequence_number":5,"output_index":0,"item":{"id":"msg_...","type":"message","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Привет!"}]}}
data: {"type":"response.completed","sequence_number":6,"response":{"id":"resp_...","object":"response","status":"completed","output":[],"usage":{"input_tokens":9,"output_tokens":7,"total_tokens":16,"cost":{"total_cost":0.0008}}}}
data: [DONE]
События
Жизненный цикл ответа:| Событие | Когда приходит |
|---|---|
response.created | Ответ создан |
response.in_progress | Ответ взят в работу |
response.completed | Ответ успешно завершён |
response.failed | Ответ завершился ошибкой |
response.incomplete | Ответ прерван по лимиту токенов |
response.ping | Проверка живости соединения |
error | Ошибка в середине потока |
| Событие | Когда приходит |
|---|---|
response.output_item.added | Начался новый элемент output |
response.output_item.done | Элемент output готов целиком |
response.content_part.added | Началась новая часть контента элемента |
response.content_part.done | Часть контента закрыта |
| Событие | Когда приходит |
|---|---|
response.output_text.delta | Очередной кусок текста |
response.output_text.done | Текст элемента готов целиком |
response.output_text.annotation.added | Ссылка в тексте (например, источник поиска) |
response.refusal.delta | Модель отказалась отвечать |
| Событие | Когда приходит |
|---|---|
response.function_call_arguments.delta | Очередной кусок аргументов функции |
response.function_call_arguments.done | Аргументы функции готовы |
response.web_search_call.in_progress | Идёт веб-поиск |
response.file_search_call.in_progress | Идёт поиск по файлам |
response.code_interpreter_call.* | Шаги интерпретатора кода |
response.mcp_call.* | Обращение к MCP-серверу |
response.image_generation_call.partial_image | Промежуточная картинка |
| Событие | Когда приходит |
|---|---|
response.reasoning_summary_text.delta | Очередной кусок пересказа рассуждений |
response.reasoning_summary_part.added | Новая часть пересказа рассуждений |
sequence_number — номер по порядку. По нему можно отсеять дубли и поймать пропуск кадров. Индексы output_index и content_index адресуют конкретный элемент и часть контента внутри него.
Деньги списываются на событии
response.completed: именно в его поле response.usage.cost.total_cost лежит сумма в рублях. Если поток оборвался раньше, списания по этому кадру не будет — сверяйтесь с балансом через GET /api/v1/balance.После последнего события сервер дописывает кадр
data: [DONE]. Его нет в спецификации OpenAI Responses API: строгий клиент попытается распарсить [DONE] как JSON и упадёт. Обработайте эту строку как конец потока и завершайте чтение.error с объектом error внутри, а response.completed и [DONE] не придут вовсе:
data: {"type":"error","sequence_number":7,"error":{"message":"...","type":"server_error"}}
Проверки перед вызовом
Часть ошибок возвращается до обращения к провайдеру — в формате OpenAI:{
"error": {
"message": "input is required",
"type": "invalid_request_error",
"param": "input",
"code": "invalid_request"
}
}
| Ситуация | Ответ |
|---|---|
| Нет ключа | 401 invalid_api_key |
| Модель неизвестна | 404 model_not_found |
| Не хватает денег | 402 insufficient_quota |
Нет input | 400 input is required |
Неподдерживаемый reasoning.effort | 400 invalid_request |
| Входные токены плюс резерв выхода не помещаются в окно | 422 content_too_large |
| Провайдер недоступен | 503 service_unavailable |
Что дальше
Запрос чату
Тот же набор моделей в формате Chat Completions
Anthropic Messages
Совместимость с Anthropic SDK
Каталог моделей
Идентификаторы и цены
Ошибки
Полная таблица кодов
Авторизации
API-ключ в формате sk-.... Альтернативно — заголовок X-Api-Key: sk-... (совместимо с Anthropic SDK).
Тело
application/json
Пример:
"gpt-4o"
Строка с запросом либо массив сообщений.
Доступные опции:
none, auto, required, any Show child attributes
Show child attributes
Доступные опции:
auto, disabled Ответ
Успешный ответ. При stream: true — поток SSE с событиями Responses API, завершающийся кадром data: [DONE].
Пример:
"response"
Show child attributes
Show child attributes
Доступные опции:
completed, in_progress, incomplete, failed, cancelled, queued Show child attributes
Show child attributes
⌘I
Responses API
curl --request POST \
--url https://speshu.ai/api/v1/responses \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "gpt-4o",
"input": "<string>",
"stream": false,
"instructions": "<string>",
"max_output_tokens": 123,
"max_tool_calls": 123,
"temperature": 123,
"top_p": 123,
"text": {},
"tools": [
{}
],
"parallel_tool_calls": true,
"reasoning": {
"summary": "<string>",
"max_tokens": 123
},
"previous_response_id": "<string>",
"conversation": {},
"include": [
"<string>"
],
"store": true,
"metadata": {}
}
'import requests
url = "https://speshu.ai/api/v1/responses"
payload = {
"model": "gpt-4o",
"input": "<string>",
"stream": False,
"instructions": "<string>",
"max_output_tokens": 123,
"max_tool_calls": 123,
"temperature": 123,
"top_p": 123,
"text": {},
"tools": [{}],
"parallel_tool_calls": True,
"reasoning": {
"summary": "<string>",
"max_tokens": 123
},
"previous_response_id": "<string>",
"conversation": {},
"include": ["<string>"],
"store": True,
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'gpt-4o',
input: '<string>',
stream: false,
instructions: '<string>',
max_output_tokens: 123,
max_tool_calls: 123,
temperature: 123,
top_p: 123,
text: {},
tools: [{}],
parallel_tool_calls: true,
reasoning: {summary: '<string>', max_tokens: 123},
previous_response_id: '<string>',
conversation: {},
include: ['<string>'],
store: true,
metadata: {}
})
};
fetch('https://speshu.ai/api/v1/responses', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://speshu.ai/api/v1/responses",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'gpt-4o',
'input' => '<string>',
'stream' => false,
'instructions' => '<string>',
'max_output_tokens' => 123,
'max_tool_calls' => 123,
'temperature' => 123,
'top_p' => 123,
'text' => [
],
'tools' => [
[
]
],
'parallel_tool_calls' => true,
'reasoning' => [
'summary' => '<string>',
'max_tokens' => 123
],
'previous_response_id' => '<string>',
'conversation' => [
],
'include' => [
'<string>'
],
'store' => true,
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://speshu.ai/api/v1/responses"
payload := strings.NewReader("{\n \"model\": \"gpt-4o\",\n \"input\": \"<string>\",\n \"stream\": false,\n \"instructions\": \"<string>\",\n \"max_output_tokens\": 123,\n \"max_tool_calls\": 123,\n \"temperature\": 123,\n \"top_p\": 123,\n \"text\": {},\n \"tools\": [\n {}\n ],\n \"parallel_tool_calls\": true,\n \"reasoning\": {\n \"summary\": \"<string>\",\n \"max_tokens\": 123\n },\n \"previous_response_id\": \"<string>\",\n \"conversation\": {},\n \"include\": [\n \"<string>\"\n ],\n \"store\": true,\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://speshu.ai/api/v1/responses")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"gpt-4o\",\n \"input\": \"<string>\",\n \"stream\": false,\n \"instructions\": \"<string>\",\n \"max_output_tokens\": 123,\n \"max_tool_calls\": 123,\n \"temperature\": 123,\n \"top_p\": 123,\n \"text\": {},\n \"tools\": [\n {}\n ],\n \"parallel_tool_calls\": true,\n \"reasoning\": {\n \"summary\": \"<string>\",\n \"max_tokens\": 123\n },\n \"previous_response_id\": \"<string>\",\n \"conversation\": {},\n \"include\": [\n \"<string>\"\n ],\n \"store\": true,\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://speshu.ai/api/v1/responses")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"gpt-4o\",\n \"input\": \"<string>\",\n \"stream\": false,\n \"instructions\": \"<string>\",\n \"max_output_tokens\": 123,\n \"max_tool_calls\": 123,\n \"temperature\": 123,\n \"top_p\": 123,\n \"text\": {},\n \"tools\": [\n {}\n ],\n \"parallel_tool_calls\": true,\n \"reasoning\": {\n \"summary\": \"<string>\",\n \"max_tokens\": 123\n },\n \"previous_response_id\": \"<string>\",\n \"conversation\": {},\n \"include\": [\n \"<string>\"\n ],\n \"store\": true,\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"object": "response",
"model": "<string>",
"output": [
{
"id": "<string>",
"type": "<string>",
"status": "<string>",
"role": "<string>",
"content": [
{}
]
}
],
"created_at": 123,
"completed_at": 123,
"status": "completed",
"error": {},
"usage": {
"total_tokens": 123,
"input_tokens": 123,
"output_tokens": 123,
"input_tokens_details": {
"cached_tokens": 123,
"text_tokens": 123,
"image_tokens": 123
},
"output_tokens_details": {
"reasoning_tokens": 123,
"text_tokens": 123
},
"cost": {
"input_cost": 123,
"output_cost": 123,
"total_cost": 123
}
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"param": "<string>",
"code": "invalid_request"
}
}