API Reference
Conversational Agents
Conversational agents enable real-time conversations with your AI agents using Server-Sent Events (SSE) for streaming responses.
Chat API
POST
/v1/chatInitiate or continue a conversation with an agent. Returns streaming responses via SSE.
Request Headers
bash
X-API-Key: YOUR_API_KEY
X-Backend-Token: YOUR_BACKEND_TOKEN (optional)Request Body
json
{
"agentId": "agent_abc123",
"environmentId": "env_xyz789",
"messages": [
{"content": "Hello, I need help with my account"}
],
"threadId": "thread_def456", // optional - continue existing conversation
"customerId": "customer_ghi789", // optional - user identifier for scoped memory
"customInstructions": "The user is a premium customer", // optional - additional context
"uploadedFiles": { // optional - file attachments
"file1": {
"url": "https://example.com/file.pdf",
"name": "document.pdf",
"type": "application/pdf"
}
},
"screenState": { // optional - UI context for Screen Observer
"route": "/dashboard",
"routeName": "Dashboard",
"timestamp": "2025-01-15T12:00:00Z",
"entities": {
"user": {"id": "123", "name": "John Doe"}
}
},
"logChannelId": "log_channel_abc", // optional - real-time logging channel
"logToolScore": true // optional - enable tool execution scoring
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
agentId | string | Yes | ID of the agent to chat with |
environmentId | string | Yes | Environment ID for agent execution |
messages | array | Yes | Array of message objects with content field |
threadId | string | No | Continue existing conversation (returned in complete event) |
customerId | string | No | User identifier for customer-scoped memory and tracking |
customInstructions | string | No | Additional context or instructions for this conversation |
uploadedFiles | object | No | File attachments with url, name, and type properties |
screenState | object | No | UI context (route, entities, observedElements) for Screen Observer |
logChannelId | string | No | Channel ID for real-time logging and monitoring |
logToolScore | boolean | No | Enable tool execution scoring for analytics |
Response (SSE Stream)
The chat endpoint returns Server-Sent Events (SSE) for real-time streaming. All events follow a wrapper structure with type, data/event, and isComplete fields.
meebly-eventWrapper for AI agent stream events including text generation, tool calls, and approvals
json
data: {
"type": "meebly-event",
"event": {
"type": "text-delta",
"payload": {
"text": "chunk of text"
}
},
"isComplete": false
}Event Subtypes:
text-delta- Incremental text chunks from the agent (append to build full message)tool-call- Agent is calling a tool (contains toolCallId, toolName, args)tool-result- Tool execution completed (contains toolCallId, result)tool-call-approval- Tool requires human approval - (contains runId for approve/decline endpoints)start- Agent execution startedfinish- Agent execution finished
completeStream completed successfully - Contains full response, threadId, executedTools, successUrl, and traceId
json
data: {
"type": "complete",
"data": {
"text": "Final response text",
"toolCalls": [],
"overallSuccess": true
},
"isComplete": true
}errorAn error occurred during streaming - Stream ends immediately
json
data: {
"type": "error",
"error": "Error message describing what went wrong",
"isComplete": true
}When tools require approval, look for
meebly-event with type: "tool-call-approval". Extract the runId to approve or decline the tool execution. See the Tool Approval (HITL) section for details.Example Implementation
javascript
const response = await fetch('https://api.meebly.ai/v1/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'YOUR_API_KEY'
},
body: JSON.stringify({
agentId: 'agent_abc123',
environmentId: 'env_xyz789',
messages: [{content: 'Hello, I need help'}],
screenState: {
route: '/dashboard',
routeName: 'Dashboard',
timestamp: new Date().toISOString()
}
})
});
// Handle Server-Sent Events stream
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
let fullResponse = '';
while (true) {
const {value, done} = await reader.read();
if (done) break;
buffer += decoder.decode(value, {stream: true});
const lines = buffer.split('\n\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const event = JSON.parse(line.slice(6));
if (event.type === 'meebly-event') {
// Handle AI stream events
if (event.event.type === 'text-delta') {
fullResponse += event.event.payload.text;
console.log('Text chunk:', event.event.payload.text);
} else if (event.event.type === 'tool-call') {
console.log('Tool called:', event.event.payload.toolName);
} else if (event.event.type === 'tool-call-approval') {
console.log('Approval needed, runId:', event.event.payload.runId);
// Don't close connection - send approval via separate API call
}
} else if (event.type === 'complete') {
console.log('Complete response:', event.data.text);
console.log('Thread ID:', event.data.threadId);
console.log('Trace ID:', event.data.traceId);
// Save threadId for continuing conversation
} else if (event.type === 'error') {
console.error('Error:', event.error);
}
} catch (e) {
// Handle parsing errors for incomplete chunks
}
}
}
}Save the
threadId from the complete event to maintain conversation context in subsequent requests.Last updated: March 2026Report an issue