Browse the docs
API reference
Time and leave
The caller's own time, leave, expenses, and the workspace's goals.
My time
GET/v1/time
The caller's running timer and own time entries between two days (default the last 7, max 31). Never rates, costs or anyone else's time.
Requires time.read
Query parameters
fromstringYYYY-MM-DD; defaults to six days before to.
tostringYYYY-MM-DD; defaults to today in the caller's timezone.
curl "https://atrix.dev/api/v1/time" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"timer": {
"id": "cm4r6a1bc0008wq08k5m2p7xz",
"startedAt": "2026-10-27T05:12:40.000Z",
"projectId": "cm3y1k7mn0000ab07c3d5f8gh",
"projectName": "Atrix AI",
"issueId": "cm4c2n9qr0011de08f6h3j1kw",
"issueTitle": "Fix invite dead end",
"note": "",
"billable": true
},
"todayMinutes": 48,
"timezone": "Asia/Dubai",
"entries": [
{
"id": "cm4r5t8yu0007wq08e2j9n4lb",
"date": "2026-10-26",
"minutes": 90,
"projectId": "cm3y1k7mn0000ab07c3d5f8gh",
"projectName": "Atrix AI",
"issueId": null,
"issueTitle": null,
"note": "Onboarding review",
"billable": true,
"source": "MANUAL",
"running": false,
"locked": false,
"invoiced": false,
"start": "2026-10-26T05:00:00.000Z",
"end": "2026-10-26T06:30:00.000Z"
}
],
"totalMinutes": 90
}Log time
POST/v1/time/log
Logs time already worked on a day that is not in the future, optionally from a start time. Refused if that week is submitted or approved.
Requires time.write
Body
datestringrequiredYYYY-MM-DD, not in the future.
minutesintegerrequired1 to 1440.
startstringHH:MM in the caller's timezone.
projectIdstringA product id, slug or name.
issueIdstringAn issue id or title; its product is used.
notestringUp to 500 characters.
curl -X POST "https://atrix.dev/api/v1/time/log" \
-H "Authorization: Bearer $ATRIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "date": "…", "minutes": 1 }'{
"entry": {
"id": "cm4r5t8yu0007wq08e2j9n4lb",
"date": "2026-10-26",
"minutes": 90,
"projectId": "cm3y1k7mn0000ab07c3d5f8gh",
"projectName": "Atrix AI",
"issueId": null,
"issueTitle": null,
"note": "Onboarding review",
"billable": true,
"source": "MANUAL",
"running": false,
"locked": false,
"invoiced": false,
"start": "2026-10-26T05:00:00.000Z",
"end": "2026-10-26T06:30:00.000Z"
},
"overlap": false
}Start my timer
POST/v1/time/timer/start
Starts the caller's timer, optionally on a product and/or issue. A timer already running is stopped and saved first.
Requires time.write
Body
projectIdstringA product id, slug or name.
issueIdstringAn issue id or title; its product is used.
notestringUp to 500 characters.
curl -X POST "https://atrix.dev/api/v1/time/timer/start" \
-H "Authorization: Bearer $ATRIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "projectId": "cm9x2k1a0000", "issueId": "cm9x2k1a0000" }'{
"timer": {
"id": "cm4r6a1bc0008wq08k5m2p7xz",
"startedAt": "2026-10-27T05:12:40.000Z",
"projectId": "cm3y1k7mn0000ab07c3d5f8gh",
"projectName": "Atrix AI",
"issueId": "cm4c2n9qr0011de08f6h3j1kw",
"issueTitle": "Fix invite dead end",
"note": "",
"billable": true
},
"stoppedPrevious": false
}Stop my timer
POST/v1/time/timer/stop
Stops the caller's running timer and saves it as one or more entries, split at midnight. 422 when no timer is running.
Requires time.write
curl -X POST "https://atrix.dev/api/v1/time/timer/stop" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"minutes": 52,
"entryIds": [
"cm4r6a1bc0008wq08k5m2p7xz"
],
"discarded": false,
"overlap": false
}My leave
GET/v1/leave/balances
The caller's annual-leave balance for this year, the leave types they can request, their upcoming and pending requests, and who approves them.
Requires leave.read
curl "https://atrix.dev/api/v1/leave/balances" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"balance": {
"year": 2026,
"entitled": 22,
"carryIn": 3,
"used": 9,
"pending": 2,
"remaining": 14
},
"types": [
{
"key": "ANNUAL",
"name": "Annual leave",
"paid": true,
"requiresApproval": true
}
],
"upcoming": [
{
"id": "cm4s1e4fg0003pl08t7w2y5ua",
"type": "ANNUAL",
"typeName": "Annual leave",
"start": "2026-11-16",
"end": "2026-11-17",
"startHalf": false,
"endHalf": false,
"days": 2,
"status": "PENDING",
"reason": null,
"canCancel": true
}
],
"approvers": [
"Moeid Saleem"
],
"today": "2026-10-27"
}Who is out today
GET/v1/leave/out-today
Names of colleagues out of office today. Never the type of leave, a reason or the dates.
Requires leave.read
curl "https://atrix.dev/api/v1/leave/out-today" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"out": [
{
"name": "Sara Khan"
}
]
}Request leave
POST/v1/leave/requests
Asks for leave for the caller, counting working days and checking balance and clashes, then notifies approvers. With dryRun true it only returns the preview.
Requires leave.write
Body
typestringrequiredA leave type key from /leave/balances, e.g. ANNUAL or SICK.
startstringrequiredYYYY-MM-DD.
endstringrequiredYYYY-MM-DD, not before start.
startHalfbooleanStart with a half day (afternoon only).
endHalfbooleanEnd with a half day (morning only).
reasonstringUp to 500 characters, shown to the caller and their approvers only.
dryRunbooleanPreview without submitting.
curl -X POST "https://atrix.dev/api/v1/leave/requests" \
-H "Authorization: Bearer $ATRIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "type": "…", "start": "…", "end": "…" }'{
"request": {
"id": "cm4s1e4fg0003pl08t7w2y5ua",
"status": "PENDING",
"days": 2,
"start": "2026-11-16",
"end": "2026-11-17"
},
"preview": {
"days": 2,
"holidays": [],
"weekendDays": 0,
"remaining": 14,
"after": 12,
"needsApproval": true,
"crowded": [
{
"date": "2026-11-16",
"count": 1
}
]
},
"notified": [
"Moeid Saleem"
]
}Cancel my leave
DELETE/v1/leave/requests/{id}
Cancels one of the caller's own pending or approved requests while the app still allows it; approvers are told.
Requires leave.write
Path parameters
idstringrequiredThe leave request id.
curl -X DELETE "https://atrix.dev/api/v1/leave/requests/ID" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"cancelled": {
"id": "cm4s1e4fg0003pl08t7w2y5ua",
"start": "2026-11-16",
"end": "2026-11-17",
"days": 2
}
}My expenses
GET/v1/expenses
The caller's own claims with expenses dated in a window (default the last 30 days, max 92), with status and totals in minor units. Receipts are flagged, never returned.
Requires expenses.read
Query parameters
fromstringYYYY-MM-DD; defaults to 29 days before to.
tostringYYYY-MM-DD; defaults to today.
curl "https://atrix.dev/api/v1/expenses" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"from": "2026-09-28",
"to": "2026-10-27",
"receiptRequiredAboveMinor": 5000,
"claims": [
{
"id": "cm4t3g7hj0001mn08r4s6v9xc",
"title": "October expenses",
"status": "SUBMITTED",
"currency": "USD",
"claimTotalMinor": 4250,
"inRangeMinor": 4250,
"submittedAt": "2026-10-20T11:03:00.000Z",
"decidedAt": null,
"decisionNote": null,
"reimbursedAt": null,
"blocker": null,
"items": [
{
"id": "cm4t3g8kl0002mn08w1x3z5bd",
"date": "2026-10-19",
"merchant": "Careem",
"category": "TRAVEL",
"amountMinor": 4250,
"note": "",
"hasReceipt": false,
"projectName": null
}
]
}
],
"totalsMinorByCurrency": {
"USD": 4250
}
}File an expense
POST/v1/expenses
Adds an expense for the caller and sends it for approval. If the amount needs a receipt, or it joins an open draft that already has expenses, it stays a DRAFT with submitted false.
Requires expenses.write
Body
datestringrequiredYYYY-MM-DD, the day it was paid.
amountnumberrequiredPositive, in major units, e.g. 12.50.
currencystringrequiredA three-letter code, e.g. USD.
categoryenumrequiredThe expense category.
TRAVELMEALSSOFTWAREEQUIPMENTOTHERmerchantstringrequired1-80 characters.
notestringUp to 400 characters.
curl -X POST "https://atrix.dev/api/v1/expenses" \
-H "Authorization: Bearer $ATRIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "date": "…", "amount": 1, "currency": "…", "category": "TRAVEL", "merchant": "…" }'{
"claimId": "cm4t3g7hj0001mn08r4s6v9xc",
"itemId": "cm4t3g8kl0002mn08w1x3z5bd",
"submitted": true,
"status": "SUBMITTED",
"message": "Sent for approval."
}Delete a draft claim
DELETE/v1/expenses/{id}
Deletes one of the caller's own DRAFT claims and the expenses in it. Anything sent, approved or paid is refused.
Requires expenses.write
Path parameters
idstringrequiredThe claim id.
curl -X DELETE "https://atrix.dev/api/v1/expenses/ID" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"deleted": "cm4t3g7hj0001mn08r4s6v9xc"
}Send a draft claim
POST/v1/expenses/{id}/submit
Sends one of the caller's own DRAFT claims for approval. 404 if it is not theirs, 409 if already sent, 422 when it cannot be sent yet (e.g. a required receipt is missing).
Requires expenses.write
Path parameters
idstringrequiredThe claim id.
curl -X POST "https://atrix.dev/api/v1/expenses/ID/submit" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"claimId": "cm4t3g7hj0001mn08r4s6v9xc",
"submitted": true,
"status": "SUBMITTED",
"message": "Sent for approval."
}Attach a receipt
POST/v1/expenses/items/{itemId}/receipt
Attaches or replaces the receipt on one of the caller's own draft expenses, as multipart file or raw bytes (JPEG, PNG, WebP, HEIC or PDF, up to 8 MB). 404 not theirs, 409 no longer a draft, 413 too large, 415 wrong type, 429 over the day's count.
Requires expenses.write
Path parameters
itemIdstringrequiredThe expense item id.
Body
filefileThe receipt as a multipart/form-data part; or send the raw bytes as the body instead.
curl -X POST "https://atrix.dev/api/v1/expenses/items/ITEMID/receipt" \
-H "Authorization: Bearer $ATRIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "file": "…" }'{
"claimId": "cm4t3g7hj0001mn08r4s6v9xc",
"itemId": "cm4t3g8kl0002mn08w1x3z5bd",
"hasReceipt": true,
"receipt": {
"mime": "image/jpeg",
"name": "careem-receipt.jpg"
}
}List goals
GET/v1/goals
Goals whose period overlaps a window (default this quarter), with owner, status, rolled-up progress 0-100 and whether a check-in is due. Other people's private goals are never returned.
Requires goals.read
Query parameters
fromstringYYYY-MM-DD; defaults to the start of this quarter.
tostringYYYY-MM-DD; defaults to the end of this quarter.
minebooleanOnly goals the caller owns.
statusenumOnly goals with this status.
ON_TRACKAT_RISKOFF_TRACKDONE
curl "https://atrix.dev/api/v1/goals" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"period": {
"start": "2026-10-01",
"end": "2026-12-31"
},
"goals": [
{
"id": "cm4u8j2kl0004qr08h6n1p3ty",
"title": "Reach 50 paying workspaces",
"level": "COMPANY",
"status": "AT_RISK",
"ownerId": "cm3z8p1aa0000qs07h2k5t9we",
"ownerName": "Sara Khan",
"parentGoalId": null,
"periodStart": "2026-10-01",
"periodEnd": "2026-12-31",
"visibility": "WORKSPACE",
"progress": 38,
"krCount": 3,
"lastCheckInAt": "2026-10-20T09:00:00.000Z",
"checkInDue": true,
"mine": true,
"canEdit": true
}
]
}Get a goal
GET/v1/goals/{id}
One goal with key results, recent check-ins, the goals above and below it, and linked products and issues. Deal amounts are null unless the caller may see deal values; a private goal that is not theirs is a 404.
Requires goals.read
Path parameters
idstringrequiredThe goal id.
curl "https://atrix.dev/api/v1/goals/ID" \
-H "Authorization: Bearer $ATRIX_TOKEN"{
"id": "cm4u8j2kl0004qr08h6n1p3ty",
"title": "Reach 50 paying workspaces",
"status": "AT_RISK",
"progress": 38,
"description": "Self-serve conversions only.",
"expected": 30,
"keyResults": [
{
"id": "cm4u8j3mn0005qr08x2c4v6bn",
"title": "Paying workspaces",
"kind": "NUMBER",
"source": "MANUAL",
"unit": null,
"progress": 38,
"start": 0,
"target": 50,
"current": 19,
"redacted": false,
"note": null,
"linkProject": null,
"linkIssue": null
}
],
"checkIns": [
{
"id": "cm4u9a1bc0006qr08d4f7g9hj",
"status": "AT_RISK",
"note": "Trial conversion is slow.",
"progress": 38,
"at": "2026-10-20T09:00:00.000Z",
"authorName": "Sara Khan"
}
],
"ancestors": [],
"children": [],
"links": [
{
"id": "cm4u9b2cd0007qr08k1l3m5np",
"kind": "project",
"label": "Atrix AI",
"href": "/dashboard/projects/atrix-ai"
}
]
}Check in on a goal
POST/v1/goals/{id}/check-in
Posts a check-in as the caller with a status, note and optional new values for manual key results. Only the goal's owner or a workspace admin may.
Requires goals.write
Path parameters
idstringrequiredThe goal id.
Body
statusenumrequiredThe goal's status as of this check-in.
ON_TRACKAT_RISKOFF_TRACKDONEnotestringUp to 2000 characters.
valuesobject[]Up to 12 of { krId, value }, new current values for manual key results.
curl -X POST "https://atrix.dev/api/v1/goals/ID/check-in" \
-H "Authorization: Bearer $ATRIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "status": "ON_TRACK" }'{
"progress": 42
}