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:

ScopeRequests/MinuteBurst Allowance
Execute (queries)100120
Write (create/update)1015
Read (list/get)200250
Admin (org settings)5060

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 format
  • 401: Invalid API key
  • 403: API key lacks Execute scope
  • 404: Agent not found
  • 429: Rate limit exceeded
  • 500: 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: Pagination
  • agent_id: Filter by agent
  • start_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 StatusCodeDescriptionAction
400invalid_requestMissing required field, invalid formatCheck request body against docs
401unauthorizedInvalid/missing API keyVerify key format, regenerate if needed
403forbiddenInsufficient scopeCheck key permissions (Settings → API Keys)
404not_foundResource doesn't existVerify ID, check resource wasn't deleted
429rate_limit_exceededToo many requestsWait for reset (check X-RateLimit-Reset header)
500internal_errorServer errorRetry with exponential backoff, contact support if persists
503service_unavailableMaintenance or overloadRetry 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 generated
  • data_source.synced: Data source sync finished
  • agent.updated: Agent configuration changed
  • eval.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


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