EndpointsLink to this section
All paths are relative to the base URL and require your Bearer key.
| Method | Path | Purpose |
|---|---|---|
| POST | /responses | Create a response. Add stream: true for SSE. |
| POST | /responses/compact | Compact a stored response into an official compaction object. |
| GET | /responses/{response_id} | Retrieve a stored response while it is retained. |
| GET | /responses/{response_id}/input_items | List the input items stored for one response. |
| DELETE | /responses/{response_id} | Forget a stored response. |
| POST | /responses/{response_id}/cancel | Official cancel route. Responses are not background jobs. |
| POST | /chat/completions | Chat Completions encoding: normalizes once into the same Responses document. |
| POST | /files | Multipart upload. Mints a file-* id for input_file and input_image. |
| GET | /files | List the files owned by your key. |
| GET | /files/{file_id} | File metadata, no bytes. |
| GET | /files/{file_id}/content | Raw file bytes. |
| DELETE | /files/{file_id} | Delete a file you own. |
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
}'
| Field | Type | What it does |
|---|---|---|
modelrequired | string | A 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. |
input | string | array | The user turn, or a full item list. Replayed function calls pair with their outputs by call_id, so a retried transcript keeps its causality. |
instructions | string | System-level guidance for this turn. Only text you write is sent — the platform never appends its own. |
stream | boolean | false (default) returns one JSON response. true returns text/event-stream. See streaming. |
store | boolean | Defaults to true: the response is retained and can be retrieved or used as previous_response_id. false skips persistence. |
previous_response_id | string | Continue a stored conversation from an earlier response id. |
max_output_tokens | integer | Upper bound on the tokens this turn may generate. |
tools | array | Function tools your code executes, plus hosted tools the platform executes. See hosted tools. |
tool_choice | string | object | auto (default) lets the model decide, required forces a tool, or name one tool. The model authors the arguments in every case. |
max_tool_calls | integer | Caps 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_calls | boolean | Allow several independent tool calls in one model round. |
include | array | Extra response fields you want returned, such as the sources a hosted web search used. |
context_management | array | Official compaction configuration, for example [{"type":"compaction","compact_threshold":100000}]. See compaction. |
metadata | object | Your own key-value labels, carried on the response for bookkeeping. |
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.
{
"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
}
}
modelis the model id you sent — the price you are charged and the transcript you keep are both traceable to it.usagecounts tokens as the serving model counted them;cached_tokensreports the part served from the provider’s prompt cache, when the model reports it.outputcan 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 insideoutput.
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, orresponse.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
| Event | Carries |
|---|---|
response.created / response.in_progress | The response shell, before output. |
response.output_item.added / .done | Each output item as it opens and closes. |
response.content_part.added / .done | Text, refusal, or reasoning parts. |
response.output_text.delta / .done | Assistant text as it is produced. |
response.function_call_arguments.delta / .done | Arguments for a function call you will execute. |
response.web_search_call.in_progress / .searching / .completed | Hosted web search trajectory with real outcomes. |
response.tool_search_call.in_progress / .completed | Hosted tool discovery over the tools you declared. |
response.completed / .incomplete / .failed / .cancelled | The 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 \
-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.
| Method | Path | Purpose |
|---|---|---|
| GET | /responses/{response_id} | Retrieve a stored response while it is retained. |
| GET | /responses/{response_id}/input_items | List the input items stored for one response. |
| DELETE | /responses/{response_id} | Forget a stored response. |
| POST | /responses/{response_id}/cancel | Official cancel route. Responses are not background jobs. |
| POST | /chat/completions | Chat 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_itemsreturns its input items. Both are tenant-isolated: another organization’s key sees404, 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}/cancelexists as the official route, but this product does not admitbackground: true. A stored hit returns400 response_not_cancellable; an unknown id returns404.store: falseskips persistence. A laterprevious_response_idthat points at an unpersisted response is a400, 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.
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: trueis rejected on this route. - The result is the model family’s official compaction object. Sealed
encrypted_contentinside 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.
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", … }
{
"model": "openai/gpt-5.5",
"input": [
{
"role": "user",
"content": [
{ "type": "input_text", "text": "Summarise the attached report." },
{ "type": "input_file", "file_id": "file-3c9…" }
]
}
]
}
purposeis one ofuser_data(default),vision,assistants,fine-tune, orevals.GET /fileslists your key’s files withfirst_id,last_id, andhas_more;GET /files/{id}/contentreturns 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
systemprompt. - Streaming follows Anthropic stream semantics with one typed terminal.
POST /chat/completionsis 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, functiontools,tool_choice,parallel_tool_calls,response_format(including strictjson_schema),reasoning_effort, andmax_completion_tokensmap onto their Responses fields.- A field the Responses document cannot carry faithfully is refused with
400 invalid_requestbefore any model call — for examplenabove 1, a non-emptystop,logprobs, audio output, or the deprecatedfunctionsshape. Nothing is dropped silently. - Streams send
chat.completion.chunkframes with exactly onefinish_reason, a usage chunk whenstream_options.include_usageis true, anddata: [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_contentfrom 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.