Skip to main content

What this is

Searchable’s REST API is the language-agnostic way to ship request events from your app. It’s a single POST to a Cloudflare-hosted ingest endpoint with an Authorization: Bearer sk_live_… header and a JSON body of one or more events. The server-side AI-bot classifier filters non-AI user agents, so even if you POST every request from your app, only crawlers like GPTBot, ClaudeBot, and PerplexityBot end up in your dashboard.
Use this when the Middleware SDK doesn’t fit — non-Node stacks, in-house CDN workers, batch jobs that replay logs, or anywhere you want fine-grained control over the payload.

Prerequisites

The two credentials from the common prerequisites: a project site token (st_…) and a workspace API key (sk_live_…)
Any runtime that can make an authenticated HTTPS POST — curl, fetch, requests, Go’s net/http, etc.

Endpoint

Requests are authenticated, verified, and forwarded at Cloudflare’s edge — there’s no DB round-trip on the auth path, so you can call this from latency-sensitive contexts.

Request body

Top-level fields

Event fields

Unknown fields are ignored. Fields with bad types are coerced where safe (counts → unsigned int, status codes → uint).

Response

202 is the success status — events are accepted and dispatched asynchronously. There is no synchronous confirmation that an event reached ClickHouse; use the LLM Analytics → Setup status strip to verify end-to-end flow.

Quick start — curl

A successful call returns an empty body and 202 Accepted. Within a few seconds, the Custom card in LLM Analytics → Setup flips to Connected.

Examples

Node — fetch

Don’t await this from a request handler in latency-sensitive paths — either fire it after the response is flushed, or push it onto a worker queue.

Python — requests

Go — net/http

Batching

The endpoint accepts up to 1 MB per request and any number of events in the events array. For high-volume sources, batch events on a short flush interval (e.g. every 5 s or every 100 events) rather than sending one POST per request — fewer network round-trips, same data. Each event in a batch is independent; ingest validates and persists them individually, so a single malformed event doesn’t drop the rest of the batch.

What gets recorded

Even though you can post any HTTP request through this endpoint, Searchable’s server-side classifier only records events whose user_agent matches a known AI crawler. Everything else is dropped silently. That’s intentional: it lets you instrument your app once and not worry about which UAs to filter in your code. The bot list is refreshed daily — new AI agents are picked up automatically. You can sanity-check the classifier against the public bot artifact at:
That’s the same list the worker uses internally — useful if you want to do client-side filtering to reduce ingest load.

Verifying the connection

In Searchable:
  1. Go to LLM Analytics → Setup
  2. Hit the endpoint with a known AI user agent to force a first event (see the curl example)
  3. Click Refresh in the status strip

Troubleshooting

The Authorization header is missing.
  • Check the header is named exactly Authorization (not authorisation, X-Authorization, etc.)
  • The value must be Bearer followed by your sk_live_… key, with one space and no quotes
  • Some CDNs strip Authorization on internal hops — verify the header is present when the request leaves your edge
The API key’s signature failed verification.
  • Confirm you copied the key in full — it’s two URL-safe base64 segments separated by a .
  • If you’ve recently revoked the key in Searchable, generate a new one (Settings → API Keys → New key)
  • Make sure you’re using a key with the Log Events permission — generating from the Custom connector dialog assigns it by default
The body must include site_token at the top level. Don’t put it inside an event object.
events must be an array, even for a single event. Wrap your event in [ … ]:
Request body exceeded 1 MB. Either split into multiple POSTs, or trim large fields (headers, query parameters, custom properties) from each event.
The classifier is dropping them because the user_agent isn’t a known AI crawler. Use an AI UA in your test:
Or fetch the live AI-bot list and confirm your UA matches one of the patterns:

Removing the integration

  1. Stop sending POSTs from your app
  2. In Searchable → Settings → API Keys → revoke the API key
Revoking the key is the cleanest stop — every subsequent POST returns 403, regardless of where it’s coming from.

Next steps

Middleware SDK

On Node? The SDK is one import and handles the payload for you.

See the data

Open LLM Analytics to see which assistants are crawling your site.