Conversations API
Retrieve and browse your chatbot's messages programmatically through the Developer API.
Base URL
https://api.peki.ai/api
Authentication
All endpoints require HMAC-SHA256 authentication. See the Messages API guide for full details on signature generation.
Required Headers
| Header | Required | Description |
|---|---|---|
Content-Type | ✅ | Must be application/json |
X-API-Key | ✅ | Your API key (starts with pk_) |
X-Signature | ✅ | HMAC-SHA256 signature |
X-Timestamp | ✅ | Unix timestamp in seconds |
List Messages
Get all messages for your chatbot with pagination. Optionally filter by session or user.
GET /Dev/{chatbotId}/messages
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
chatbotId | string | ✅ | The unique identifier for your chatbot |
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
sessionId | string | ❌ | - | Filter messages by session ID |
userId | string | ❌ | - | Filter messages by user ID |
page | int | ❌ | 1 | Page number (1-based) |
pageSize | int | ❌ | 20 | Number of items per page |
Response
{
"data": [
{
"id": "6612a1b2c3d4e5f6a7b8c9d2",
"chatbotId": "your_chatbot_id",
"chatSessionId": "6612a1b2c3d4e5f6a7b8c9d1",
"chatUserId": "6612a1b2c3d4e5f6a7b8c9d0",
"senderType": "User",
"text": "What are the latest crypto trends?",
"tokenCount": 12,
"responseTime": null,
"createdAt": "2025-04-08T12:00:00Z"
},
{
"id": "6612a1b2c3d4e5f6a7b8c9d3",
"chatbotId": "your_chatbot_id",
"chatSessionId": "6612a1b2c3d4e5f6a7b8c9d1",
"chatUserId": "6612a1b2c3d4e5f6a7b8c9d0",
"senderType": "Bot",
"text": "Based on current market trends, here are the key developments...",
"tokenCount": 350,
"responseTime": 1.25,
"createdAt": "2025-04-08T12:00:02Z"
}
],
"error": null,
"totalItems": 500,
"pageSize": 20,
"currentPage": 1,
"totalPages": 25
}
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the message |
chatbotId | string | The chatbot this message belongs to |
chatSessionId | string | The session this message belongs to |
chatUserId | string | The user who sent or received the message |
senderType | string | Who sent the message: User or Bot |
text | string | The message content (for text messages) |
url | string | Media URL (for media messages) |
tokenCount | int | Number of tokens consumed by this message |
responseTime | number | AI response time in seconds (only for Bot messages) |
createdAt | datetime | When the message was sent |
Get Message
Get a single message by its ID.
GET /Dev/{chatbotId}/messages/{messageId}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
chatbotId | string | ✅ | The unique identifier for your chatbot |
messageId | string | ✅ | The unique identifier for the message |
Response
{
"data": {
"id": "6612a1b2c3d4e5f6a7b8c9d2",
"chatbotId": "your_chatbot_id",
"chatSessionId": "6612a1b2c3d4e5f6a7b8c9d1",
"chatUserId": "6612a1b2c3d4e5f6a7b8c9d0",
"senderType": "User",
"text": "What are the latest crypto trends?",
"tokenCount": 12,
"createdAt": "2025-04-08T12:00:00Z"
},
"error": null
}
Error Response
{
"data": null,
"error": "Message not found."
}
Get Message Count
Get the number of messages within a date range — optionally filtered by sender.
The count and count-by-month endpoints aggregate server-side in a single database query. For analytics and dashboards, use these instead of paging through GET /messages and counting client-side — they are dramatically faster and transfer almost no data, no matter how many messages exist.
GET /Dev/{chatbotId}/messages/count?from={from}&to={to}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
chatbotId | string | ✅ | The unique identifier for your chatbot |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
from | datetime (ISO 8601) | ✅ | Start of the range (inclusive), e.g. 2025-01-01 |
to | datetime (ISO 8601) | ✅ | End of the range (exclusive). Must be after from |
sent | boolean | ❌ | Filter by sender. true = user-sent only, false = non-user (bot/system/agent), omitted = all senders |
Response
{
"data": 1234,
"error": null
}
The data field is the number of messages in the range, respecting the sent filter when provided.
Examples
GET /Dev/{chatbotId}/messages/count?from=2025-01-01&to=2025-02-01 # all messages
GET /Dev/{chatbotId}/messages/count?from=2025-01-01&to=2025-02-01&sent=true # user-sent only
Error Response
{
"data": 0,
"error": "`to` must be greater than `from`."
}
Get Message Counts by Month
Get message metrics aggregated per calendar month across a date range — useful for usage dashboards, growth tracking, and billing.
GET /Dev/{chatbotId}/messages/count-by-month?from={from}&to={to}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
chatbotId | string | ✅ | The unique identifier for your chatbot |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
from | datetime (ISO 8601) | ✅ | Start of the range (inclusive) |
to | datetime (ISO 8601) | ✅ | End of the range (exclusive). Must be after from |
Response
{
"data": [
{
"month": "2025-01",
"messageCount": 5200,
"userMessageCount": 2600,
"distinctUsers": 480,
"distinctSessions": 910,
"tokenTotal": 1450000
},
{
"month": "2025-02",
"messageCount": 6100,
"userMessageCount": 3050,
"distinctUsers": 530,
"distinctSessions": 1020,
"tokenTotal": 1710000
}
],
"error": null
}
Response Fields
| Field | Type | Description |
|---|---|---|
month | string | Month bucket in YYYY-MM format (UTC) |
messageCount | number | Total messages (any sender) in the month |
userMessageCount | number | Messages sent by users only (senderType = User) |
distinctUsers | number | Distinct users who sent at least one message in the month |
distinctSessions | number | Distinct sessions active in the month |
tokenTotal | number | Sum of tokenCount across all messages in the month |
Error Response
{
"data": null,
"error": "`to` must be greater than `from`."
}
Filtering Messages
By Session
Get all messages in a specific conversation session:
GET /Dev/{chatbotId}/messages?sessionId=6612a1b2c3d4e5f6a7b8c9d1
By User
Get all messages from a specific user across all sessions:
GET /Dev/{chatbotId}/messages?userId=6612a1b2c3d4e5f6a7b8c9d0
Combined Filters
Filter by both session and user:
GET /Dev/{chatbotId}/messages?sessionId=SESSION_ID&userId=USER_ID&page=1&pageSize=50
Pagination
All list endpoints return paginated results with the following metadata:
| Field | Type | Description |
|---|---|---|
totalItems | int | Total number of records |
pageSize | int | Number of items per page |
currentPage | int | Current page number |
totalPages | int | Total number of pages |
Use the page and pageSize query parameters to navigate through results. Results are ordered by creation date (newest first).
Code Examples
JavaScript
const crypto = require("crypto");
const apiKey = "pk_your_api_key";
const apiSecret = "sk_your_api_secret";
const chatbotId = "your_chatbot_id";
const sessionId = "your_session_id";
// Get messages for a specific session
const timestamp = Math.floor(Date.now() / 1000);
const path = `/api/Dev/${chatbotId}/messages?sessionId=${sessionId}&page=1&pageSize=50`;
const payload = `GET\n${path}\n\n${timestamp}`;
const signature = crypto
.createHmac("sha256", apiSecret)
.update(payload)
.digest("base64");
const response = await fetch(`https://api.peki.ai${path}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-API-Key": apiKey,
"X-Signature": signature,
"X-Timestamp": timestamp.toString(),
},
});
const result = await response.json();
console.log("Messages:", result.data);
console.log("Total:", result.totalItems);
// --- Monthly analytics (aggregated server-side, no pagination needed) ---
const from = "2025-01-01T00:00:00Z";
const to = "2025-04-01T00:00:00Z";
const statsPath = `/api/Dev/${chatbotId}/messages/count-by-month?from=${from}&to=${to}`;
const statsTs = Math.floor(Date.now() / 1000);
const statsSig = crypto
.createHmac("sha256", apiSecret)
.update(`GET\n${statsPath}\n\n${statsTs}`)
.digest("base64");
const stats = await fetch(`https://api.peki.ai${statsPath}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-API-Key": apiKey,
"X-Signature": statsSig,
"X-Timestamp": statsTs.toString(),
},
}).then((r) => r.json());
stats.data.forEach((m) =>
console.log(`${m.month}: ${m.messageCount} messages, ${m.distinctUsers} users`)
);
Python
import hmac, hashlib, base64, time, requests
api_key = 'pk_your_api_key'
api_secret = 'sk_your_api_secret'
chatbot_id = 'your_chatbot_id'
session_id = 'your_session_id'
# Get messages for a specific session
timestamp = str(int(time.time()))
path = f'/api/Dev/{chatbot_id}/messages?sessionId={session_id}&page=1&pageSize=50'
payload = f'GET\n{path}\n\n{timestamp}'
signature = base64.b64encode(
hmac.new(api_secret.encode(), payload.encode(), hashlib.sha256).digest()
).decode()
headers = {
'Content-Type': 'application/json',
'X-API-Key': api_key,
'X-Signature': signature,
'X-Timestamp': timestamp
}
response = requests.get(f'https://api.peki.ai{path}', headers=headers)
result = response.json()
for msg in result['data']:
sender = 'You' if msg['senderType'] == 'User' else 'Bot'
print(f'{sender}: {msg.get("text", "")}')
# --- Monthly analytics (aggregated server-side, no pagination needed) ---
stats_ts = str(int(time.time()))
stats_path = f'/api/Dev/{chatbot_id}/messages/count-by-month?from=2025-01-01T00:00:00Z&to=2025-04-01T00:00:00Z'
stats_sig = base64.b64encode(
hmac.new(api_secret.encode(), f'GET\n{stats_path}\n\n{stats_ts}'.encode(), hashlib.sha256).digest()
).decode()
stats = requests.get(f'https://api.peki.ai{stats_path}', headers={
'Content-Type': 'application/json',
'X-API-Key': api_key,
'X-Signature': stats_sig,
'X-Timestamp': stats_ts,
}).json()
for m in stats['data']:
print(f"{m['month']}: {m['messageCount']} messages, {m['distinctUsers']} users")
cURL
API_KEY="pk_your_api_key"
API_SECRET="sk_your_api_secret"
CHATBOT_ID="your_chatbot_id"
SESSION_ID="your_session_id"
TIMESTAMP=$(date +%s)
REQ_PATH="/api/Dev/$CHATBOT_ID/messages?sessionId=$SESSION_ID&page=1&pageSize=50"
PAYLOAD="GET\n$REQ_PATH\n\n$TIMESTAMP"
SIGNATURE=$(echo -ne "$PAYLOAD" | openssl dgst -sha256 -hmac "$API_SECRET" -binary | base64)
curl -s "https://api.peki.ai$REQ_PATH" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-H "X-Signature: $SIGNATURE" \
-H "X-Timestamp: $TIMESTAMP"
# --- Monthly analytics (aggregated server-side, no pagination needed) ---
STATS_TS=$(date +%s)
STATS_PATH="/api/Dev/$CHATBOT_ID/messages/count-by-month?from=2025-01-01T00:00:00Z&to=2025-04-01T00:00:00Z"
STATS_SIG=$(echo -ne "GET\n$STATS_PATH\n\n$STATS_TS" | openssl dgst -sha256 -hmac "$API_SECRET" -binary | base64)
curl -s "https://api.peki.ai$STATS_PATH" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-H "X-Signature: $STATS_SIG" \
-H "X-Timestamp: $STATS_TS"
Common Workflow
A typical flow to retrieve a full conversation:
- List users to find the user you're interested in
- List sessions filtered by
userIdto find their conversations - List messages filtered by
sessionIdto read the full conversation
GET /Dev/{chatbotId}/users
→ pick a userId
GET /Dev/{chatbotId}/sessions?userId={userId}
→ pick a sessionId
GET /Dev/{chatbotId}/messages?sessionId={sessionId}
→ full conversation
Error Codes
| Status Code | Description |
|---|---|
401 | Invalid API key or signature |
403 | API key doesn't have access to the specified chatbot |
404 | Message not found |
500 | Internal server error |