SylphxModels

The Responses API

Every model speaks the same document: the official OpenAI Responses request and response shape, at https://api.sylphx.ai/v1. Change the model field to switch models — nothing else in your request or stream handling moves.

POST /responsesSSE · one terminalstored 7 days

EndpointsLink to this section

All paths are relative to the base URL and require your Bearer key.

Create a responseLink to this section

POST /responses takes a strict JSON document. The only required field is model; input carries what you want the model to answer.

curl https://api.sylphx.ai/v1/responses \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.5",
    "instructions": "Answer as a concise technical writer.",
    "input": "Summarise this incident report in three bullets.",
    "max_output_tokens": 400,
    "store": true
  }'
FieldTypeWhat it does
modelrequiredstringA model id from the catalog — for example openai/gpt-5.5. There is no router alias: an id we do not sell is a typed 404, never a silent substitution.
inputstring | arrayThe user turn, or a full item list. Replayed function calls pair with their outputs by call_id, so a retried transcript keeps its causality.
instructionsstringSystem-level guidance for this turn. Only text you write is sent — the platform never appends its own.
streambooleanfalse (default) returns one JSON response. true returns text/event-stream. See streaming.
storebooleanDefaults to true: the response is retained and can be retrieved or used as previous_response_id. false skips persistence.
previous_response_idstringContinue a stored conversation from an earlier response id.
max_output_tokensintegerUpper bound on the tokens this turn may generate.
toolsarrayFunction tools your code executes, plus hosted tools the platform executes. See hosted tools.
tool_choicestring | objectauto (default) lets the model decide, required forces a tool, or name one tool. The model authors the arguments in every case.
max_tool_callsintegerCaps tool calls for the whole request. An explicit cap is never dropped: a route that cannot honor it fails before any tool runs.
parallel_tool_callsbooleanAllow several independent tool calls in one model round.
includearrayExtra response fields you want returned, such as the sources a hosted web search used.
context_managementarrayOfficial compaction configuration, for example [{"type":"compaction","compact_threshold":100000}]. See compaction.
metadataobjectYour own key-value labels, carried on the response for bookkeeping.
CautionStrict by design
Requests are strict JSON: duplicate keys, malformed tool definitions, non-finite numbers, and unknown fields fail before any model runs. The contract lists the complete accepted key set.

The response objectLink to this section

A non-streaming call returns one application/json Responses object. Visible text, refusals, function calls, and hosted tool items keep their identity and order.

200 OK · application/json
{
  "id": "resp_9f2c41d0a8",
  "object": "response",
  "created_at": 1789123456,
  "status": "completed",
  "model": "openai/gpt-5.5",
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "content": [
        { "type": "output_text", "text": "…", "annotations": [] }
      ]
    }
  ],
  "usage": {
    "input_tokens": 128,
    "output_tokens": 96,
    "total_tokens": 224,
    "cached_tokens": 0
  }
}
  • model is the model id you sent — the price you are charged and the transcript you keep are both traceable to it.
  • usage counts tokens as the serving model counted them; cached_tokens reports the part served from the provider’s prompt cache, when the model reports it.
  • output can contain messages, refusals, function calls, and hosted tool items — each with its own identity and status.
  • The official SDKs expose the assistant text as output_text; on the raw wire, read the text parts inside output.

StreamingLink to this section

stream: true returns server-sent events. Events are complete JSON values with the official OpenAI Responses event names, and the stream commits when client-visible output is produced.

The rules that matter

  • The stream ends exactly once, with response.completed, response.incomplete, response.failed, or response.cancelled. EOF, [DONE], or HTTP 200 alone is not a successful terminal.
  • Hosted tool activity is an item on the way to that terminal — a search never ends the stream and never replaces the assistant answer.
  • If you sent stream: false, you always get one JSON object — the response content type never flips under you.

Events you will see

EventCarries
response.created / response.in_progressThe response shell, before output.
response.output_item.added / .doneEach output item as it opens and closes.
response.content_part.added / .doneText, refusal, or reasoning parts.
response.output_text.delta / .doneAssistant text as it is produced.
response.function_call_arguments.delta / .doneArguments for a function call you will execute.
response.web_search_call.in_progress / .searching / .completedHosted web search trajectory with real outcomes.
response.tool_search_call.in_progress / .completedHosted tool discovery over the tools you declared.
response.completed / .incomplete / .failed / .cancelledThe single terminal, with reason.

The stream follows the official OpenAI Responses event vocabulary; other official events (reasoning summaries, refusals handles) pass through with their own names.

curl -N https://api.sylphx.ai/v1/responses
curl -N https://api.sylphx.ai/v1/responses \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.5",
    "input": "Count to five.",
    "stream": true
  }'

Stored responsesLink to this section

With the default store: true, a completed response stays retrievable. This is what makes conversation continuation and safe retries possible.

MethodPathPurpose
GET/responses/{response_id}Retrieve a stored response while it is retained.
GET/responses/{response_id}/input_itemsList the input items stored for one response.
DELETE/responses/{response_id}Forget a stored response.
POST/responses/{response_id}/cancelOfficial cancel route. Responses are not background jobs.
POST/chat/completionsChat Completions encoding: normalizes once into the same Responses document.
  • A completed response is retained for a seven-day window from completion. Retries of the completion acknowledgement do not extend it.
  • GET /responses/{id} returns the stored response; GET /responses/{id}/input_items returns its input items. Both are tenant-isolated: another organization’s key sees 404, not someone else’s data.
  • DELETE /responses/{id} returns the official {"id": …, "object": "response", "deleted": true} object. Deleting is how you forget a stored turn before its window ends.
  • POST /responses/{id}/cancel exists as the official route, but this product does not admit background: true. A stored hit returns 400 response_not_cancellable; an unknown id returns 404.
  • store: false skips persistence. A later previous_response_id that points at an unpersisted response is a 400, so choose one shape per conversation.

CompactionLink to this section

POST /responses/compact compacts a stored conversation into an official response.compaction object you can continue from — useful when a transcript approaches the context window.

POST https://api.sylphx.ai/v1/responses/compact
curl https://api.sylphx.ai/v1/responses/compact \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.5",
    "previous_response_id": "resp_9f2c41d0a8"
  }'
  • Compact is unary: stream: true is rejected on this route.
  • The result is the model family’s official compaction object. Sealed encrypted_content inside it belongs to that model family and is not portable to a different one — continue the conversation on the same family.
  • You can also let the API compact during a create by sending context_management. Where a model cannot compact, the request fails with a typed error instead of substituting a local summary; there is no fabricated digest.

FilesLink to this section

Upload once, then reference the file id from a Responses input item. File ids are tenant-isolated and expire with the same seven-day retention window.

POST https://api.sylphx.ai/v1/files
curl https://api.sylphx.ai/v1/files \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -F "file=@report.pdf" \
  -F "purpose=user_data"

# → { "id": "file-3c9…", "object": "file", "status": "processed", … }
Reference the upload
{
  "model": "openai/gpt-5.5",
  "input": [
    {
      "role": "user",
      "content": [
        { "type": "input_text", "text": "Summarise the attached report." },
        { "type": "input_file", "file_id": "file-3c9…" }
      ]
    }
  ]
}
  • purpose is one of user_data (default), vision, assistants, fine-tune, or evals.
  • GET /files lists your key’s files with first_id, last_id, and has_more; GET /files/{id}/content returns the raw bytes.
  • A request that names a missing file id fails with 400 file_not_found — the API does not guess which file you meant.

Messages: a second encodingLink to this section

POST /messages accepts the Anthropic Messages format. It decodes under Anthropic rules, normalizes once into the same Responses document, and can call any model in the catalog.

  • Hosted tools follow the same ownership on Messages: the model initiates, the platform executes, and you observe server-tool blocks. No instruction coaching is added to your system prompt.
  • Streaming follows Anthropic stream semantics with one typed terminal.
  • POST /chat/completions is the same kind of encoding for the OpenAI Chat Completions format (see below).

Chat Completions: the OpenAI chat encodingLink to this section

POST /chat/completions accepts the OpenAI Chat Completions format. It normalizes once into the same Responses document, so errors, usage, and prices are the Responses ones, and it can call any model in the catalog.

  • messages, function tools, tool_choice, parallel_tool_calls, response_format (including strict json_schema), reasoning_effort, and max_completion_tokens map onto their Responses fields.
  • A field the Responses document cannot carry faithfully is refused with 400 invalid_request before any model call — for example n above 1, a non-empty stop, logprobs, audio output, or the deprecated functions shape. Nothing is dropped silently.
  • Streams send chat.completion.chunk frames with exactly one finish_reason, a usage chunk when stream_options.include_usage is true, and data: [DONE]. Hosted tools stay on Responses and Messages.

Switching models safelyLink to this section

Because model is a field, you can move a conversation to another model without changing facades. Keep the transcript, drop the model-specific state.

  • Keep the visible transcript and your function or tool results.
  • Remove execution observations and provider-sealed content (for example encrypted_content from a compaction) before sending the transcript to a different model family.
  • Send the remaining items as a new request with the new model id on the same endpoint. If the new model cannot honor the transcript, you get a typed error — never a silently rewritten request.
TipPrices travel with the model
Every id in the catalog has its own published input, output, and cached-input rate. See models and pricing before you switch in production.