# Use Responses and Conversations

Source: https://cicora.ai/en/docs/responses

The Responses API is an OpenAI-compatible interface for text and image input, function calling, structured output, streaming, and durable conversation state. It is available at `https://api.cicora.ai/v1` and uses the same Bearer API key and model IDs as the other API formats.

## Create a response

Choose an available text model from `GET /v1/models`, then start with one non-streaming request:

```bash
export CICORA_API_KEY="sk_..."

curl --fail-with-body --silent --show-error https://api.cicora.ai/v1/responses \
  -H "Authorization: Bearer $CICORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4",
    "input": "Reply with ok"
  }'
```

Read assistant text from the `output` array. A text response contains an assistant `message` with one or more `output_text` parts:

```json
{
  "id": "resp_example",
  "object": "response",
  "status": "completed",
  "model": "openai/gpt-5.4",
  "output": [
    {
      "id": "msg_example",
      "type": "message",
      "role": "assistant",
      "status": "completed",
      "content": [{ "type": "output_text", "text": "ok", "annotations": [] }]
    }
  ]
}
```

*A Responses request creates durable output that can continue through a previous response or a Conversation.*

*Responses supports portable state with `previous_response_id` and Conversations.*

## Continue a previous response

Responses are stored by default. Send the returned ID as `previous_response_id` when the next request should include the previous portable input and output history:

```bash
curl --fail-with-body --silent --show-error https://api.cicora.ai/v1/responses \
  -H "Authorization: Bearer $CICORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4",
    "previous_response_id": "resp_example",
    "input": "Now answer with one word"
  }'
```

Use either `previous_response_id` or `conversation` in a request, not both. Retrieve an earlier stored response with `GET /v1/responses/{response_id}`, inspect its original portable input with `GET /v1/responses/{response_id}/input_items`, or delete stored state with `DELETE /v1/responses/{response_id}`.

Add an `Idempotency-Key` header when a network retry must not create a second stored response. Reusing the key with the same request returns the original response; do not reuse it for a different body.

## Stream response events

Set `stream` to `true` to receive Responses Server-Sent Events (SSE). Process events in sequence and treat only a terminal `response.completed`, `response.failed`, or `response.incomplete` event as final:

```bash
curl --no-buffer --fail-with-body --silent --show-error https://api.cicora.ai/v1/responses \
  -H "Authorization: Bearer $CICORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4",
    "input": "Reply with ok",
    "stream": true
  }'
```

```text
data: {"type":"response.created","sequence_number":1,"response":{"id":"resp_example","status":"in_progress"}}

data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_example","output_index":0,"content_index":0,"delta":"ok"}

data: {"type":"response.completed","sequence_number":8,"response":{"id":"resp_example","status":"completed"}}
```

A connection close without a terminal event is incomplete. Retry with bounded backoff only before output was delivered; after a text, tool-call, or reasoning event arrives, preserve the partial result and let the caller decide whether to continue.

## Use function tools and structured output

Pass portable `function` tools in `tools`. When the model returns a `function_call`, execute it in your application, then send a `function_call_output` item in the next request. Function execution stays in your environment; cicora.ai does not run arbitrary client code.

Use `text.format` with `json_object` or `json_schema` for supported structured-output requests. Check the selected model's current `supported_parameters` in `GET /v1/models`; model availability and optional capabilities can change.

## Keep a named Conversation

Conversations are separate durable objects for a sequence of portable input and output items. Create one, then pass its ID as `conversation` to `POST /v1/responses`:

```bash
export CICORA_CONVERSATION_ID="$(
  curl --fail-with-body --silent --show-error https://api.cicora.ai/v1/conversations \
    -H "Authorization: Bearer $CICORA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"metadata":{"project":"support-bot"}}' \
  | jq -r '.id'
)"

curl --fail-with-body --silent --show-error https://api.cicora.ai/v1/responses \
  -H "Authorization: Bearer $CICORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"openai/gpt-5.4\",\"conversation\":\"$CICORA_CONVERSATION_ID\",\"input\":\"Reply with ok\"}"
```

Use `GET`, `POST`, and `DELETE` on `/v1/conversations/{conversation_id}` to retrieve, update metadata, or delete a Conversation. Its items are available at `/v1/conversations/{conversation_id}/items`; append up to 20 portable items with `POST`, and use `after`, `limit`, and `order` to page through them.

## Compatibility boundary

The portable API accepts text and image input, function tools, tool results, response chaining, Conversations, and the documented request fields on this page. It intentionally rejects hosted tools and provider-private state: `web_search`, `file_search`, `code_interpreter`, computer use, hosted MCP, background jobs, and encrypted provider-native reasoning state.

**Do not assume all OpenAI features are portable**


An OpenAI SDK can call the published endpoint, but an application may still
rely on a hosted tool or an undocumented request field. Start with the
smallest request above, then add one capability at a time and handle a public
error response explicitly.


## Troubleshooting


**The API rejects a request field or tool**


The portable Responses contract is intentionally strict. Remove the
unsupported field, use a `function` tool that your application executes, or
choose a supported API flow. The error identifies the public parameter when
available.


**A response cannot find a previous ID or Conversation**


Use the exact returned ID with the same API key and workspace. Do not
combine `previous_response_id` and `conversation` in one create request, and
do not reuse an ID after deleting its stored object.


**The stream delivered output but did not complete**


Keep the delivered result and record the last event, response ID, model,
HTTP status or public error, and time. Do not automatically replay a request
that already delivered content or a tool call.

## FAQ

### What is cicora.ai?

cicora.ai is a multi-model AI workspace and compatible API for chat, text, images, video, coding tools, and teams. Start with the [overview](/en.md), [documentation](/en/docs.md), or [model catalog](/en/models.md).

### How is usage billed?

Confirmed usage is charged in USD from the active workspace's prepaid balance. Use the live catalog for current model prices and the [usage guide](/en/docs/usage-costs.md) for settlement details.

### Which protocols and integrations are available?

Documentation covers OpenAI-compatible Chat Completions and Responses, Anthropic Messages, image interfaces, Claude Code, OpenCode, and Codex CLI. Compatibility does not imply support for every upstream parameter.

### Which sources are authoritative and current?

For model IDs, availability, capabilities, limits, and prices, use the [live catalog](/en/models.md). For API behavior, use the matching [documentation page](/en/docs.md). Never include API keys, private workspace data, or preview URLs in public documents.
