# Responses API

Sayfa: https://docs.sonecentral.com/responses
Markdown: https://docs.sonecentral.com/responses.md

> POST /responses ile OpenAI Responses biçiminde konuşun; sohbeti previous_response_id ya da conversation ile sürdürün, saklanan yanıtları okuyun ve silin.

```http
POST https://pb.sonecentral.com/api/v1/responses
```

OpenAI Responses biçimini kullanır. Sohbeti sürdürmek için önceki yanıtın kimliğini göndermeniz yeter; geçmişi her seferinde yeniden yollamazsınız.

## İlk mesaj ve devamı

**OpenAI JS**

```ts
const first = await client.responses.create({
  model: 'default',
  input: 'Saç boyası için randevu almak istiyorum.',
});

console.log(first.output_text);

const second = await client.responses.create({
  model: 'default',
  previous_response_id: first.id,
  input: 'Perşembe öğleden sonra olur mu?',
});

console.log(second.output_text);
```

**OpenAI Python**

```python
first = client.responses.create(
    model="default",
    input="Saç boyası için randevu almak istiyorum.",
)
print(first.output_text)

second = client.responses.create(
    model="default",
    previous_response_id=first.id,
    input="Perşembe öğleden sonra olur mu?",
)
print(second.output_text)
```

**curl**

```bash
curl https://pb.sonecentral.com/api/v1/responses \
  -H "Authorization: Bearer $SONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "default", "input": "Saç boyası için randevu almak istiyorum." }'
```

`output_text` SDK'nın kolaylığıdır: bütün `output_text` parçalarını birleştirir.

## İstek

| Alan | Tür | Açıklama |
| --- | --- | --- |
| `model` | string | Asistanın kimliği ya da "default". Zorunlu. |
| `input` | string \| array | Yeni mesaj. Metin ya da OpenAI girdi öğeleri: rolü olan message öğeleri ve item_reference. Mesajlarda input_text ve output_text parçaları okunur. Bir item_reference kimliği en fazla 64 karakterdir. Son öğe ziyaretçinin metin mesajı olmalıdır. Zorunlu. |
| `previous_response_id` | string | Önceki yanıtın kimliği, resp_ ve 32 karakter. Aynı sohbet sürer. conversation ile birlikte gönderilemez. Bir yanıt kimliğinden uzun bir değer reddedilir. |
| `conversation` | string \| { id: string } | Sohbetin kimliği, yani sone.conversation_id. previous_response_id yerine kullanılabilir. |
| `store` | boolean | false ise yanıt saklanmaz; GET /responses/{id} ve previous_response_id onu bulamaz. Varsayılan: true. |
| `instructions` | string | Sunucu anahtarıyla asistana yalnız bilgi olarak iletilir. En fazla 2.000 karakter ve JSON olarak 4 KB; daha uzunu reddedilir. Tarayıcı anahtarıyla yok sayılır, saklanmaz ve yanıtta yer almaz. Saklanan yanıtta onu yalnız yanıtı saklayan anahtar görür. |
| `stream` | boolean | true ise yanıt olaylarla akar. Varsayılan: false. |
| `user` | string | Yalnız sunucu anahtarıyla dikkate alınır. Kendi sisteminizdeki ziyaretçi kimliği; aynı değer aynı sohbeti bulur. En fazla 64 karakter; daha uzunu reddedilir. Yanıtta yer almaz ve saklanmaz. |
| `safety_identifier` | string | user ile aynı işi görür. İkisi birden gelirse bu kullanılır. En fazla 64 karakter; daha uzunu reddedilir. Sunucu anahtarıyla yanıtta yer alır ve onunla saklanır; tarayıcı anahtarıyla yok sayılır, saklanmaz ve yanıtta yer almaz. |
| `metadata` | object | Yanıtta olduğu gibi geri gelir, sohbeti bulmak için kullanılmaz. Saklanan yanıtta onu yalnız yanıtı saklayan anahtar görür. En fazla 16 anahtar; anahtar en fazla 64 karakter, değer en fazla 512 karakterlik metin; tamamı JSON olarak en fazla 4 KB. |

`conversation` yerine `X-Sone-Conversation-Id` başlığını da kullanabilirsiniz. `conversation` ile `previous_response_id` birlikte gelirse istek `400 conflicting_parameters` alır.

`input` içindeki `system` ve `developer` mesajları `instructions` gibi [geliştirici bağlamıdır](https://docs.sonecentral.com/kimlik-dogrulama.md#gelistirici-baglami). Geri gönderdiğiniz asistan mesajları ve `item_reference` öğeleri sohbeti bulmak için okunur: [Sohbet sürekliliği](https://docs.sonecentral.com/sohbet-surekliligi.md#sohbet-nasil-bulunur).

`temperature`, `top_p`, `max_output_tokens`, `reasoning`, `text.verbosity`, `tool_choice`, `truncation` ve benzeri model ayarları yok sayılır. `max_output_tokens` yanıtta olduğu gibi geri gelir ama yanıtın uzunluğunu değiştirmez. Şunlar reddedilir:

| Ne | Hata |
| --- | --- |
| `tools` ya da `function_call` gibi işlev çağrısı öğeleri | `400 tools_not_supported` |
| `background: true` | `400 unsupported_parameter` |
| `text.format`, `text` dışında | `400 unsupported_parameter` |
| Yeni mesajda görsel ya da dosya parçası | `400 unsupported_content` |
| Tanınmayan bir girdi öğesi türü | `400 unsupported_item` |

`reasoning` öğeleri sessizce atlanır.

## Yanıt

```json
{
  "id": "resp_7c1e9a4f2b8d6e3a0f5c9b2d7e4a1c8f",
  "object": "response",
  "created_at": 1760866200,
  "completed_at": 1760866203,
  "status": "completed",
  "model": "k3m9x2p7q1w8e4r",
  "previous_response_id": null,
  "conversation": { "id": "conv_x8k2m9p4q7w1r3t" },
  "output": [
    {
      "type": "message",
      "id": "msg_w8e4rk3m9x2pq7a",
      "status": "completed",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "Elbette. Hangi gün size uygun?",
          "annotations": [],
          "logprobs": []
        }
      ],
      "sone": {
        "id": "msg_w8e4rk3m9x2pq7a",
        "role": "assistant",
        "type": "text",
        "text": "Elbette. Hangi gün size uygun?",
        "created_at": 1760866203
      }
    }
  ],
  "usage": {
    "input_tokens": 10,
    "input_tokens_details": { "cached_tokens": 0 },
    "output_tokens": 8,
    "output_tokens_details": { "reasoning_tokens": 0 },
    "total_tokens": 18
  },
  "sone": { "conversation_id": "conv_x8k2m9p4q7w1r3t", "status": "answered" }
}
```

Örnek kısaltıldı; yanıt OpenAI'nin tanımladığı diğer alanları da taşır. `usage` [Chat Completions](https://docs.sonecentral.com/chat-completions.md)'taki gibi uzunluktan tahmin edilir.

Asistanın gönderdiği her mesaj ayrı bir `message` öğesidir; öğenin `id`'si mesajın Sonecentral'daki kimliğidir. Ürün kartı, düğme ya da dosya içeren bir mesajda da `content` düz metin karşılığını taşır; yapılandırılmış hali öğenin `sone` alanındadır. Biçimi: [Zengin mesajlar](https://docs.sonecentral.com/zengin-mesajlar.md).

Yanıtın üst düzeyindeki `sone` sohbetin kimliğini ve turun durumunu verir. `status` değerleri [Chat Completions](https://docs.sonecentral.com/chat-completions.md) sayfasındakiyle aynıdır. `human` ve `silent` turlarında `output` boş olur. Sohbetin kimliği ayrıca `X-Sone-Conversation-Id` yanıt başlığında gelir.

## Saklanan yanıtlar

`store` açıksa yanıt saklanır. Varsayılan budur. Saklanan yanıtlar 30 gün sonra silinir; sohbetin kendisi Mesajlar ekranında kalır.

| Uç nokta | Ne yapar |
| --- | --- |
| `GET /responses/{id}` | Yanıtı aynı biçimde döner. |
| `GET /responses/{id}/input_items` | Bu istekte gönderdiğiniz kendi girdi öğelerini liste olarak döner. Varsayılan sıra yeniden eskiye; `?order=asc` eskiden yeniye verir. Liste tek sayfadır, `has_more` her zaman `false` olur. |
| `DELETE /responses/{id}` | Saklanan yanıtı siler: `{ "id": "resp_…", "object": "response.deleted", "deleted": true }`. Yalnız yanıtı saklayan anahtarla çalışır. Sohbetin kendisi silinmez. |
| `POST /responses/{id}/cancel` | Yanıt varsa her zaman `400 not_cancellable` döner. Yanıtlar istek içinde tamamlanır, iptal edilecek arka plan işi yoktur. |

Saklanan yanıt, girdiden yalnız isteğin kendi öğelerini tutar: ziyaretçinin yeni mesajları (son asistan öğesinden sonraki kullanıcı mesajları), `item_reference` öğeleri ve sunucu anahtarıyla `system` ile `developer` mesajları. Tarayıcı anahtarının `system` ve `developer` mesajları, `instructions` gibi, kullanılmaz ve saklanmaz. Yeniden gönderdiğiniz geçmiş saklanmaz; onu sohbetin kendisi tutar. Bu öğelerden en fazla 40'ı ve JSON olarak toplam 8 KB saklanır, en yenileri önce. En yeni öğe her zaman saklanır, 8 KB'a sığmıyorsa metni sonundan kısaltılarak; her öğenin metni en fazla 4.000 karakterdir. Kimliği olmayan öğelere, girdideki yerine göre `resp_…_in_0` gibi bir kimlik verilir.

Yanıtla saklanan istek alanlarının hepsi sınırlıdır: `instructions` en fazla 2.000 karakter, `metadata` en fazla 16 anahtar, `safety_identifier` ve `user` en fazla 64 karakter, bir `item_reference` kimliği en fazla 64 karakter. `instructions` ve `metadata` ayrıca JSON olarak en fazla 4 KB olabilir: karakter sınırı içinde kalsa da, örneğin dört baytlık karakterlerle, daha büyük olanı reddedilir. Sınırı aşan istek `400` alır ve hiçbir şey saklanmaz. `previous_response_id` boşlukları atılmış haliyle saklanır; bir yanıt kimliğinden uzunsa istek `400 previous_response_id_too_long` alır.

Aynı mesajı yeniden gönderdiğinizde, aynı `Idempotency-Key` ile ya da aynı `previous_response_id` ve aynı `input` ile, asistan yeniden yanıt vermez ve yeni bir yanıt saklanmaz: ilk yanıt aynı kimlikle döner. Sohbet ekipteyken de aynı `Idempotency-Key` ile ya da aynı `previous_response_id` ve aynı `input` ile gelen deneme ilk yanıtı aynı kimlikle alır.

Saklanan bir yanıta, yanıtın asistanını çağırabilen her anahtar kimliğiyle ulaşır: yanıtı ve girdi öğelerini okur, `previous_response_id` ile sohbeti sürdürür. Anahtarın çağıramadığı bir asistanın yanıtı ona yokmuş gibi görünür: `404 response_not_found`, `previous_response_id`'de `404 previous_response_not_found`.

Geliştirici bağlamınız, `metadata` değerleriniz ve gönderdiğiniz son kullanıcı kimliği yalnız yanıtı saklayan anahtara geri döner. Başka bir anahtar yanıtı `instructions`, `safety_identifier` ve `user` alanları `null`, `metadata` alanı boş (`{}`) olarak okur; girdi öğelerinde `system` ve `developer` mesajlarını görmez. Yanıtı yalnız onu saklayan anahtar silebilir; başka bir anahtarın silme isteği `404 response_not_found` alır. Bir anahtarı yenileyip eskisini iptal ettiğinizde eskisinin sakladığı yanıtlar 30 gün sonra kendiliğinden silinir.

Yanıt kimlikleri tahmin edilemeyecek kadar uzundur ama yine de onları sır gibi saklayın.

```ts
const stored = await client.responses.retrieve('resp_7c1e9a4f2b8d6e3a0f5c9b2d7e4a1c8f');
const items = await client.responses.inputItems.list('resp_7c1e9a4f2b8d6e3a0f5c9b2d7e4a1c8f');
await client.responses.delete('resp_7c1e9a4f2b8d6e3a0f5c9b2d7e4a1c8f');
```

## Akış

`"stream": true` ile olaylar OpenAI'nin tanımladığı sırayla gelir. Her olayda 0'dan başlayıp birer artan bir `sequence_number` vardır. Her asistan mesajı kendi öğesini açar ve kapatır:

```txt
event: response.created
data: {"type":"response.created","sequence_number":0,"response":{"id":"resp_7c1e","status":"in_progress","conversation":{"id":"conv_x8k2m9p4q7w1r3t"},"output":[]}}

event: response.in_progress
data: {"type":"response.in_progress","sequence_number":1,"response":{"id":"resp_7c1e","status":"in_progress"}}

: sone.activity {"label":"Uygun saatlere bakılıyor"}

event: response.output_item.added
data: {"type":"response.output_item.added","sequence_number":2,"output_index":0,"item":{"type":"message","id":"msg_w8e4","status":"in_progress","role":"assistant","content":[],"sone":{…}}}

event: response.content_part.added
data: {"type":"response.content_part.added","sequence_number":3,"item_id":"msg_w8e4","output_index":0,"content_index":0,"part":{"type":"output_text","text":"","annotations":[],"logprobs":[]}}

event: response.output_text.delta
data: {"type":"response.output_text.delta","sequence_number":4,"item_id":"msg_w8e4","output_index":0,"content_index":0,"delta":"Elbette. Hangi gün size ","logprobs":[]}

event: response.output_text.delta
data: {"type":"response.output_text.delta","sequence_number":5,"item_id":"msg_w8e4","output_index":0,"content_index":0,"delta":"uygun?","logprobs":[]}

event: response.output_text.done
data: {"type":"response.output_text.done","sequence_number":6,"item_id":"msg_w8e4","output_index":0,"content_index":0,"text":"Elbette. Hangi gün size uygun?","logprobs":[]}

event: response.content_part.done
data: {"type":"response.content_part.done","sequence_number":7,"item_id":"msg_w8e4","output_index":0,"content_index":0,"part":{"type":"output_text","text":"Elbette. Hangi gün size uygun?","annotations":[],"logprobs":[]}}

event: response.output_item.done
data: {"type":"response.output_item.done","sequence_number":8,"output_index":0,"item":{"type":"message","id":"msg_w8e4","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Elbette. Hangi gün size uygun?","annotations":[],"logprobs":[]}],"sone":{…}}}

event: response.completed
data: {"type":"response.completed","sequence_number":9,"response":{"id":"resp_7c1e","status":"completed","sone":{"conversation_id":"conv_x8k2m9p4q7w1r3t","status":"answered"}}}
```

Örnekteki nesneler kısaltıldı; gerçek olaylar alanların tamamını taşır.

`: sone.activity` satırı bir olay değil, bir SSE yorumudur: asistan bir araç kullanırken "Uygun saatlere bakılıyor" gibi kısa bir durumu `label` alanında verir. `sequence_number` taşımaz. OpenAI SDK'ları yorum satırlarını atlar; bu durumu göstermek istiyorsanız akışı kendiniz ayrıştırın ve `: sone.activity ` ile başlayan satırın geri kalanını JSON olarak okuyun. `: ping` satırları da yorumdur.

**OpenAI JS**

```ts
import OpenAI from 'openai';

const stream = await client.responses.create({
  model: 'default',
  input: 'Saç boyası için randevu almak istiyorum.',
  stream: true,
});

try {
  for await (const event of stream) {
    if (event.type === 'response.output_text.delta') process.stdout.write(event.delta);
    if (event.type === 'response.output_item.done') process.stdout.write('\n');
  }
} catch (error) {
  // Akış başladıktan sonraki bir hata: SDK error olayını APIError olarak fırlatır.
  if (error instanceof OpenAI.APIError) console.error(error.code, error.message);
  else throw error;
}
```

**OpenAI Python**

```python
stream = client.responses.create(
    model="default",
    input="Saç boyası için randevu almak istiyorum.",
    stream=True,
)

for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)
    elif event.type == "response.output_item.done":
        print()
    elif event.type == "error":
        print(event.code, event.message)
```

Akış başladıktan sonra bir hata olursa önce `code` ve `message` taşıyan bir `error` olayı, ardından `response.failed` gelir ve akış kapanır. Responses akışında `data: [DONE]` yoktur; akış `response.completed` ya da `response.failed` ile biter. OpenAI'nin Node SDK'sı `error` olayında hata fırlatır; Python SDK'sı onu `type` değeri `"error"` olan bir olay olarak verir. Ayrıntılar: [Hatalar](https://docs.sonecentral.com/hatalar.md#akis-sirasinda-hata).

## Hatalar

| Durum | `code` | Ne zaman |
| --- | --- | --- |
| `400` | `missing_input` | `input` yok. |
| `400` | `invalid_input` | `input` bir metin ya da öğe dizisi değil. |
| `400` | `invalid_role` | Bir mesaj öğesinin rolü yok ya da tanınmıyor. |
| `400` | `missing_user_message` | Son öğe ziyaretçinin metin mesajı değil. |
| `400` | `unsupported_item` | Tanınmayan bir girdi öğesi türü var. |
| `400` | `conflicting_parameters` | `previous_response_id` ile `conversation` birlikte gönderildi. |
| `400` | `instructions_too_long` | `instructions` 2.000 karakterden ya da JSON olarak 4 KB'tan uzun. |
| `400` | `invalid_metadata` | `metadata` sınırı aşıyor (16 anahtar, 64 ve 512 karakter, JSON olarak 4 KB) ya da bir değeri metin değil. |
| `400` | `safety_identifier_too_long` | `safety_identifier` 64 karakterden uzun. |
| `400` | `user_too_long` | `user` 64 karakterden uzun. |
| `400` | `previous_response_id_too_long` | `previous_response_id`, boşlukları atıldıktan sonra bir yanıt kimliğinden uzun. |
| `400` | `item_id_too_long` | Bir `item_reference` kimliği 64 karakterden uzun. |
| `400` | `not_cancellable` | `cancel` çağrıldı. |
| `400` | `conversation_model_mismatch` | Sohbet başka bir asistanla açılmış. |
| `404` | `response_not_found` | Yanıt yok, silinmiş, 30 günü geçmiş, `store: false` ile üretilmiş, başka bir çalışma alanına ait ya da anahtarınızın çağıramadığı bir asistanın sohbetinde. Silmede ayrıca: yanıtı başka bir anahtar saklamış. |
| `404` | `previous_response_not_found` | `previous_response_id` ile gösterilen yanıt bulunamadı ya da anahtarınızın çağıramadığı bir asistanın sohbetinde. |
| `404` | `conversation_not_found` | `conversation` bu çalışma alanında bir API sohbeti değil. |
| `409` | `conversation_busy` | Aynı sohbette önceki mesaj hâlâ yanıtlanıyor. |

Bütün kodlar: [Hatalar](https://docs.sonecentral.com/hatalar.md).
