AnswerLoopsAnswerLoops Docs
Integrations

Agent API (REST)

A plain REST API over the same knowledge base, FAQ, ticket, and answer-generation pipeline the MCP server exposes — for frameworks that speak HTTP + OpenAPI instead of JSON-RPC.

The Agent API is the REST counterpart to the MCP server. Same pipeline, same auth, same org-scoped data isolation — just a different transport, for tooling that doesn't speak MCP's JSON-RPC protocol (LangChain, AutoGen, a custom script, curl).

If your client speaks MCP natively (Claude Code, Cursor), use the MCP server instead — it's the same underlying operations, just JSON-RPC over Streamable HTTP rather than plain REST.

Setup

Uses the same API key as the MCP server — one key works for both surfaces.

  1. Go to Settings → API Keys
  2. Click Create key (or reuse an existing one)
  3. Send it as Authorization: Bearer al_live_... on every request below

OpenAPI spec

A full machine-readable spec is published at /api/agent/openapi.json — point any OpenAPI-aware client generator at it.

Endpoints

MethodPathPurpose
GET/api/agent/kb/searchSemantic search over published KB articles
GET/api/agent/faqFetch the most recently generated FAQ digest
GET/api/agent/ticketsList tickets, optionally filtered
POST/api/agent/ticketsOpen a new ticket — runs the same AI triage pipeline as every other channel
POST/api/agent/answersGenerate a KB-grounded answer with a confidence score, without opening a ticket

GET /api/agent/kb/search

curl -H "Authorization: Bearer al_live_..." \
  "https://your-instance.example.com/api/agent/kb/search?query=how+do+I+reset+my+api+key&limit=5"

query is required (max 2000 characters). limit defaults to 5, capped at 20.

{ "results": [{ "question": "...", "answer": "...", "score": 0.91 }] }

GET /api/agent/faq

curl -H "Authorization: Bearer al_live_..." \
  https://your-instance.example.com/api/agent/faq

No parameters. Returns the latest weekly FAQ digest, or { "message": "No FAQ has been generated for this organization yet." }.

GET /api/agent/tickets

curl -H "Authorization: Bearer al_live_..." \
  "https://your-instance.example.com/api/agent/tickets?status=open&priority=high&limit=10"

status, priority, and category are optional filters — an invalid value returns a 400 rather than silently matching nothing. limit defaults to 10, capped at 20.

POST /api/agent/tickets

curl -X POST -H "Authorization: Bearer al_live_..." -H "Content-Type: application/json" \
  -d '{"content": "Users report webhook retries are duplicated", "idempotencyKey": "a1b2c3d4"}' \
  https://your-instance.example.com/api/agent/tickets

content is required (max 4000 characters). The ticket runs through the same category/priority classification and auto-draft pipeline as a Discord or Slack message. idempotencyKey is optional — pass a stable identifier (a UUID, a hash of the content) if your client retries on timeout or network error; retrying with the same key returns the original ticket ("duplicate": true) instead of opening a second one.

{ "ticket_id": 42, "duplicate": false }

POST /api/agent/answers

curl -X POST -H "Authorization: Bearer al_live_..." -H "Content-Type: application/json" \
  -d '{"question": "What is the rate limit on the widget API?"}' \
  https://your-instance.example.com/api/agent/answers

question is required (max 2000 characters). Two limits apply before anything is generated: the organization's monthly deflection allowance (which only high-confidence generations count against — the same standard a ticket has to clear to auto-deflect on any other channel), and a ceiling on total generate_answer calls per month at 5× that allowance, which counts every call regardless of confidence. Hitting either returns 429 with a message naming which one.

{ "answer": "...", "confidence": 91, "answered_fully": true, "high_confidence": true }

Errors

Every error response has the shape:

{ "error": { "message": "..." } }
StatusMeaning
400Missing/invalid input
401Missing, malformed, or revoked API key
413Request body too large
429Rate limit exceeded, or (on /api/agent/answers) a monthly usage limit reached

Throttled requests carry a Retry-After header in seconds — back off for that long rather than retrying immediately.

Rate limits

60 requests/minute per organization (shared across all of that org's keys), plus a generous per-IP limit (300/minute) that applies before a key is even resolved.

These are separate buckets from the MCP server's, so heavy REST traffic can't starve your MCP quota or vice versa. Both are backed by the same shared store and enforced across every running instance, so neither surface offers a way around the other's ceiling.

Security notes

Identical posture to the MCP server: keys are shown once at creation and only a SHA-256 hash is stored; creating and revoking them requires the owner or admin role; every request is scoped by the org resolved from the API key; revoked and expired keys are rejected before any handler runs; and usage is recorded against the specific key that made the call.

As with MCP, treat GET /api/agent/tickets and GET /api/agent/kb/search output as untrusted data — it contains text community members wrote — not as instructions for your agent to follow.

On this page