API reference

Every route the Trell API exposes, in one place. Browsers talk to the ingestion routes with a publishable key; your servers talk to the management routes with a secret key.

Base URL

All routes below live at https://trepi.relake.co. The tracking SDK is served from https://trepi.relake.co/sdk/trell.js and the health probe at GET /health returns { ok: true }.

Authentication

Publishable key (pk_…) — ships in public pages. Send it as Authorization: Bearer pk_…. For navigator.sendBeacon, which cannot set headers, append ?key=pk_… instead. Requests are checked against the project domain allowlist.

Secret key (sk_…) — server-to-server only, header-only, and never accepted from the browser. Use it for analytics, funnels, views and server-side ingestion. It skips the origin check because servers send no Origin.

Admin key — a single server secret (TRELL_ADMIN_KEY) used only to bootstrap projects via POST /v1/projects.

The secret shows only once

The project secret and any named server keys reveal their value at creation time only — Trell stores hashes. Lose one and you rotate it from workspace settings.

Conventions

Success responses return JSON directly — ingestion answers 202 with { inserted, duplicates }. Failures share one envelope:

json
{
  "error": { "code": "invalid_api_key", "message": "invalid_api_key" }
}
missing_api_key401

No Authorization header was sent.

invalid_api_key401

The key is unknown or revoked.

origin_not_allowed403

The page origin is not in the project domain allowlist.

limit_reached403

The workspace event quota is exhausted (Free 5,000 / Pro 50,000).

invalid_event400

An event payload failed validation.

batch_too_large413

The batch exceeds the maximum event count.

payload_too_large413

The request body exceeds the size limit.

rate_limited429

Too many requests — honor the Retry-After header.

Ingestion is rate-limited per project and IP, and workspaces are metered at 5,000 events on Free and 50,000 on Pro. Exceeding either returns 429 or 403 limit_reached respectively.

Ingestion

Accepts a single event object or an array (batch). Each event carries event_id, type, ts, visitor/session ids, page context, device context and optional form data. The seven types are documented in Events.

POST/v1/ingestpk or sk

Ingest one event or a batch. Answers 202 with inserted and duplicate counts; duplicates are deduped by event_id.

POST/v1/eventspk or sk

Alias of /v1/ingest — same payload, same auth, same response.

bash
curl -X POST https://trepi.relake.co/v1/ingest \
  -H "Authorization: Bearer pk_YOUR_PUBLIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_id": "evt_01JABC",
    "type": "form_submit",
    "ts": "2026-09-12T10:30:00.000Z",
    "session_id": "ses_abc",
    "visitor_id": "vis_abc",
    "url": "https://your-site.com/contact",
    "page": { "path": "/contact", "title": "Contact" },
    "form": { "id": "contact_sales" },
    "device": { "type": "desktop", "os": "Windows", "browser": "Chrome" }
  }'

Projects

POST/v1/projectsadmin

Bootstrap a project: body { name, slug?, organizationName?, domains? }. Answers 201 with the project and its { pk, sk } pair — the sk is shown exactly once.

Analytics

All analytics routes take the project id in the path and accept the standard filters — from, to, type, form, page, device, browser, os and UTM filters — plus an optional segment. The stats route also accepts compareFrom / compareTo for period-over-period deltas.

GET/v1/projects/:id/statssk

KPI metrics for the range, with optional comparison metrics for the compare range.

GET/v1/projects/:id/seriessk

Time series buckets. Query interval=hour|day|week|month (default day).

GET/v1/projects/:id/breakdownsk

Top-N breakdown by dimension=page|utm_source|device|browser|os (default page). Query limit caps rows (default 25).

GET/v1/projects/:id/formssk

Per-form rollups backing the dashboard form table.

GET/v1/projects/:id/eventssk

Paginated raw event log with the standard filters — the same data the dashboard exports to CSV.

GET/v1/projects/:id/funnel-livesk

Live view→start→submit→success funnel for the selected range.

GET/v1/projects/:id/realtimesk

Most recent activity snapshot for realtime panels.

bash
curl "https://trepi.relake.co/v1/projects/PROJECT_ID/stats?from=2026-08-12&to=2026-09-12" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"

Funnels

Funnels are built from ordered event-type steps. Create and edit them with CRUD, then run funnel-compute over any range to get step-to-step conversion and drop-off.

GET/v1/projects/:id/funnelssk

List saved funnels.

POST/v1/projects/:id/funnelssk

Create a funnel from an ordered step list.

GET/v1/projects/:id/funnels/:fidsk

Fetch one funnel definition.

PATCH/v1/projects/:id/funnels/:fidsk

Update a funnel definition.

DELETE/v1/projects/:id/funnels/:fidsk

Delete a funnel.

POST/v1/projects/:id/funnel-computesk

Compute conversion over a range for ad-hoc or saved step lists.

Saved views

GET/v1/projects/:id/viewssk

List saved dashboard views.

POST/v1/projects/:id/viewssk

Save the current filter set as a named view.

DELETE/v1/projects/:id/views/:vidsk

Delete a saved view.

Prefer clicking over curl? Every route above is exercised by the dashboard relay documented in Routes.

MCP server

AI assistants talk to Trell through a separate host: https://mcp.relake.co — not https://trepi.relake.co, which serves only the REST API above. It speaks Streamable HTTP, authenticates with a Bearer service key or OAuth, and exposes 28 tools for reading stats, managing funnels, webhooks, domains and keys.

Full endpoint, auth, scope and tool reference lives on its own page: MCP server.