Drifty API
The Drifty API lets you read your own records over HTTPS, for example to show today’s focus time on your website or to build a weekly report. It is part of Pro, including a trial.
The API reads what your computers have synced to Drifty Cloud. Turn sync on in Settings → Sync on each computer whose records you want to read; a computer with sync off contributes nothing.
Create a key
Section titled “Create a key”- Open Settings → Agents, CLI & API and choose New key.
- Name it, choose what it can read, and choose when it expires.
- Copy the key. Drifty shows it only once and keeps only a fingerprint of it.
| Permission | What it can read |
|---|---|
| Summary | Focus, neutral and drift time per day, categories, and time by app and site |
| Activity | Each recorded stretch with its app, site and window or page title |
Apps and sites you exclude never appear, including records synced before you excluded them. The page address itself is never sent, though a window or page title can contain whatever the page showed.
Each key in the list shows its last characters, what it can read, when it was created and when it expires, and when it was last used. An account can have 10 keys. Delete a key from its ⋯ menu and anything using it stops working at once. Keys are paused while your account has no Pro access and work again when it returns, unless they have expired.
Keep keys on a server, for example in an environment variable. A key written into a web page’s code can be read by anyone who opens the page, so the API does not answer requests made from a browser page.
Make a request
Section titled “Make a request”Send the key as a bearer token. Every endpoint is a GET under https://drifty.so/api/v1 and answers JSON.
curl -H "Authorization: Bearer $DRIFTY_API_KEY" \ "https://drifty.so/api/v1/summary?tz=Asia/Seoul"Days run from midnight to midnight in the time zone you pass as tz (an IANA name such as Europe/Berlin; the default is UTC). Dates are written YYYY-MM-DD and must fall in 2000–2099.
| Endpoint | Permission | Returns |
|---|---|---|
/me |
any | key (id, name, scopes, createdAt, expiresAt) and rateLimit |
/summary?date=&tz= |
Summary | One day (default today): tracked, focus, neutral, drift and unclassified seconds, focus share, time by category, top apps and sites |
/days?from=&to=&tz= |
Summary | Daily totals for up to 31 days (default the last 7) |
/activity?date=&tz= |
Activity | items in time order, limit up to 500 (default 100); pass nextCursor back as cursor for the next page. from and to ISO times (up to 31 days apart) can replace date. |
A summary looks like this:
{ "timeZone": "Asia/Seoul", "from": "2026-10-25T15:00:00.000Z", "to": "2026-10-26T15:00:00.000Z", "date": "2026-10-26", "trackedSeconds": 27000, "focusSeconds": 18000, "neutralSeconds": 5400, "driftSeconds": 3600, "unclassifiedSeconds": 0, "focusShare": 0.6667, "categories": [{ "category": "workspace", "seconds": 16200 }], "apps": [{ "name": "Visual Studio Code", "seconds": 12600 }], "sites": [{ "domain": "github.com", "seconds": 3000 }], "devices": 2, "lastActivityAt": "2026-10-26T09:41:00.000Z"}Each activity item has id, deviceId, start, end, durationSeconds, app, bundleId, site, windowTitle, pageTitle, category, productivity and platform. Days in /days carry the same totals as a summary without the category, app and site lists.
Time that two computers recorded at once counts once, as in the app. Categories you added yourself appear as custom. The numbers follow the productivity each computer recorded, so they can differ slightly from the app if you changed how a category counts.
Limits and errors
Section titled “Limits and errors”Each key can make 60 requests a minute, and all of an account’s keys together 120. Errors look like { "error": { "code": "…", "message": "…" } }.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request |
A parameter is missing or out of range |
| 401 | missing_api_key, invalid_api_key |
No key, or a key that is wrong, expired or deleted |
| 402 | plan_required |
The account has no Pro access |
| 403 | insufficient_scope |
The key lacks the permission this endpoint needs |
| 404 | not_found |
No such endpoint |
| 405 | method_not_allowed |
Only GET is answered |
| 409 | sync_paused |
The cloud copy is being deleted or was deleted; turn sync on again |
| 422 | range_too_large |
The range holds too many records; ask for fewer days |
| 429 | rate_limited |
Too many requests; wait for Retry-After seconds |
| 500 | server_error |
Something failed on our side; try again |
Records reach the API after your computers sync, so the latest minutes can lag a little.