For Coding Agents
AGNT Chats
Multi-turn conversation management with platform-aware AI responses. Chats handle the full lifecycle of a conversation — creation, message accumulation, AI processing, and archival — across email, SMS, WhatsApp, Slack, Teams, and native chat.
Why AGNT Chats
Most chat APIs treat every platform the same. That's wrong. An email response needs subject lines, recipients, and CC fields. An SMS response needs to be short. A Slack message can use rich formatting. AGNT Chats understands these differences and shapes AI responses accordingly.
The processing pipeline also handles the messy realities of group conversations: ignore detection, status-based CC routing, and message suppression. You don't build this logic — it's built in.
Quick Start
Create a chat, add a message, and process it to get an AI response:
# Create a chat
curl -X POST https://api.agnt.ai/chats \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"assistantId": "asst_abc123",
"title": "Project kickoff discussion"
}'
# Add a user message
curl -X POST https://api.agnt.ai/chats/chat_xyz789/messages \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "Can you schedule a kickoff meeting for next Tuesday?",
"role": "user",
"platform": "chat"
}'
# Process the chat — generate an AI response
curl -X POST https://api.agnt.ai/chats/chat_xyz789/process \
-H "Authorization: Bearer $TOKEN"Core Concepts
Chats vs. Messages
Chats and messages are separate resources, fetched independently. A chat is the container — it holds metadata, status, and the assistant reference. Messages live inside the chat but are paginated separately. This matters for performance: you can list 500 chats without loading a single message body.
Platform-Aware Responses
When you process a chat, the AI response is shaped by the platform of the most recent message:
- Email: Response includes
to,cc, andsubjectfields. Full formatting. Proper threading. - SMS / WhatsApp: Simplified response. No subject lines. Concise content.
- Slack / Teams: Simplified response optimized for channel-style messaging.
- Chat: Native AGNT chat format. Clean and straightforward.
You don't configure this. It happens automatically based on the platform field of messages in the conversation.
Processing and Locking
POST /chats/:chatId/process is the core action. It sends the conversation to the AI and returns a response. Processing uses a Redis distributed lock with a 30-second TTL. If two requests try to process the same chat simultaneously, the second gets a 409 Conflict. This prevents duplicate responses and race conditions in webhook-driven architectures.
Smart Processing Behaviors
Processing isn't just "send messages to AI, get response." The pipeline includes:
- Ignore detection: In group conversations, the AI determines whether a message is directed at it. If not, processing returns
ignored: trueand no response is generated. - Message suppression: In some cases, the AI determines a response isn't needed (e.g., a simple acknowledgment in a thread). Returns
suppressed: true. - Status-based CC: The system automatically manages CC recipients based on conversation status and participant roles.
- Task creation: Processing can return
taskIdswhen the AI identifies actionable items in the conversation.
Auto-Provisioning
When a delegated JWT includes an email AGNT hasn't seen, the user is created automatically. No signup flow required. See Authentication for details.
API Reference
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /chats | List chats |
POST | /chats | Create a chat |
GET | /chats/:chatId | Get a chat (without messages) |
DELETE | /chats/:chatId | Delete a chat |
POST | /chats/:chatId/process | Process chat and generate AI response |
GET | /chats/:chatId/messages | List messages in a chat |
POST | /chats/:chatId/messages | Add a message to a chat |
GET | /chats/:chatId/messages/:messageId | Get a single message |
PUT | /chats/:chatId/messages/:messageId | Update a message |
DELETE | /chats/:chatId/messages/:messageId | Delete a message |
DELETE | /chats/:chatId/messages | Clear all messages in a chat |
Chat Object
{
"id": "chat_xyz789",
"title": "Project kickoff discussion",
"status": "active",
"messageCount": 12,
"assistant": {
"id": "asst_abc123",
"name": "Project Manager",
"email": "pm@assistant.agnt.ai"
},
"metadata": {},
"lastMessageAt": "2026-02-28T18:30:00.000Z",
"createdAt": "2026-02-28T14:00:00.000Z"
}| Field | Type | Description |
|---|---|---|
id | string | Unique chat identifier |
title | string | Chat title |
status | string | active or archived |
messageCount | number | Total messages in the chat |
assistant | object | Associated assistant (id, name, email) |
metadata | object | Arbitrary key-value metadata |
lastMessageAt | string | ISO 8601 timestamp of the most recent message |
createdAt | string | ISO 8601 timestamp of chat creation |
Message Object
{
"id": "msg_001",
"role": "user",
"content": "Can you schedule a kickoff meeting for next Tuesday?",
"files": [],
"timestamp": "2026-02-28T18:30:00.000Z",
"metadata": {},
"platform": "email",
"referenceId": "msg-id-from-email-provider",
"from": "jane@example.com",
"to": ["pm@assistant.agnt.ai"],
"cc": ["team@example.com"],
"subject": "Re: Project Kickoff"
}| Field | Type | Description |
|---|---|---|
id | string | Unique message identifier |
role | string | user or assistant |
content | string | Message body |
files | array | Attached file references |
timestamp | string | ISO 8601 timestamp |
metadata | object | Arbitrary key-value metadata |
platform | string | One of: email, sms, whatsapp, slack, teams, chat |
referenceId | string | External message ID (e.g., email provider message ID) |
from | string | Sender address (email messages) |
to | array | Recipient addresses (email messages) |
cc | array | CC addresses (email messages) |
subject | string | Subject line (email messages) |
List Chats
GET https://api.agnt.ai/chats
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by active or archived |
assistantId | string | Filter by assistant |
metadata.* | string | Filter by metadata field (e.g., metadata.projectId=proj_123) |
page | number | Page number (default: 1) |
perPage | number | Results per page (default: 20) |
curl "https://api.agnt.ai/chats?status=active&assistantId=asst_abc123&page=1&perPage=10" \
-H "Authorization: Bearer $TOKEN"{
"data": [
{
"id": "chat_xyz789",
"title": "Project kickoff discussion",
"status": "active",
"messageCount": 12,
"assistant": {
"id": "asst_abc123",
"name": "Project Manager",
"email": "pm@assistant.agnt.ai"
},
"metadata": {},
"lastMessageAt": "2026-02-28T18:30:00.000Z",
"createdAt": "2026-02-28T14:00:00.000Z"
}
],
"pagination": {
"page": 1,
"perPage": 10,
"total": 1
}
}Create Chat
POST https://api.agnt.ai/chats
| Field | Type | Required | Description |
|---|---|---|---|
assistantId | string | Yes | The assistant to associate with this chat |
title | string | No | Chat title |
metadata | object | No | Arbitrary key-value metadata |
curl -X POST https://api.agnt.ai/chats \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"assistantId": "asst_abc123",
"title": "Weekly sync",
"metadata": {
"projectId": "proj_123",
"channel": "internal"
}
}'{
"id": "chat_new001",
"title": "Weekly sync",
"status": "active",
"messageCount": 0,
"assistant": {
"id": "asst_abc123",
"name": "Project Manager",
"email": "pm@assistant.agnt.ai"
},
"metadata": {
"projectId": "proj_123",
"channel": "internal"
},
"lastMessageAt": null,
"createdAt": "2026-03-01T10:00:00.000Z"
}Get Chat
GET https://api.agnt.ai/chats/:chatId
Returns the chat object without messages. Use the messages endpoint to fetch messages separately.
curl https://api.agnt.ai/chats/chat_xyz789 \
-H "Authorization: Bearer $TOKEN"Delete Chat
DELETE https://api.agnt.ai/chats/:chatId
Permanently deletes the chat and all its messages. This is irreversible.
curl -X DELETE https://api.agnt.ai/chats/chat_xyz789 \
-H "Authorization: Bearer $TOKEN"Process Chat
POST https://api.agnt.ai/chats/:chatId/process
Sends the conversation to the AI assistant and returns a response. This is the core action — it's where the intelligence happens.
Uses a Redis distributed lock (30-second TTL). If another process request is already running for this chat, you'll get a 409 Conflict.
curl -X POST https://api.agnt.ai/chats/chat_xyz789/process \
-H "Authorization: Bearer $TOKEN"Standard response (email platform):
{
"message": {
"content": "I'll schedule the kickoff meeting for next Tuesday at 10am. I've sent calendar invites to the team.",
"to": ["jane@example.com"],
"cc": ["team@example.com"],
"subject": "Re: Project Kickoff"
},
"taskIds": ["task_456"]
}Standard response (SMS/WhatsApp/Slack/Teams/chat platform):
{
"message": {
"content": "Done — kickoff meeting is set for next Tuesday at 10am. Calendar invites sent."
},
"taskIds": []
}Ignored response (group conversation, not directed at assistant):
{
"ignored": true
}Suppressed response (response not needed):
{
"suppressed": true
}Conflict response (409):
{
"error": "Chat is already being processed"
}Add Message
POST https://api.agnt.ai/chats/:chatId/messages
| Field | Type | Required | Description |
|---|---|---|---|
content | string | Yes | Message body |
role | string | No | user or assistant (default: user) |
platform | string | No | email, sms, whatsapp, slack, teams, or chat |
files | array | No | File attachments |
metadata | object | No | Arbitrary key-value metadata |
referenceId | string | No | External message ID (email) |
from | string | No | Sender address (email) |
to | array | No | Recipient addresses (email) |
cc | array | No | CC addresses (email) |
subject | string | No | Subject line (email) |
# Simple chat message
curl -X POST https://api.agnt.ai/chats/chat_xyz789/messages \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "What is the status of the rollout?",
"role": "user",
"platform": "chat"
}'
# Email message with full headers
curl -X POST https://api.agnt.ai/chats/chat_xyz789/messages \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "Hi team, what is the status of the rollout?",
"role": "user",
"platform": "email",
"referenceId": "provider-msg-id-abc",
"from": "jane@example.com",
"to": ["pm@assistant.agnt.ai"],
"cc": ["team@example.com"],
"subject": "Rollout Status"
}'{
"id": "msg_002",
"role": "user",
"content": "What is the status of the rollout?",
"files": [],
"timestamp": "2026-03-01T10:05:00.000Z",
"metadata": {},
"platform": "chat"
}List Messages
GET https://api.agnt.ai/chats/:chatId/messages
| Parameter | Type | Description |
|---|---|---|
page | number | Page number (default: 1) |
perPage | number | Results per page (default: 20) |
curl "https://api.agnt.ai/chats/chat_xyz789/messages?page=1&perPage=50" \
-H "Authorization: Bearer $TOKEN"{
"data": [
{
"id": "msg_001",
"role": "user",
"content": "Can you schedule a kickoff meeting for next Tuesday?",
"files": [],
"timestamp": "2026-02-28T18:30:00.000Z",
"metadata": {},
"platform": "chat"
},
{
"id": "msg_002",
"role": "assistant",
"content": "Done — kickoff meeting is set for next Tuesday at 10am.",
"files": [],
"timestamp": "2026-02-28T18:31:00.000Z",
"metadata": {},
"platform": "chat"
}
],
"pagination": {
"page": 1,
"perPage": 50,
"total": 2
}
}Get Message
GET https://api.agnt.ai/chats/:chatId/messages/:messageId
curl https://api.agnt.ai/chats/chat_xyz789/messages/msg_001 \
-H "Authorization: Bearer $TOKEN"Update Message
PUT https://api.agnt.ai/chats/:chatId/messages/:messageId
curl -X PUT https://api.agnt.ai/chats/chat_xyz789/messages/msg_001 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "Can you schedule a kickoff meeting for next Wednesday instead?",
"metadata": { "edited": true }
}'Delete Message
DELETE https://api.agnt.ai/chats/:chatId/messages/:messageId
curl -X DELETE https://api.agnt.ai/chats/chat_xyz789/messages/msg_001 \
-H "Authorization: Bearer $TOKEN"Clear All Messages
DELETE https://api.agnt.ai/chats/:chatId/messages
Removes every message from the chat. The chat itself remains. Useful for resetting a conversation without losing the chat metadata and assistant association.
curl -X DELETE https://api.agnt.ai/chats/chat_xyz789/messages \
-H "Authorization: Bearer $TOKEN"For Coding Agents
If you're an AI coding agent integrating with AGNT Chats, here's what matters:
-
Always set
platformwhen adding messages. The processing pipeline uses it to shape responses. If you omit it, you lose platform-specific formatting. -
Handle
409 Conflicton process calls. In concurrent systems (webhooks, queues), two workers might try to process the same chat. Retry with exponential backoff or let the other worker handle it. -
Check for
ignoredandsuppressedin process responses. Don't treat these as errors. An ignored response in a group conversation is correct behavior — the message wasn't for the assistant. -
Use
metadatafor your own tracking. Store external IDs, thread references, or workflow state in metadata. You can filter chats bymetadata.*query parameters. -
Paginate messages, not chats. The chat object includes
messageCountbut not the messages themselves. This is intentional. Fetch messages separately with pagination for conversations that grow large. -
Process after adding messages, not before. The typical flow is: add message, then process. Processing analyzes the full conversation history including the message you just added.
For Product Teams
AGNT Chats is the conversation layer between your users and AI assistants. Here's how to think about it:
Multi-channel from day one. A single chat can contain messages from different platforms. A conversation might start over email, continue on Slack, and resolve in-app. The assistant adapts its response style to whatever platform the latest message came from.
No message queue to build. The process endpoint handles locking, deduplication, and conflict resolution. You POST messages and POST to process — that's the entire integration surface for a working AI chat experience.
Metadata-driven filtering. Tag chats with project IDs, customer segments, priority levels, or anything else. Query by any metadata field. This replaces building a separate tagging or categorization system.
Task extraction is automatic. When the AI identifies actionable items during processing, it creates tasks and returns their IDs. You don't parse the response for action items — they're structured data in the response.
Archival, not deletion. For most workflows, archive chats instead of deleting them. Set status to archived via update. Archived chats are excluded from default list queries but remain accessible by ID for audit trails and context retrieval.