Skip to main content

API Reference

Xenith's public API lets you read and write your own data — intentions, focus sessions, and dimension scores — from your own scripts, tools, or integrations. It's your data; the API just gives you a way to reach it programmatically.

Authentication

Create an API key in Settings → API access. The raw key is shown once, at creation — store it somewhere safe, since Xenith only ever stores its hash.

Send it as a bearer token on every request:

curl https://xenith.life/api/v1/intentions \
-H "Authorization: Bearer xnth_live_..."

Requests without a valid key get 401 Unauthorized. You can revoke a key at any time from the same Settings page — it stops working immediately.

Base URL

https://xenith.life/api/v1

Rate limits

Each key is limited to 60 requests per minute. Responses include a remaining field showing how many requests you have left in the current window; going over returns 429 with { "error": "rate_limited" }.

Errors

Errors are always a JSON body with an error field:

StatusMeaning
400Invalid request body or query parameters
401Missing or invalid API key
403Your key doesn't have the required scope
429Rate limit exceeded
500Something went wrong on Xenith's end

Intentions

GET /api/v1/intentions

Requires scope intentions:read.

Query parameters (all optional):

ParamDescription
scheduled_dateFilter to a single date (YYYY-MM-DD)
completedtrue or false
limitMax results, 1–100 (default 50)
cursorPagination cursor — pass the previous response's next_cursor
curl "https://xenith.life/api/v1/intentions?scheduled_date=2026-07-12" \
-H "Authorization: Bearer xnth_live_..."
{
"data": [ /* intention rows */ ],
"remaining": 59,
"next_cursor": null
}

POST /api/v1/intentions

Requires scope intentions:write.

Body:

FieldTypeRequired
titlestring (1–200 chars)yes
descriptionstring (max 2000 chars)no
scheduled_datestring (YYYY-MM-DD)no
dimensionstringno
estimated_minutesinteger (1–1440)no
curl -X POST https://xenith.life/api/v1/intentions \
-H "Authorization: Bearer xnth_live_..." \
-H "Content-Type: application/json" \
-d '{"title": "Write the quarterly review", "dimension": "Work"}'

Focus sessions

GET /api/v1/focus-sessions

Requires scope focus_sessions:read.

Query parameters (all optional): start, end (ISO timestamps to filter started_at), limit (1–100, default 50), cursor.

POST /api/v1/focus-sessions

Requires scope focus_sessions:write. Logs a completed (or in-progress) focus session — this is a record of actual timer usage, not a way to schedule a future session, so started_at can't be more than 24 hours in the future.

Body:

FieldTypeRequired
duration_minutesinteger (1–1440)yes
session_typestringno
notesstring (max 2000 chars)no
started_atISO timestampno
completed_atISO timestampno

Dimension scores

GET /api/v1/dimension-scores

Requires scope dimension_scores:read. Read-only — scores are recorded through Xenith's own weekly check-in, not writable via the API.

Query parameters (all optional):

ParamDescription
dimensionFilter to one life dimension
history1 to return full history; omitted returns only the latest score per dimension

Scopes

New API keys currently receive all available scopes:

  • intentions:read, intentions:write
  • focus_sessions:read, focus_sessions:write
  • dimension_scores:read

Per-scope key creation is on the roadmap; for now, every key can do everything listed above.

CORS

All /api/v1/* endpoints allow cross-origin requests from any origin — authentication is entirely via the Authorization header (never cookies), so there's no ambient browser credential to protect against.