Product
API Endpoints Reference
API endpoints for querying agents, managing data sources, and retrieving analytics.
TL;DR
API endpoints for querying agents, managing data sources, and retrieving analytics.
Key Takeaways
- Base URL
- Authentication
- Rate Limits
- API Endpoints
- Error Responses
- Webhooks
API endpoints for querying agents, managing data sources, and retrieving analytics.
Base URL
https://api.twig.so
Protocol: HTTPS only (HTTP requests redirect to HTTPS)
API Version: v1 (included in path: /api/v1/... or legacy /api/...)
Authentication
Include API key in Authorization header:
curl -H "Authorization: Bearer twigsk_live_abc123..." \
https://api.twig.so/api/agents
Key format: twigsk_live_... (production) or twigsk_test_... (test)
Generate key: Settings → API Keys → Generate New Key
See Authentication for key management.
Rate Limits
Enforced per API key:
| Scope | Requests/Minute | Burst Allowance |
|---|---|---|
| Execute (queries) | 100 | 120 |
| Write (create/update) | 10 | 15 |
| Read (list/get) | 200 | 250 |
| Admin (org settings) | 50 | 60 |
Headers in response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1610708100
When exceeded: 429 Too Many Requests with reset timestamp
See Rate Limits for optimization strategies.
API Endpoints
Chat & Completion
POST /api/v1/query
Generate agent response. Replaces legacy /api/chat.
Request:
{
"agent_id": "agent_abc123",
"query": "What is your refund policy?",
"session_id": "sess_xyz789",
"stream": false,
"temperature": 0.7,
"max_tokens": 500
}
Required fields: agent_id, query
Optional fields:
session_id: For multi-turn conversations (creates new if omitted)stream: Boolean, SSE streaming (default: false)temperature: 0-2 (default: agent config value)max_tokens: Response length limit (default: agent config value)
Response (200 OK):
{
"response": "Our refund policy allows returns within 30 days...",
"sources": [{
"chunk_id": "chk_abc123",
"document_title": "Refund Policy",
"document_url": "https://example.com/refund",
"similarity_score": 0.89,
"chunk_text": "Refunds are processed within..."
}],
"metadata": {
"interaction_id": "int_xyz456",
"latency_ms": 1432,
"tokens_input": 523,
"tokens_output": 145,
"cost_usd": 0.0042,
"rag_strategy": "cedar",
"model": "gpt-4"
}
}
Error responses:
400: Missing required field, invalid agent_id format401: Invalid API key403: API key lacks Execute scope404: Agent not found429: Rate limit exceeded500: Internal error
Latency: 1-5s depending on RAG strategy
POST /api/v1/semantic-search
Retrieve chunks without LLM generation.
Request:
{
"query": "pricing information",
"org_id": "org_123",
"top_k": 10,
"similarity_threshold": 0.7,
"data_source_ids": ["ds_1", "ds_2"]
}
Required: query, org_id
Response (200 OK):
{
"chunks": [{
"chunk_id": "chk_abc123",
"text": "Pricing starts at $99/month...",
"similarity_score": 0.85,
"document_id": "doc_456",
"document_title": "Pricing Page"
}],
"query_embedding": [0.123, -0.456, ...],
"metadata": {
"total_chunks_searched": 15234,
"latency_ms": 234
}
}
Agents
GET /api/v1/agents
List agents. Requires Read scope.
Query params:
limit: Max results (default: 50, max: 200)offset: Pagination (default: 0)
Response (200):
{
"agents": [{
"id": "agent_abc123",
"name": "Support Agent",
"rag_strategy": "cedar",
"model": "gpt-4",
"status": "active",
"data_source_ids": ["ds_1", "ds_2"],
"created_at": "2024-01-15T10:30:00Z"
}],
"total": 5,
"limit": 50,
"offset": 0
}
POST /api/v1/agents
Create agent. Requires Write scope.
Request:
{
"name": "Support Agent",
"system_prompt": "You are a helpful support assistant.",
"rag_strategy": "cedar",
"model": "gpt-4",
"temperature": 0.7,
"max_tokens": 500,
"data_source_ids": ["ds_1", "ds_2"]
}
Required: name, data_source_ids
Response (201): Agent object with generated id
GET /api/v1/agents/:id
Get agent details. Requires Read scope.
PUT /api/v1/agents/:id
Update agent. Requires Write scope.
Request: Same fields as POST, all optional
Response (200): Updated agent object
DELETE /api/v1/agents/:id
Delete agent. Requires Write scope.
Response (204): No content
Data Sources
GET /api/v1/data-sources
List data sources. Requires Read scope.
Query params: limit, offset, status (active/processing/failed)
POST /api/v1/data-sources
Create data source. Requires Write scope.
Request:
{
"type": "website",
"name": "Product Documentation",
"config": {
"url": "https://docs.example.com",
"max_pages": 1000
},
"sync_frequency": "daily"
}
Types: website, file, confluence, slack, google_drive, sharepoint
Sync frequency: hourly, daily, weekly, manual
Response (201): Data source object with ID, status "pending"
POST /api/v1/data-sources/:id/sync
Trigger sync. Requires Write scope.
Response (202): Sync job queued
GET /api/v1/data-sources/:id/status
Check processing status.
Response:
{
"status": "processing",
"chunks_indexed": 450,
"progress_pct": 75,
"estimated_completion": "2024-01-15T10:45:00Z"
}
Interactions
GET /api/v1/interactions
List query history. Requires Read scope.
Query params:
limit,offset: Paginationagent_id: Filter by agentstart_date,end_date: Date range (YYYY-MM-DD)feedback: Filter by positive/negative/null
Response:
{
"interactions": [{
"id": "int_xyz123",
"agent_id": "agent_abc",
"query": "What is pricing?",
"response": "Pricing starts at...",
"feedback": "positive",
"latency_ms": 1432,
"created_at": "2024-01-15T10:30:00Z"
}],
"total": 1250
}
POST /api/v1/interactions/:id/feedback
Submit feedback. Requires Execute scope.
Request:
{
"feedback": "positive",
"comment": "Very helpful!"
}
feedback values: positive, negative
Analytics
GET /api/v1/analytics
Get metrics. Requires Admin scope.
Query params:
start_date,end_date: Date range (required, YYYY-MM-DD)agent_id: Filter by agent (optional)granularity:hour,day,week,month(default: day)
Response:
{
"metrics": {
"total_queries": 10250,
"unique_users": 1523,
"avg_latency_ms": 1843,
"accuracy_rate": 0.82,
"citation_rate": 0.91,
"total_cost_usd": 42.50
},
"time_series": [{
"timestamp": "2024-01-15T00:00:00Z",
"queries": 450,
"latency_p50": 1432,
"latency_p95": 2890
}]
}
Users
GET /api/v1/users
List users. Requires Admin scope.
POST /api/v1/users
Create user. Requires Admin scope.
Request:
{
"email": "user@example.com",
"name": "John Doe",
"role": "train"
}
Roles: readonly, train, configure, admin
Knowledge Base
GET /api/v1/kb
List KB articles. Requires Read scope.
Query params: status (draft/published), limit, offset
POST /api/v1/kb
Create KB article. Requires Write scope.
Request:
{
"title": "How to reset password",
"content": "Steps: 1. Click Forgot Password...",
"tags": ["auth", "password"],
"status": "published"
}
PUT /api/v1/kb/:id
Update article. Creates new version. Requires Write scope.
Error Responses
Standard format:
{
"error": {
"code": "invalid_request",
"message": "Agent not found",
"details": {
"agent_id": "agent_123",
"org_id": "org_456"
}
},
"request_id": "req_xyz789"
}
request_id: Include when contacting support
Error Codes
| HTTP Status | Code | Description | Action |
|---|---|---|---|
| 400 | invalid_request | Missing required field, invalid format | Check request body against docs |
| 401 | unauthorized | Invalid/missing API key | Verify key format, regenerate if needed |
| 403 | forbidden | Insufficient scope | Check key permissions (Settings → API Keys) |
| 404 | not_found | Resource doesn't exist | Verify ID, check resource wasn't deleted |
| 429 | rate_limit_exceeded | Too many requests | Wait for reset (check X-RateLimit-Reset header) |
| 500 | internal_error | Server error | Retry with exponential backoff, contact support if persists |
| 503 | service_unavailable | Maintenance or overload | Retry after 5-10 minutes |
Retry logic: Use exponential backoff for 429, 500, 503 errors. Do NOT retry 400, 401, 403, 404.
Webhooks
Receive event notifications via HTTP POST to your endpoint.
Configure: Settings → Webhooks → Add Endpoint
Events:
interaction.completed: Query processed, response generateddata_source.synced: Data source sync finishedagent.updated: Agent configuration changedeval.completed: Evaluation run finished
Payload example:
{
"event": "interaction.completed",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"interaction_id": "int_xyz123",
"agent_id": "agent_abc",
"latency_ms": 1432
}
}
Security: Webhook signature in X-Twig-Signature header (HMAC-SHA256)
See Webhooks Guide for verification and retry logic.
SDKs
TypeScript/JavaScript:
npm install @twig/sdk
Python:
pip install twig-sdk
Usage example (TypeScript):
import { TwigClient } from '@twig/sdk';
const client = new TwigClient({ apiKey: process.env.TWIG_API_KEY });
const response = await client.query({
agentId: 'agent_abc123',
query: 'What is pricing?'
});
console.log(response.response);
See SDK Documentation for full API reference.
Next Steps
- Authentication Guide - API key generation and rotation
- Rate Limiting - Optimization strategies, caching
- Webhooks Setup - Event-driven integrations
- SDK Reference - Client library docs
Agent Instructions: Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.
Perform an HTTP GET request on the current page URL with the ask query parameter:
GET /dev/product/developer-api/rest-api.md?ask=<question>
The question should be specific, self-contained, and written in natural language. The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.
Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
Related Pages
Last updated January 26, 2026


