CohorlyDocs
GitHub

Admin API

The admin and query endpoints let you manage projects and pull data programmatically. Everything under /api/* is authenticated with your account API key - find it in the dashboard under Settings. This page covers project management, event metadata, users, and stats; the analytical queries are on the Queries page.

!

The API key grants read and admin access to all your projects. Keep it server-side - never ship it in client code. For client-side event tracking use the project token instead.

Authentication

Send Authorization: Bearer $API_KEY on every /api/* request. A missing or wrong key returns 401.

bash
curl https://api.cohorly.com/api/projects \
  -H "Authorization: Bearer $API_KEY"

Projects

GET/api/projects

List all projects with their event counts. Each item is { id, name, token, created_at, event_count }.

json
[
  {
    "id": 1,
    "name": "default",
    "token": "0c0f5e2a-...",
    "created_at": 1751600000000,
    "event_count": 1284
  }
]
POST/api/projects

Create a project. Body { name }. Returns the created project with a fresh UUID token (201). A duplicate name returns 409; a missing name returns 400.

bash
curl -X POST https://api.cohorly.com/api/projects \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "mobile-app" }'
DELETE/api/projects/:id

Delete a project and all of its data. Returns 409 if it is the last remaining project (you cannot delete them all).

Event metadata

These GETs accept an optional projectId query param; omitting it targets your first project, so pass it explicitly when you track more than one app.

GET/api/events?projectId=

Recent raw events for the project.

GET/api/events/names?projectId=

Distinct event names seen in the project - useful for autocomplete.

GET/api/events/properties?event=&projectId=

Property keys observed on a given event name.

Users

GET/api/users?limit&search&projectId=

List user profiles, optionally filtered by search and capped by limit.

GET/api/users/:distinctId?projectId=

Fetch a single profile. The shape is a UserProfile:

ts
interface UserProfile {
  distinct_id: string;
  properties: Record<string, unknown>;
  first_seen: number | null; // unix ms
  last_seen: number | null;  // unix ms
  event_count: number;
}

Stats

GET/api/stats?projectId=

Summary counts for the project, shown on the dashboard overview:

json
{
  "events": 12345,
  "users": 321,
  "profiles": 280,
  "event_names": 14,
  "events_today": 97
}

Status (no auth)

Public health endpoints backing the status page - no Bearer key or project token required.

GET/status

Current health: { ok, db, uptime_seconds, latest }, where latest is the most recent recorded health check ({ checked_at, ok, latency_ms }) or null.

GET/status/history?days=90

Daily uptime aggregates (days clamped 1-90): { date, total, ok_count, uptime_pct, avg_latency_ms }[]. The server records a health check every 60 seconds and keeps 90 days of history.