This API is being deprecated in favor of the /chat/send-chat-message API,
it will be removed by end of Jan 2026.
Simple Chat Flow
Send Message Simple API is the quickest way to interact with Gorbit programmatically. This endpoint has fewer required parameters and returns a concise JSON payload described byChatBasicResponse.
You must specify either a
chat_session_id or a persona_id in your request.import requests
API_BASE_URL = "https://cloud.gorbit.app/api" # or your own domain
API_KEY = "YOUR_KEY_HERE"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
'''
- To create a chat session, see the Full-featured Chat Flow guide below.
- To find your persona_id, see the List Agents endpoint in the Agents API Reference.
'''
response = requests.post(
f"{API_BASE_URL}/chat/send-message-simple-api",
headers=headers,
json={
"message": "What is Gorbit?",
"persona_id": 0 # The default Gorbit Search Agent (int)
}
)
data = response.json()
answer = data.get("answer")
answer_citationless = data.get("answer_citationless")
message_id = data.get("message_id")
docs = data.get("top_documents") or []
top_documents = [
{
"id": doc.get("document_id"),
"title": doc.get("semantic_identifier"),
"link": doc.get("link")
} for doc in docs
]
cited_docs_map = data.get("cited_documents") or {}
print(f"Answer: {answer}")
print(f"Answer (citationless): {answer_citationless}")
print(f"Message ID: {message_id}")
print(f"Top Documents: {top_documents[:5]}") # Print top 5 documents
print(f"Citations map: {cited_docs_map}")
#!/bin/bash
API_BASE_URL="https://cloud.gorbit.app/api"
API_KEY="YOUR_KEY_HERE"
echo "Sending message to Gorbit..."
RESPONSE=$(curl -s -X POST "${API_BASE_URL}/chat/send-message-simple-api" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"message": "What is Gorbit?",
"persona_id": 0
}'
)
echo "Answer:"
echo $RESPONSE | jq -r '.answer'
echo -e "\nAnswer (citationless):"
echo $RESPONSE | jq -r '.answer_citationless'
echo -e "\nMessage ID:"
echo $RESPONSE | jq -r '.message_id'
echo -e "\nTop Documents:"
echo $RESPONSE | jq '.top_documents | .[] | {id: .document_id, title: .semantic_identifier, link: .link}'
Advanced Chat Flow
The/send-message endpoint is what the Gorbit frontend uses to send and receive messages.
Responses are streamed back in packets of JSON objects.
To understand the response format, see the Core Concepts documentation.
1
Prepare your request
import requests
API_BASE_URL = "https://cloud.gorbit.app/api" # or your own domain
API_KEY = "YOUR_KEY_HERE"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
API_BASE_URL="https://cloud.gorbit.app/api"
API_KEY="YOUR_KEY_HERE"
2
Create a chat session
session_response = requests.post(
f"{API_BASE_URL}/chat/create-chat-session",
headers=headers,
json={
"persona_id": 0, # The default Gorbit Search Agent
"description": "Gorbit API Guide Chat Session"
}
)
chat_session_id = session_response.json()["chat_session_id"]
CHAT_SESSION_RESPONSE=$(curl -s -X POST "${API_BASE_URL}/chat/create-chat-session" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"persona_id": 0,
"description": "Gorbit API Guide Chat Session"
}'
)
# Extract chat session ID (requires jq for JSON parsing)
CHAT_SESSION_ID=$(echo $CHAT_SESSION_RESPONSE | jq -r '.chat_session_id')
3
Send message
payload = {
"chat_session_id": chat_session_id,
"parent_message_id": None,
"message": "What is Gorbit?",
"file_descriptors": [],
"search_doc_ids": [],
"retrieval_options": {}
}
# Consume the streamed packets fully and then print a summary
# NOTE: The first packet always contains message IDs:
# {"user_message_id": int, "reserved_assistant_message_id": int}
with requests.post(
f"{API_BASE_URL}/chat/send-message",
headers=headers,
json=payload,
stream=True,
) as resp:
resp.raise_for_status()
full_text = []
docs_raw = None
citations_map = {}
user_message_id = None
reserved_assistant_message_id = None
# Each line is a JSON Packet: { ind: int, obj: { type: "...", ... } }
for line in resp.iter_lines(decode_unicode=True):
if not line:
continue
try:
packet = json.loads(line)
except Exception:
continue
# First packet: message IDs
if "user_message_id" in packet and "reserved_assistant_message_id" in packet:
user_message_id = packet.get("user_message_id")
reserved_assistant_message_id = packet.get("reserved_assistant_message_id")
continue
obj = packet.get("obj", {})
ptype = obj.get("type")
if ptype == "message_start":
# Includes final search documents per API spec
docs_raw = obj.get("final_documents") or docs_raw
elif ptype == "message_delta":
delta = obj.get("content", "")
full_text.append(delta)
elif ptype == "citation_delta":
# Update citation map using citation_num -> document_id pairs
if isinstance(obj.get("citations"), list):
for c in obj["citations"]:
cnum = c.get("citation_num")
did = c.get("document_id")
if cnum is not None and did is not None:
citations_map[str(cnum)] = str(did)
elif ptype == "stop":
break
# Prepare documents (id/title/link) if present
top_documents = []
if isinstance(docs_raw, list):
for d in docs_raw:
top_documents.append(
{
"id": d.get("document_id") or d.get("id"),
"title": d.get("semantic_identifier") or d.get("title"),
"link": d.get("link") or d.get("url"),
}
)
print("Final Answer:\n" + "".join(full_text))
if user_message_id is not None:
print(f"\nUser message ID: {user_message_id}")
if reserved_assistant_message_id is not None:
print(f"Reserved assistant message ID: {reserved_assistant_message_id}")
print("\nTop Documents:")
print(json.dumps(top_documents, indent=2))
print("\nCitations map (citation_num -> document_id):")
print(json.dumps(citations_map, indent=2))
# Read streamed response to completion (no live token rendering)
curl -s -N -X POST "${API_BASE_URL}/chat/send-message" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d "{
\"chat_session_id\": \"${CHAT_SESSION_ID}\",
\"parent_message_id\": null,
\"message\": \"What is Gorbit?\",
\"file_descriptors\": [],
\"search_doc_ids\": [],
\"retrieval_options\": {}
}" \
| (
TEXT=""
DOCS_JSON=""
CITS_JSON='{}'
USER_MSG_ID=""
RESERVED_ASST_ID=""
while IFS= read -r line; do
[ -z "$line" ] && continue
# First packet contains message IDs
uid=$(echo "$line" | jq -r '.user_message_id // empty')
rid=$(echo "$line" | jq -r '.reserved_assistant_message_id // empty')
if [ -n "$uid" ] || [ -n "$rid" ]; then
[ -n "$uid" ] && USER_MSG_ID="$uid"
[ -n "$rid" ] && RESERVED_ASST_ID="$rid"
continue
fi
type=$(echo "$line" | jq -r '.obj.type // empty')
if [ "$type" = "message_start" ]; then
docs=$(echo "$line" | jq -c '(.obj.final_documents) // empty')
if [ -n "$docs" ] && [ -z "$DOCS_JSON" ]; then
DOCS_JSON="$docs"
fi
elif [ "$type" = "message_delta" ]; then
delta=$(echo "$line" | jq -r '.obj.content // empty')
TEXT+="$delta"
elif [ "$type" = "citation_delta" ]; then
newmap=$(echo "$line" | jq -c '
if (.obj.citations // empty) then
(reduce (.obj.citations // [])[] as $c ({}; .[($c.citation_num|tostring)] = ($c.document_id|tostring)))
else
{}
end')
CITS_JSON=$(jq -c --argjson A "$CITS_JSON" --argjson B "$newmap" '$A * $B' <<< '{}')
elif [ "$type" = "stop" ]; then
break
fi
done
echo "Final Answer:"
printf "%s\n" "$TEXT"
echo
if [ -n "$USER_MSG_ID" ]; then
echo "User message ID: $USER_MSG_ID"
fi
if [ -n "$RESERVED_ASST_ID" ]; then
echo "Reserved assistant message ID: $RESERVED_ASST_ID"
fi
echo
echo "Top Documents:"
if [ -z "$DOCS_JSON" ]; then
echo "[]"
else
echo "$DOCS_JSON" | jq -c '[.[] | {id: (.document_id // .id), title: (.semantic_identifier // .title), link: (.link // .url)}]'
fi
echo
echo "Citations map (citation_num -> document_id):"
echo "$CITS_JSON" | jq '.'
)
Next Steps
Guide: Use the Ingestion API
Use the lightweight ingestion API to index documents
Guide: Create a Connector
Learn how to create and configure Connectors programmatically