Skip to content

Public API reference

Facts reviewed:

Use the SDK for browser tracking. Use these HTTP APIs for server jobs, integrations, and trusted AI tools. The API base is https://api.owleye.dev; unlike the browser SDK, an HTTP client needs a complete URL.

Credential Purpose Where to get it Where it belongs
Public Tracking ID (owl_…) Browser SDK events and rules App Overview or Settings Browser code
Ingestion API key, events:write Send server events App API Keys Your server or secret store
Developer key, stats:read Query aggregate reports Settings → Developer mode Your server
Developer key, events:read Read bounded event exports Settings → Developer mode Your server
Developer key, ai:prompt Ask the OwlEye AI analyst Settings → Developer mode Your server or trusted tool executor

These secret key families are separate and cannot be substituted for each other. A key is scoped to one app. Use the matching public Tracking ID in requests; a different app cannot be accessed just by changing the URL or JSON.

Send either header:

Authorization: Bearer YOUR_SECRET_KEY
x-owleye-api-key: YOUR_SECRET_KEY

Do not send secrets in URL query strings, browser bundles, SDK options, public notebooks, or LLM prompts. CORS is not granted on these server-to-server secret-key interfaces. Console session endpoints are internal to the console and are not an automation API.

Method Path Required scope Guide
POST /v1/events/api events:write Server ingestion
GET /v1/developer/sites/{siteId}/stats stats:read Analytics queries
GET /v1/developer/sites/{siteId}/events events:read Event pagination
POST /v1/developer/sites/{siteId}/prompt ai:prompt AI integrations

Browse endpoints, parameters, and response models in the OpenAPI explorer, or download the OpenAPI JSON schema. Browser SDK transport uses /v1/events and /v1/rules with its public Tracking ID; prefer the SDK over implementing that browser protocol yourself.

Developer APIs require the app owner to enable both Developer mode and API access. Pro permits stats:read; Business and Custom permit all three developer scopes. Current plan, ownership, expiry, revocation, and toggles are checked on each request.

Developer API requests share an organization allowance of 60 requests/minute on Pro or 600 on Business/Custom, with a separate source-IP ceiling of 600/minute. These are refilling token buckets, not a promise of full burst capacity every minute. Ingestion has separate limits and consumes the app’s event allowance.

Status Action
400 Correct the request fields or bounds
401 Check key, expiry, revocation, and developer toggles
403 Check app scope, role, plan, and feature access
409 Resolve a duplicate/conflicting request; do not blindly retry
413 Reduce the request body size
429 Wait for Retry-After and reduce concurrency
5xx Retry eligible reads with bounded backoff; verify ingestion before replaying events

Successful developer responses use Cache-Control: no-store. Keep analytics out of shared public caches. Store newly created keys immediately: their secrets are only shown once. See developer access setup.

Console routes have a shared 120-request/minute per-IP budget checked before session-token validation, SQLite session lookup, or app-membership lookup. This covers current and legacy Console routes, including the session endpoint. Anonymous and forbidden requests consume the same budget; changing cookies, paths, query strings, or source ports does not create a new one. Only configured trusted proxies can supply a forwarded client IP.

The existing 60-request/minute per-session-and-IP limit still applies after authentication. Both are refilling token buckets: the IP bucket holds at most 120 requests and refills at two per second. Users behind one public IP share the early budget. Exhaustion returns 429 with Retry-After before database work; responses remain private, no-store. The early limiter has a separate bounded pool of 4,000 tracked IP buckets so anonymous traffic cannot consume the authenticated session limiter’s storage. CORS preflights do not access the database or consume this request budget. Limits are process-local, as with other API limits.

Successful GET and HEAD responses from /version and /v1/openapi.json use Cache-Control: public, max-age=3600, must-revalidate. Browsers and shared caches may reuse this deployment metadata for one hour. These unversioned URLs are not marked immutable, so a deployment can remain unseen in an existing cached copy for up to one hour. Error responses, health endpoints, login configuration and authenticated data keep their existing private, no-store policy. Client caching reduces normal repeated requests; clients can ignore it, so it is not an abuse rate limit.

The hosted API limits each of /health, /health/live, and /health/ready to one request per IP per endpoint every 120 seconds, with no burst allowance. GET and HEAD share the same budget; query strings do not create a new budget. Excess requests return 429 with Retry-After. Loopback probes follow the same limit. Forwarded client IPs are accepted only from configured trusted proxies.

All three endpoints share their own in-memory snapshot across clients for 60 seconds per API process. Concurrent cache misses run one probe per endpoint; disconnecting a client does not cancel the shared refresh. Failed checks are cached too and return 503. A database-backed probe has a three-second timeout. /health/live does not query a database; /health checks SQLite; /health/ready checks SQLite, ClickHouse, and hosted retention readiness.

Responses expose X-OwlEye-Health-Age in seconds. HTTP responses remain Cache-Control: private, no-store: caching happens inside the API, not in browsers or a CDN. An expired snapshot refreshes on the next eligible request; this is not a background monitor or a guarantee of detecting failures within one minute. A single monitoring IP must poll each endpoint no more often than every two minutes and obey Retry-After (use 121 seconds to allow timing margin). A process restart clears snapshots and rate buckets. Limits are process-local; multiple replicas need shared or edge enforcement.

Console login capabilities use the database-free /v1/auth/config endpoint, with its separate 60-per-minute IP budget, so health polling limits do not hide sign-in methods.