Skip to content

Yapay Zeka Mesajları ​

Bir oturum içindeki mesajlar. Bir kullanıcı mesajı göndermek, asistan yanıtını oluşturan bir yapay zeka çalışmasını tetikler.

Sohbet Akışı Çözüm Yolu ​

  1. Konuşma geçmişini veya sayfalandırma imlecini görüntülemek için oturuma ait mevcut mesajları getirin (GET /ai/sessions/:sessionId/messages).
  2. Yeni bir kullanıcı mesajı gönderin ('POST /ai/sessions/:sessionId/messages') ve hem 'userMessage'ı hem de 'assistantMessage.runId'yi yakalayın.
  3. Asistan çıktısını GET /ai/sessions/:sessionId/messages/:messageId/stream (veya çalıştırma akışı) yoluyla aktarın ve `message.delta' olaylarını geldiklerinde kullanıcı arayüzüne ekleyin.
  4. Kullanıcı asistanın sözünü keserse, kısmi içeriği sonlandırmak ve "durum: durduruldu"yu göstermek için "POST /ai/sessions/:sessionId/messages/:assistantMessageId/stop" öğesini çağırın.
javascript
const startChat = async (sessionId) => {
  const history = await fetch(
    `${BASE_URL}/ai/sessions/${sessionId}/messages`,
    { headers: { Authorization: `Bearer ${TOKEN}` } }
  );
  console.log("Existing messages:", (await history.json()).data);

  const reply = await fetch(
    `${BASE_URL}/ai/sessions/${sessionId}/messages`,
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${TOKEN}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ content: "Show me a recap of today's tasks." }),
    }
  );
  const {
    assistantMessage: { id: assistantId },
  } = (await reply.json()).data;

  const stream = new EventSource(
    `${BASE_URL}/ai/sessions/${sessionId}/messages/${assistantId}/stream`,
    { headers: { Authorization: `Bearer ${TOKEN}` } }
  );
  stream.addEventListener("message.delta", (event) => {
    const { payload } = JSON.parse(event.data);
    console.log("Delta:", payload.delta);
  });
};

Uç noktalar ​

MethodPathDescriptionAuthRate Limit
GET/ai/sessions/:sessionId/messagesList messagesJWT + Entitlement60/min
POST/ai/sessions/:sessionId/messagesSend a messageJWT + Entitlement20/min
POST/ai/sessions/:sessionId/messages/:assistantMessageId/retriesYeni bir yanıt sürümü oluşturJWT + Entitlement20/min
POST/ai/sessions/:sessionId/messages/:assistantMessageId/selectionBir yanıt sürümünü seçJWT + Entitlement—
GET/ai/sessions/:sessionId/messages/:messageId/streamSSE message streamJWT + Entitlement20/min
POST/ai/sessions/:sessionId/messages/:assistantMessageId/stopStop generationJWT + Entitlement30/min

GET /ai/sessions/:sessionId/messages ​

Tanım ​

İmleç tabanlı veya sayfa tabanlı sayfalandırmayla bir oturumdaki mesajları listeleyin.

Kimlik Doğrulama: JWT Taşıyıcı jetonu + aktif AI yetkisi gereklidir. Hız sınırı: 60/dak

Rica etmek ​

  • Başlıklar: Authorization: Bearer <token>
  • Yol parametreleri: sessionId
Sorgu Parametreleri ​
ParameterTypeRequiredDescription
limitnumberNoNumber of messages to return
cursorstringNoCursor for cursor-based pagination
offsetnumberNoOffset for page-based pagination
chainyIdstringNoFilter by Chainy. Returns 404 if the session is not associated with this Chainy.

Cevap ​

Yanıt Örneği ​
json
{
  "data": [
    {
      "id": "cm5msg001",
      "role": "user",
      "content": "How can I improve my vocabulary retention rate?",
      "createdAt": "2026-03-17T10:05:00.000Z"
    },
    {
      "id": "cm5msg002",
      "role": "assistant",
      "content": "Spaced repetition is one of the most effective techniques...",
      "status": "completed",
      "toolCalls": [
        {
          "id": "tc_abc123",
          "toolKey": "memory.search",
          "input": { "query": "vocabulary retention" },
          "status": "completed",
          "output": { "total": 2 },
          "error": null,
          "executionMs": 64
        }
      ],
      "suggestions": [
        {
          "suggestion": "Can you turn that into a 7-day vocabulary executable workflow?",
          "priority": 1
        },
        {
          "suggestion": "What should I do when I keep forgetting the same words?",
          "priority": 2
        }
      ],
      "tokensUsed": 850,
      "createdAt": "2026-03-17T10:05:00.000Z"
    }
  ],
  "meta": {
    "cursor": "eyJpZCI6ImNtNW1zZzAwMiJ9",
    "hasMore": false,
    "total": 2
  }
}
Yanıt Alanları ​
FieldTypeDescription
idstringMessage ID
rolestringuser or assistant
contentstring | nullMessage content
statusstringAssistant messages: running, completed, stopped, failed
suggestionsobject[]Follow-up suggestion cards returned separately from the assistant markdown. Empty when disabled, unavailable, or not generated.
runIdstring | nullID of the AI run that produced this message. Use this to attach a stream listener on page reload. Present on all assistant messages once the run is created.
toolCallsobject[] | nullFor Chao sessions: list of tool calls made during this message. See Tool Call Fields below.
modelIdstring | nullID of the model that generated the response
modelNamestring | nullDisplay name of the model
providerKeystring | nullProvider identifier (e.g. "anthropic", "openai")
createdAtstringISO 8601
Takım Çağrı Alanları ​

'toolCalls'daki her giriş, bu mesaj sırasında Chao tarafından çağrılan bir aracı temsil eder:

FieldTypeDescription
idstringTool call ID (matches SSE callId, toolCallId, or stepId)
toolKeystringTool name (e.g. "bits.create", "chainies.list")
inputobjectArguments Chao passed to the tool
statusstringpending, executing, completed, failed, degraded, rejected, or skipped
outputobject | nullTool result (present when status is completed)
errorstring | nullError message (present when status is failed)
executionMsnumber | nullExecution duration in milliseconds

'toolCalls' kalıcıdır ve her geçmiş isteğinde döndürülür. Sayfa yeniden yüklendiğinde, bu alandan araç kartlarını yeniden oluşturun ve yardımcı mesajın hala etkin bir "runId"si varsa bir akış dinleyicisini yeniden ekleyin.

Canlı SSE yüklerini aynı kart şekline göre normalleştirin:

Normalized fieldPreferred lookup
toolKeypayload.toolKey ?? payload.key
callIdpayload.callId ?? payload.toolCallId ?? envelope.stepId
inputpayload.input ?? payload.args
outputpayload.data ?? payload.output

'payload.activity' mevcut olduğunda, bu nesneden kart başlığını, ayrıntısını, durumunu ve konusunu işleyin.

Kod Örnekleri ​

Oturum Oluştur'ın yanıtındaki ("data.id") "id"yi "$SESSION_ID" olarak kullanın. Zincirli filtre için, Create Chainy öğesindeki "kimliği" "$CHAINY_ID" olarak kullanın.

bash
curl "https://api.chainabit.com/api/v1/ai/sessions/$SESSION_ID/messages?limit=20" \
  -H "Authorization: Bearer $TOKEN"

# Filter by Chainy:
curl "https://api.chainabit.com/api/v1/ai/sessions/$SESSION_ID/messages?limit=20&chainyId=$CHAINY_ID" \
  -H "Authorization: Bearer $TOKEN"
javascript
const sessionId = process.env.SESSION_ID; // id from Create a Session's response

const params = new URLSearchParams({ limit: "20" });
const res = await fetch(
  `${BASE_URL}/ai/sessions/${sessionId}/messages?${params}`,
  { headers: { Authorization: `Bearer ${TOKEN}` } }
);
const { data, meta } = await res.json();

// Filter by Chainy:
const chainyId = process.env.CHAINY_ID; // id of an existing Chainy (see Create Chainy)

const chainyParams = new URLSearchParams({
  limit: "20",
  chainyId,
});
const chainyRes = await fetch(
  `${BASE_URL}/ai/sessions/${sessionId}/messages?${chainyParams}`,
  { headers: { Authorization: `Bearer ${TOKEN}` } }
);
python
import os
import requests

session_id = os.environ["SESSION_ID"]  # id from Create a Session's response

res = requests.get(
    f"{BASE_URL}/ai/sessions/{session_id}/messages",
    headers={"Authorization": f"Bearer {TOKEN}"},
    params={"limit": 20},
)
body = res.json()

# Filter by Chainy:
chainy_id = os.environ["CHAINY_ID"]  # id of an existing Chainy (see Create Chainy)

chainy_res = requests.get(
    f"{BASE_URL}/ai/sessions/{session_id}/messages",
    headers={"Authorization": f"Bearer {TOKEN}"},
    params={
        "limit": 20,
        "chainyId": chainy_id,
    },
)

POST /ai/sessions/:sessionId/messages ​

Tanım ​

Asistan yanıtını oluşturmak için bir yapay zeka çalışmasını tetikleyen bir oturuma kullanıcı mesajı gönderin.

Kimlik Doğrulama: JWT Taşıyıcı jetonu + aktif AI yetkisi gereklidir. Hız sınırı: 20/dak

Rica etmek ​

  • Başlıklar: Authorization: Bearer <token>, Content-Type: application/json
  • Yol parametreleri: sessionId
Talep Gövdesi ​
FieldTypeRequiredConstraintsDescription
contentstringYesNon-empty, ≤ 20,000 charactersMessage content. The 20,000-character cap applies to every caller, including the seed message returned by feature endpoints such as POST /productivity/priority-analysis/runs.
modelstringNoActive model keyOverride the model for this message
effortModestringNo"basic", "thinking", or "pro"High-level model tier preference. basic uses a standard model, thinking selects a thinking-capable model, pro selects the highest-capability tier. Overrides the session-level effortMode if both are set. Exact model selection remains a backend hint.
providerstringNoLowercase identifier (e.g. openai)AI provider key. Requires a paid plan with the corresponding provider entitlement.
capabilityKeystringNoai.search.web, ai.research.deep, ai.image.generate, ai.video.generate, ai.audio.generateExplicit Chao capability to execute deterministically. When set, the matching capability-specific parameters are accepted (see Capability Parameters).
attachmentIdsstring[]NoValid file IDsArray of file IDs to attach
memoryIdsstring[]NoValid memory IDsOptional memory items to pin into the run
idempotencyKeystringNo—Client-side dedupe key for retries
parametersobjectNoCapability-specific paramsLong-term contract for capability-specific parameters. See Capability Parameters.
structuredBlocksobject[]NoMention/media blocksStructured user-side blocks such as agent mentions or media references

Yeteneğe özgü alanlar ("durationSeconds", "aspectRatio", "generateAudio" vb. gibi) da geriye dönük uyumluluk için üst düzeyde gönderilebilir. Aşağıdaki bölüme bakın.

Yetenek Parametreleri ​

'capabilityKey' ayarlandığında mesaj uç noktası, yeteneğin bildirdiği parametreleri kabul eder. İki eşdeğer istek şekli desteklenir:

  1. Üst düzey alanlar (mevcut istemci uyumluluğu):
    json
    {
      "content": "lo-fi beat with a deep bass line",
      "capabilityKey": "ai.audio.generate",
      "durationSeconds": 20,
      "bpm": 90,
      "styleTokens": ["lo-fi", "chill"]
    }
  2. İç içe geçmiş 'parametreler' nesnesi (uzun vadeli sözleşme, yeni kod için önerilir):
    json
    {
      "content": "lo-fi beat with a deep bass line",
      "capabilityKey": "ai.audio.generate",
      "parameters": {
        "durationSeconds": 20,
        "bpm": 90,
        "styleTokens": ["lo-fi", "chill"]
      }
    }

Her iki form da mevcut olduğunda, çarpışma durumunda iç içe değerler kazanır.

Yetenek başına kabul edilen parametreler:

capabilityKeyAccepted parameters
ai.audio.generatedurationSeconds (5–30), bpm (40–220), styleTokens (string[], ≤16 items, ≤64 chars each). See Audio Generation.
ai.image.generateaspectRatio (W:H), quality (standard|hd|auto), numImages / numberOfImages (alias for count, 1–4), seed, negativePrompt (≤4000 chars), size (1024x1024|1792x1024|1024x1792), style (vivid|natural), resolution, provider, model, activeImageId. See Generative Media.
ai.video.generateaspectRatio (16:9|9:16|1:1|4:3|3:4|21:9), duration (1–60, accepts numeric strings), resolution (480p|720p|1080p|4k), size (WxH), generateAudio, negativePrompt, seed, styleTokens, inputImageUrl, inputVideoUrl, referenceImages[], referenceVideos[], provider (kling|veo|sora), model. See Video Generation.
ai.search.webmaxResults (1–20)
ai.research.deepdepth (standard|deep)

Seçilenden farklı bir yeteneğe ait olan yetenek alanları kesin bir hatayla reddedilir ("bpm yalnızca ai.audio.generate için geçerlidir"). Gerçekten bilinmeyen alanlar da 'bilinmeyen X özelliği' ile reddedilir. Sade sohbet ("capabilityKey" yok) orijinal DTO sözleşmesini korur; ekstra alanlar hâlâ reddedilir.

Cevap ​

Yanıt Örneği ​
json
{
  "data": {
    "sessionId": "$SESSION_ID",
    "userMessage": {
      "id": "cm5msg001",
      "role": "user",
      "content": "How can I improve my vocabulary retention rate? I keep forgetting words after a few days.",
      "createdAt": "2026-03-17T10:05:00.000Z"
    },
    "assistantMessage": {
      "id": "cm5msg002",
      "role": "assistant",
      "content": "",
      "suggestions": [],
      "createdAt": "2026-03-17T10:05:00.000Z"
    },
    "run": {
      "id": "cm5run003",
      "status": "queued"
    }
  }
}

Asistan mesaj kabuğu, "öneriler: []" ile hemen döndürülür. Öneriler, asistan yanıtını yazan aynı model çağrı tarafından üretilir ve geçmiş okumaları ve "message.suggestions" SSE olayı aracılığıyla "message.completed" ile aynı onay işaretinde iletilir.

Yanıt Alanları ​
FieldTypeDescription
userMessage.idstringUser message ID
userMessage.rolestringAlways user
userMessage.contentstringMessage content
userMessage.createdAtstringISO 8601
assistantMessage.idstringAssistant message ID
assistantMessage.rolestringAlways assistant
assistantMessage.contentstringEmpty string while generating
assistantMessage.suggestionsobject[]Always [] in the immediate POST response shell
run.idstringAssociated AI run ID
run.statusstringInitial run status, usually queued
Hata Örneği ​
json
{
  "error": {
    "code": "bad_request",
    "message": "bpm is only valid for ai.audio.generate; unknown property foo",
    "details": {
      "fields": [
        { "field": "bpm", "message": "bpm is only valid for ai.audio.generate", "capabilityKey": "ai.audio.generate" },
        { "field": "foo", "message": "unknown property foo" }
      ]
    }
  },
  "meta": { "requestId": "<request-id>" }
}

Kod Örnekleri ​

Oturum Oluştur'ın yanıtındaki ("data.id") "id"yi "$SESSION_ID" olarak kullanın.

bash
curl -X POST https://api.chainabit.com/api/v1/ai/sessions/$SESSION_ID/messages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "How can I improve my vocabulary retention rate? I keep forgetting words after a few days."
  }'
javascript
const sessionId = process.env.SESSION_ID; // id from Create a Session's response

const res = await fetch(`${BASE_URL}/ai/sessions/${sessionId}/messages`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    content:
      "How can I improve my vocabulary retention rate? I keep forgetting words after a few days.",
  }),
});
const { data } = await res.json();
python
import os
import requests

session_id = os.environ["SESSION_ID"]  # id from Create a Session's response

res = requests.post(
    f"{BASE_URL}/ai/sessions/{session_id}/messages",
    headers={
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json",
    },
    json={
        "content": "How can I improve my vocabulary retention rate? I keep forgetting words after a few days."
    },
)
data = res.json()["data"]

POST /ai/sessions/:sessionId/messages/:assistantMessageId/retries ​

Aynı kullanıcı turu için yeni bir asistan yanıt sürümü oluşturur. İstemci tarafından üretilen idempotencyKey zorunludur; boş olamaz ve en fazla 200 karakter olabilir.

Yanıt 201 Created olur ve yeni mesaj gönderimiyle aynı mesaj/çalıştırma biçimini kullanır. Doğrulama hataları 400, erişilemeyen oturum veya mesajlar 404 döndürür.

POST /ai/sessions/:sessionId/messages/:assistantMessageId/selection ​

Bir asistan yanıt sürümünü etkin dal olarak seçer. İstek gövdesi yoktur.

201 Created yanıtı data.activeMessageId ve data.selectedMessage alanlarını içerir.


GET /ai/sessions/:sessionId/messages/:messageId/stream ​

Tanım ​

Yardımcı mesaj oluşturulurken artımlı içerik almak için Sunucu Tarafından Gönderilen Olaylar akışına bağlanın.

Kimlik Doğrulama: JWT Taşıyıcı jetonu + aktif AI yetkisi gereklidir. Hız sınırı: 20/dak

Rica etmek ​

  • Başlıklar: Authorization: Bearer <token>, Accept: text/event-stream
  • Yol parametreleri: sessionId, messageId

Cevap ​

Yanıt Örneği ​
event: message.delta
data: {"eventId":1,"type":"message.delta","runId":"cm5run003","payload":{"delta":"Spaced repetition is one of the most "}}

event: message.delta
data: {"eventId":2,"type":"message.delta","runId":"cm5run003","payload":{"delta":"effective techniques for long-term retention. "}}

event: message.delta
data: {"eventId":3,"type":"message.delta","runId":"cm5run003","payload":{"delta":"Here are some strategies tailored to your chain..."}}

event: message.completed
data: {"eventId":4,"type":"message.completed","runId":"cm5run003","payload":{"messageId":"cm5msg002","content":"Spaced repetition is one of the most effective techniques for long-term retention. Here are some strategies tailored to your chain..."}}
Yanıt Alanları ​
FieldTypeDescription
eventstringSSE event type such as message.delta, message.completed, tool.started, tool.completed, run.error
data.payload.deltastringIncremental content token(s) for message.delta
data.payload.contentstringFull assistant content for message.completed
data.payload.messageIdstringAssistant message ID when present

Kod Örnekleri ​

Create a Session'ın yanıtındaki (data.id) '$SESSION_ID'yi kullanın ve Send a message'ın yanıtındaki (data.assistantMessage.id) 'id'yi '$MESSAGE_ID' olarak kullanın.

bash
curl -N "https://api.chainabit.com/api/v1/ai/sessions/$SESSION_ID/messages/$MESSAGE_ID/stream" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: text/event-stream"
javascript
// Browser — uses built-in EventSource (no auth header support)
// For Node.js, install: npm install eventsource
import EventSource from 'eventsource';

const sessionId = process.env.SESSION_ID; // id from Create a Session's response
const messageId = process.env.MESSAGE_ID; // assistantMessage.id from Send a Message's response

const es = new EventSource(
  `${BASE_URL}/ai/sessions/${sessionId}/messages/${messageId}/stream`,
  { headers: { Authorization: `Bearer ${TOKEN}` } }
);

es.addEventListener('message.delta', (e) => {
  const { payload } = JSON.parse(e.data);
  process.stdout.write(payload.delta);
});

es.addEventListener('message.completed', () => es.close());
es.addEventListener('run.error', (e) => {
  const { payload } = JSON.parse(e.data);
  console.error('Run error:', payload.error);
  es.close();
});
python
import os
import sseclient
import requests

session_id = os.environ["SESSION_ID"]  # id from Create a Session's response
message_id = os.environ["MESSAGE_ID"]  # assistantMessage.id from Send a Message's response

response = requests.get(
    f"{BASE_URL}/ai/sessions/{session_id}/messages/{message_id}/stream",
    headers={
        "Authorization": f"Bearer {TOKEN}",
        "Accept": "text/event-stream",
    },
    stream=True,
)
client = sseclient.SSEClient(response)
for event in client.events():
    if event.event == "message.delta":
        print(event.data, end="", flush=True)
    elif event.event == "message.completed":
        break

POST /ai/sessions/:sessionId/messages/:assistantMessageId/stop ​

Tanım ​

Devam eden bir asistan mesajı oluşturma işlemini durdurun.

Kimlik Doğrulama: JWT Taşıyıcı jetonu + aktif AI yetkisi gereklidir. Hız sınırı: 30/dak

Rica etmek ​

  • Başlıklar: Authorization: Bearer <token>
  • Yol parametreleri: sessionId, assistantMessageId

Cevap ​

Yanıt Örneği ​
json
{
  "data": {
    "id": "cm5msg002",
    "status": "stopped",
    "content": "Spaced repetition is one of the most effective techniques for long-term retention. ",
    "stoppedAt": "2026-03-17T10:05:05.000Z"
  }
}
Yanıt Alanları ​
FieldTypeDescription
idstringMessage ID
statusstringAlways stopped
contentstringPartial content generated before stopping
stoppedAtstringISO 8601 timestamp of stop

Kod Örnekleri ​

Create a Session'ın yanıtındaki (data.id) '$SESSION_ID'yi kullanın ve Send a message'ın yanıtındaki (data.assistantMessage.id) 'id'yi şu şekilde kullanın: "$ASSISTANT_MESSAGE_ID".

bash
curl -X POST https://api.chainabit.com/api/v1/ai/sessions/$SESSION_ID/messages/$ASSISTANT_MESSAGE_ID/stop \
  -H "Authorization: Bearer $TOKEN"
javascript
const sessionId = process.env.SESSION_ID; // id from Create a Session's response
const assistantMessageId = process.env.ASSISTANT_MESSAGE_ID; // assistantMessage.id from Send a Message's response

const res = await fetch(
  `${BASE_URL}/ai/sessions/${sessionId}/messages/${assistantMessageId}/stop`,
  {
    method: "POST",
    headers: { Authorization: `Bearer ${TOKEN}` },
  }
);
const { data } = await res.json();
python
import os
import requests

session_id = os.environ["SESSION_ID"]  # id from Create a Session's response
assistant_message_id = os.environ["ASSISTANT_MESSAGE_ID"]  # assistantMessage.id from Send a Message's response

res = requests.post(
    f"{BASE_URL}/ai/sessions/{session_id}/messages/{assistant_message_id}/stop",
    headers={"Authorization": f"Bearer {TOKEN}"},
)
data = res.json()["data"]

Built with purpose.