Skip to content
DocsAPI ReferenceAPI Overview

API Overview

HTTP endpoints for interacting with Struere

Struere exposes 30 HTTP endpoints through its Convex backend, including the Chat API (POST /v1/agents/:slug/chat), a full Data API for entity CRUD, WhatsApp template management, CLI sync, and 6 webhook receivers for Clerk, Kapso, Flow, Polar, Resend, and studio relay.

Base URL

Your API base URL is shown in the dashboard under Settings > API Keys.

https://api.struere.dev

Authentication

Chat endpoints authenticate via Bearer token using API keys. API keys are created in the Struere dashboard under API Keys and are scoped to a specific environment (development or production).

Authorization: Bearer sk_dev_abc123...

The environment of the API key determines which environment the request operates in. A development API key accesses development agents, entities, and configurations. A production API key accesses production data. There is no way to cross environments with a single key.

API keys are validated by computing a SHA-256 hash and looking up the hashed value in the database.

Permissions

Each API key has a set of permissions that control which endpoints it can access.

Permission Access
* Full access to all endpoints (chat, data, sync)
chat Chat endpoints (/v1/chat, /v1/agents/:slug/chat)
data Data API endpoints (/v1/data/*, /v1/entity-types)
sync CLI sync endpoints (/v1/sync/*)

Keys created in the dashboard default to * (full access). When creating keys programmatically or through the agent settings page, you can restrict permissions to specific scopes.

Endpoints

Method Path Auth Description
GET /health None Health check
POST /v1/chat Bearer token Chat with an agent by ID or router by slug
POST /v1/agents/:slug/chat Bearer token Chat with an agent by slug
POST /v1/routers/:slug/chat Bearer token Chat via a router by slug
POST /v1/compile-prompt Bearer token Compile an agent's system prompt
POST /v1/run-tool Bearer token Run a tool as it would in a real conversation (agentSlug optional)
POST /v1/fire-trigger Bearer token Manually fire a trigger for testing
POST /v1/sync/state Bearer token (sync) Get current sync state for an environment
POST /v1/sync/pull Bearer token (sync) Pull remote resource state for local sync
GET /v1/entity-types Bearer token (data) List entity types
GET /v1/data/:type Bearer token (data) List entities
GET /v1/data/:type/:id Bearer token (data) Get entity by ID
POST /v1/data/:type Bearer token (data) Create entity
POST /v1/data/:type/query Bearer token (data) Query entities with filters
POST /v1/data/:type/search Bearer token (data) Full-text search entities
PATCH /v1/data/:type/:id Bearer token (data) Update entity
DELETE /v1/data/:type/:id Bearer token (data) Delete entity
POST /webhook/clerk None Clerk user/organization sync webhook
POST /webhook/kapso/project HMAC signature WhatsApp phone number connection events
POST /webhook/kapso/messages HMAC signature WhatsApp inbound messages and status updates
POST /webhook/flow None Flow payment status updates
POST /webhook/polar HMAC signature Polar payment/billing events

GET /health

Returns the current server status and timestamp.

Request:

curl https://api.struere.dev/health

Response:

{
  "status": "ok",
  "timestamp": 1710500000000
}

POST /v1/chat

Send a message to an agent identified by its Convex document ID, or route through a router by providing routerSlug instead. See the Chat API documentation for full details.

POST /v1/agents/:slug/chat

Send a message to an agent identified by its slug. This is the preferred endpoint for external integrations as slugs are human-readable and stable across deployments. See the Chat API documentation for full details.

POST /v1/routers/:slug/chat

Send a message through a router identified by its slug. The router evaluates routing rules or classifies the message to determine which agent handles the conversation. See the Chat API documentation for full details.

POST /v1/compile-prompt

Compile an agent's system prompt with template variables resolved. Useful for debugging and testing system prompt templates without sending a real message.

Body:

Field Type Required Description
slug string Yes The agent slug
message string No Sample message for context
channel string No Sample channel (api, whatsapp, widget, dashboard)
threadMetadata object No Sample thread metadata for template resolution

Response: The compiled system prompt text and resolved template variables.

POST /v1/run-tool

Run a tool exactly as it would execute during a real agent conversation. Useful for testing tool behavior without triggering a full agent execution loop.

Body:

Field Type Required Description
agentSlug string No The agent slug to run the tool as. If omitted, runs as system actor
toolName string Yes The tool to execute (e.g., entity.query, whatsapp.send)
args object No Arguments to pass to the tool

Response: The tool execution result, or an error with errorType (not_found, tool_not_found, permission_denied, execution_error).

POST /v1/fire-trigger

Manually fire a trigger by slug. The trigger executes its actions as it would in a real activation, using the system actor. Useful for testing automations without waiting for a real data mutation or cron schedule.

Body:

Field Type Required Description
triggerSlug string Yes The trigger slug to fire
entityId string No Entity ID to use as trigger context
data object No Data payload to pass as trigger context (used in template variable resolution)

Response:

{
  "success": true,
  "triggerSlug": "notify-on-session",
  "result": {
    "steps": [
      { "tool": "entity.get", "status": "success", "durationMs": 45 },
      { "tool": "event.emit", "status": "success", "durationMs": 12 }
    ],
    "durationMs": 57
  }
}

Error Response: Returns an error with errorType (not_found, permission_denied, execution_error).

Data API

CRUD and query operations for entities in your data layer. Requires an API key with the data permission. See the Data API documentation for full details.

Webhook Endpoints

Webhook endpoints receive events from external services. See the Webhooks documentation for details on each webhook.

Error Responses

All endpoints return JSON error responses with appropriate HTTP status codes:

401 Unauthorized — Missing or invalid API key:

{
  "error": "Unauthorized"
}

400 Bad Request — Missing required fields:

{
  "error": "agentId and message are required"
}

500 Internal Server Error — Server-side execution failure:

{
  "error": "Error description"
}

Rate Limiting

Rate limits are enforced at the Convex platform level. Refer to your Convex plan for specific limits on function calls and bandwidth.

CORS

The Chat API and Data API endpoints set permissive CORS headers (Access-Control-Allow-Origin: *), so they can be called directly from browser-based applications without a proxy.

JavaScript Client

The struere npm package ships a typed JS client under the struere/client subpath. It works in browsers, Node 18+, Bun, and Deno with zero runtime dependencies.

import { StruereClient, StruereApiError } from 'struere/client'

const struere = new StruereClient({
  apiKey: process.env.STRUERE_API_KEY!,
  baseUrl: 'https://api.struere.dev',
})

const reply = await struere.chat({
  agentSlug: 'coach',
  message: 'Hi!',
})

const players = await struere.data.list<{ name: string }>('player', { limit: 50 })
const created = await struere.data.create('player', { name: 'Mia' })
const matches = await struere.data.query('player', { filters: { name: { $contains: 'Mia' } } })

try {
  await struere.data.get('player', 'missing')
} catch (err) {
  if (err instanceof StruereApiError) {
    console.error(err.status, err.message, err.requestId)
  }
}

The client throws StruereApiError on non-2xx responses with { status, message, code?, requestId?, details? }. Pass a custom fetch implementation via the fetch option for environments that lack a global.