Xác thực
Xác thực Bearer bằng khóa tích hợp (hlk_): đăng nhập bằng Apple ID sẽ tạo một khóa mặc định, và bạn có thể thêm khóa phạm vi giới hạn cho từng dịch vụ.
Token Format
A key is hlk_ followed by 32 base62 characters (~36 characters total). Only the SHA-256 hash is stored server-side, so a lost key cannot be recovered.
Authorization: Bearer hlk_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345Scopes
| Scope | Access |
|---|---|
activity:update (default) | Update existing activities and read state. Cannot create or delete activities. |
activity:manage | Everything activity:update can do, plus create and delete activities. |
Each key can additionally restrict access to specific activity slugs or prefix patterns (trailing *) and toggle three independent permission flags:
notifications— permitPOST /notifications.widgets— permit the widgets API (POST/GET/PATCH/DELETE /widgets). Off by default; toggle per key in the iOS app's integration-keys screen.emails— permit sending email (POST /emails). Independent ofnotifications; toggle per key in the iOS app's integration-keys screen.
Creating scoped keys
The default key is activity:manage with every capability enabled, which is all most integrations need. To limit a service to just its own activities, create a dedicated key restricted to a scope and slug pattern:
- Open Settings → Manage Keys in the iOS app — the same screen revokes existing keys.
- Tap +.
- Set a name, pick a scope (
activity:updateoractivity:manage), toggle the capability flags the service needs, and optionally restrict the key to a slug pattern such asgrafana-*. - Copy the generated
hlk_key and store it securely -- it is shown only once.
Endpoints
/auth/meGet the current user's profile, activity count, and current quota usage.
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"nickname": "Alice",
"activity_count": 3,
"subscribed": false,
"quota_period_month": 202606,
"notifications_used": 128,
"notifications_limit": 500,
"live_activity_updates_used": 86,
"live_activity_updates_limit": 250,
"widget_updates_used": 12,
"widget_updates_limit": 50,
"emails_used": 3,
"emails_limit": 50,
"quota_resets_at": "2026-07-01T00:00:00Z"
}Integration keys read their own live usage here — the iOS app polls /auth/me for its Usage screen and integrations (e.g. Home Assistant) surface the same counters. A *_limit field is omitted when that resource is uncapped on your tier. (Detailed subscription fields are only returned to the app's own session, not to integration keys.)
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | User ID |
nickname | string | null | Display name |
activity_count | integer | Number of activities owned by the user |
subscribed | boolean | Whether the user has an active subscription |
quota_period_month | integer | YYYYMM bucket for the current monthly usage period (UTC) |
notifications_used / notifications_limit | integer | Notifications sent this period and your tier's cap. *_limit is omitted when uncapped. |
live_activity_updates_used / live_activity_updates_limit | integer | Live Activity updates this month and your tier's cap |
widget_updates_used / widget_updates_limit | integer | Widget updates this month and your tier's cap |
emails_used / emails_limit | integer | Emails sent this month and your tier's cap (free 50, paid 200) |
quota_resets_at | string | ISO 8601 instant the active counters reset |
Access Control
| Access Level | Endpoints |
|---|---|
| No auth | GET /health |
hlk_ with activity:update | PATCH /activities/{slug} (owned activities only), GET /activities, GET /activities/{slug}, POST /notifications (if the key has the notifications flag), GET /auth/me |
hlk_ with activity:manage | All of the above, plus POST /activities, DELETE /activities/{slug} |
hlk_ with widgets flag | POST /widgets, GET /widgets, GET /widgets/{slug}, PATCH /widgets/{slug}, DELETE /widgets/{slug} |
hlk_ with emails flag | POST /emails |