HTTP Query API
The Daemo HTTP Query Endpoints allow you to trigger your agents and receive responses from any application, frontend, or backend service via standard REST requests.
Base URL
http://localhost:8080 # Development
https://api.daemo.ai # Production
Authentication
All requests require an API key in the X-API-Key header.
X-API-Key: daemo_live_your_api_key_here
API keys are created when you create a new agent at app.daemo.ai. Store them securely — they provide full access to execute your agent's tools.
You can access your API key and ready-to-use code snippets directly in the Daemo app:
- Go to app.daemo.ai
- Select your Organization
- Select your Agent
- Click Deployment in the left sidebar
- Copy the curl, JavaScript, or Python examples pre-filled with your agent ID and API key
Endpoints
1. Query (Non-Streaming)
Process a query and return the complete response. Use this for server-to-server automation where you need the final result in one payload.
Endpoint: POST /agents/{agent_id}/query
Headers:
Content-Type: application/json
X-API-Key: daemo_live_your_api_key_here
Request Body:
interface QueryRequest {
query: string; // Required: The query text
threadId?: string; // Optional: Continue existing conversation
sessionId?: string; // Optional: Group related threads
role?: string; // Optional: Role for RBAC access control
contextJson?: string; // Optional: Additional context as JSON string
analysisMode?: boolean; // Optional: Enable analysis/reasoning mode
llmConfig?: { // Optional: Override LLM settings
provider: string; // "anthropic" | "openai" | "gemini"
model?: string; // e.g., "claude-3-5-sonnet-latest"
maxTokens?: number; // Default: 8192
};
}
Response:
interface QueryResponse {
success: boolean;
response: string; // Final response (markdown)
threadId: string; // Thread ID for continuation
executionTimeMs: number;
toolInteractions: ToolCall[]; // Record of functions that were executed
errorMessage: string;
}
interface ToolCall {
toolName: string;
parameters: any;
success: boolean;
result?: any;
errorMessage?: string;
}
Example:
curl -X POST https://api.daemo.ai/agents/507f1f77bcf86cd799439011/query \
-H "Content-Type: application/json" \
-H "X-API-Key: daemo_live_abc123..." \
-d '{
"query": "What was our total revenue in Q4 2024?",
"threadId": "thread_xyz789"
}'
Response:
{
"success": true,
"response": "Based on the analysis, your Q4 2024 revenue was **$2,450,000**...",
"threadId": "thread_xyz789",
"executionTimeMs": 3245,
"toolInteractions": [
{
"toolName": "query_database",
"parameters": { "query": "SELECT SUM(revenue)..." },
"success": true,
"result": { "total_revenue": 2450000 }
}
],
"errorMessage": ""
}
2. Query Stream (Server-Sent Events)
Process a query and stream the response via SSE (Server-Sent Events). Use this for building chat interfaces where you want to show the user the agent's "Thought Process" in real-time.
Endpoint: POST /agents/{agent_id}/query-stream
Headers:
Content-Type: application/json
X-API-Key: daemo_live_your_api_key_here
Accept: text/event-stream
Request Body: Same as non-streaming endpoint.
Stream Events:
| Event Type | Description |
|---|---|
thought | Agent's reasoning process / planning step |
toolCall | Agent is executing a function |
toolResult | Function execution result returned from your SDK |
finalResponse | Complete response (Markdown) |
error | Error occurred |
Example:
curl -X POST https://api.daemo.ai/agents/507f1f77bcf86cd799439011/query-stream \
-H "Content-Type: application/json" \
-H "X-API-Key: daemo_live_abc123..." \
-H "Accept: text/event-stream" \
-d '{"query": "Analyze our customer churn rate"}'
Client Examples
JavaScript / TypeScript
// Non-streaming
async function query(agentId, apiKey, queryText) {
const response = await fetch(`https://api.daemo.ai/agents/${agentId}/query`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': apiKey
},
body: JSON.stringify({ query: queryText })
});
const data = await response.json();
if (!data.success) {
throw new Error(data.errorMessage);
}
return data;
}
// Usage
const result = await query('agent_id', process.env.DAEMO_API_KEY, 'What contacts do we have?');
console.log(result.response);
JavaScript Streaming
async function queryStream(agentId, apiKey, queryText, onEvent) {
const response = await fetch(`https://api.daemo.ai/agents/${agentId}/query-stream`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': apiKey
},
body: JSON.stringify({ query: queryText })
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const event = JSON.parse(line.slice(6));
onEvent(event);
if (event.type === 'finalResponse' || event.type === 'error') {
return event;
}
}
}
}
}
// Usage
await queryStream('agent_id', process.env.DAEMO_API_KEY, 'Analyze sales data', (event) => {
switch (event.type) {
case 'thought':
console.log('Thinking:', event.content);
break;
case 'toolCall':
console.log('Calling:', event.toolName);
break;
case 'finalResponse':
console.log('Result:', event.response);
break;
}
});
Python
import requests
import json
import os
def query(agent_id: str, api_key: str, query_text: str) -> dict:
response = requests.post(
f'https://api.daemo.ai/agents/{agent_id}/query',
headers={
'Content-Type': 'application/json',
'X-API-Key': api_key
},
json={'query': query_text}
)
data = response.json()
if not data['success']:
raise Exception(data['errorMessage'])
return data
# Usage
api_key = os.getenv("DAEMO_API_KEY")
result = query('agent_id', api_key, 'What contacts do we have?')
print(result['response'])
Multi-Turn Conversations
Daemo maintains conversation history automatically. Use threadId to continue a conversation:
class Conversation {
constructor(agentId, apiKey) {
this.agentId = agentId;
this.apiKey = apiKey;
this.threadId = null;
}
async ask(query) {
const response = await fetch(`https://api.daemo.ai/agents/${this.agentId}/query`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiKey
},
body: JSON.stringify({
query: query,
threadId: this.threadId
})
});
const data = await response.json();
this.threadId = data.threadId; // Save for next query
return data.response;
}
}
// Usage
const chat = new Conversation('agent_id', 'api_key');
await chat.ask('What was our Q4 revenue?');
await chat.ask('How does that compare to Q3?'); // Continues same thread
await chat.ask('What were the main drivers?');
Request Fields Reference
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Natural language query |
threadId | string | No | Continue existing conversation |
sessionId | string | No | Group related threads for analytics |
role | string | No | Role for RBAC access control (injected into context) |
contextJson | string | No | Additional context as JSON string |
analysisMode | boolean | No | Force "Analyst Mode" (Plan first, then act) |
llmConfig | object | No | Override LLM settings (Provider, Model, Temp) |
Error Handling
HTTP Errors
| Status | Cause |
|---|---|
| 401 | Invalid or missing API key |
| 403 | Agent ID mismatch |
| 400 | Invalid request format |
| 500 | Server error |
Response Errors
Check success field and errorMessage:
const data = await response.json();
if (!data.success) {
console.error('Query failed:', data.errorMessage);
// Common errors:
// - "Agent session not found" → Your local agent SDK is not running or disconnected
// - "Insufficient credits" → Add credits at app.daemo.ai
}
Streaming vs Non-Streaming
| Use Non-Streaming | Use Streaming |
|---|---|
| Simple queries | Long-running queries |
| Batch processing | Real-time UI updates |
| Backend integrations | Interactive chat |
| You need complete result | Show progress to user |
Recommendation: Use streaming for user-facing chat interfaces, non-streaming for backend automation.
Rate Limits & Pricing
| Account Type | Rate Limits |
|---|---|
| Dev accounts | Unlimited queries in Sandbox mode |
| Production | See our Pricing Page for usage tiers and volume discounts |
Troubleshooting
"Agent session not found"
Your agent service isn't running or hasn't connected to the control plane.
Solution: Start your agent service locally or on your server:
npm run dev # or npx ts-node src/index.ts
"Insufficient credits"
Organization has run out of credits.
Solution: Add credits at app.daemo.ai → Organization → Billing
"Authentication failed"
Invalid API key.
Solution: - Verify key starts with daemo_live_
- Check key at app.daemo.ai → Agent → Settings
SSE Connection Drops
Proxy/load balancer timeout.
Solution (Nginx):
location /agents {
proxy_pass http://backend;
proxy_read_timeout 300s;
proxy_buffering off;
}