Sandtime.io REST API
Use the Sandtime.io REST API from cURL or any standard HTTP client. The current reference documents verified operations across public route paths, plus a machine-readable OpenAPI schema.
When to use REST
The REST API is the right fit when your environment only supports plain HTTP, when you want cURL examples, or when you need direct control over payloads and endpoint URLs.
For AI agents, Sandtime.io still recommends the MCP server first because MCP exposes higher-level workflows and more ergonomic tool contracts. Reach for REST when MCP is unavailable or when the user explicitly asks for raw HTTP.
- Use REST when you need direct HTTP control, cURL scripts, CI jobs, or a standard API client.
- Use the OpenAPI JSON when you want to generate clients, validate requests, or feed the schema to tooling.
- Use MCP instead when an AI client can call tools directly and benefit from higher-level workflows.
Authenticate with a Bearer token
REST requests target your organization hostname directly, for example https://acme.sandtime.io/api. The hostname identifies the workspace, so REST does not require the X-Sandtime-Organization header used by MCP.
curl -X GET 'https://your-organization.sandtime.io/api/auth' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Machine-readable docs and API conventions
Everything below is backed by the same shared route registry that also generates the OpenAPI JSON.
OpenAPI JSON
A downloadable OpenAPI schema for code generation, validators, and API tooling.
https://sandtime.io/api/openapi.jsonSKILL.md
A machine-readable integration guide for agents deciding between MCP and raw HTTP.
https://sandtime.io/SKILL.mdMCP docs
The higher-level integration path for Claude Code, Codex, and other MCP clients.
https://sandtime.io/mcpRequest conventions
- Base URL: one workspace per hostname, for example https://acme.sandtime.io/api.
- Authentication: send Authorization: Bearer <token>. Today the token is copied from the sandtime_access_token cookie.
- Format: requests and responses use JSON. Route-specific examples below mirror the current server implementation.
- Workflow: resolve IDs with read requests before writes so you never guess project, user, member, or report identifiers.
Route groups
Jump into a namespace, then inspect each route path, supported methods, request body examples, and sample responses.
Workspace
Workspace discovery, organization settings, and authentication helpers.
Activities
Time entry CRUD for manual logging, timers, and admin corrections.
Projects
Projects, memberships, and project-specific revenue rates.
Users
Users, personal preferences, and organization-level cost rates.
Geofences
Geofence definitions plus mobile enter and exit triggers.
Requests
Approval and assignment workflows live under /requests.
- /requests/projects/{projectId}/members/{memberId}/role
- /requests/{requestId}/projects/members/role
- /requests/projects/{projectId}/members
- /requests/{requestId}/projects/members
- /requests/projects/request-assignment
- /requests/{requestId}/projects/assign
- /requests/{requestId}
- /requests/timesheets/{year}/{week}/unlock
- /requests/{requestId}/timesheets/unlock
- /requests/timesheets/{year}/{week}/approvals
- /requests/{requestId}/timesheets/approvals
Timesheets
Explicit timesheet locks, automatic lock execution, and reminder delivery.
Billing
Billing, plan changes, and checkout helpers.
Workspace
Workspace discovery, organization settings, and authentication helpers.
Authentication snapshot
Read the current cookie-backed auth snapshot or list the organizations available to the signed-in user.
Get the current auth snapshot
Returns the current user email, active organization domain, and the same Bearer token currently extracted from the session cookie.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/auth' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"domain": "acme",
"email": "alex.rivera@example.com",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example"
}Organizations
List the active organizations available to the signed-in user account.
List active organizations
Returns the active workspaces available to the current user across Sandtime.io.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/organizations' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
[
{
"active": true,
"domain": "acme",
"name": "Acme Studio"
},
{
"active": true,
"domain": "northwind",
"name": "Northwind Consulting"
}
]Organization settings
Read, update, or permanently remove the current organization.
Get organization settings
Returns the organization settings loaded for the current hostname.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/organization' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"coreHours": {
"end": "17:00",
"start": "09:00"
},
"currency": "USD",
"holidays": {
"country": "US",
"excluded": []
},
"id": "8a4affba-df59-47bd-8173-d175e76efd15",
"lockingTimesheets": {
"enabled": false,
"timeZone": null,
"week": null,
"year": null
},
"name": "Acme Studio",
"notes": "Weekly client delivery team.",
"onboarding": {
"assignMembers": {
"done": true,
"viewed": true
},
"inviteMembers": {
"done": true,
"viewed": true
},
"organization": {
"done": true,
"viewed": true
},
"preferences": {
"done": false,
"viewed": true
},
"projects": {
"done": true,
"viewed": true
}
},
"plan": "free",
"rounding": {
"enabled": false,
"interval": 900000,
"mode": "NEAREST"
},
"timeZone": "Europe/Warsaw"
}Update organization settings
Updates mutable organization settings such as currency, notes, core hours, holidays, rounding, and timesheet locking.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/organization' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"coreHours": {
"end": "16:00",
"start": "08:00"
},
"currency": "EUR",
"notes": "Updated delivery schedule for the summer quarter.",
"rounding": {
"enabled": true,
"interval": 900000,
"mode": "NEAREST"
},
"timeZone": "Europe/Warsaw"
}'Request body example
{
"coreHours": {
"end": "16:00",
"start": "08:00"
},
"currency": "EUR",
"notes": "Updated delivery schedule for the summer quarter.",
"rounding": {
"enabled": true,
"interval": 900000,
"mode": "NEAREST"
},
"timeZone": "Europe/Warsaw"
}Response example
{
"coreHours": {
"end": "17:00",
"start": "09:00"
},
"currency": "USD",
"holidays": {
"country": "US",
"excluded": []
},
"id": "8a4affba-df59-47bd-8173-d175e76efd15",
"lockingTimesheets": {
"enabled": false,
"timeZone": null,
"week": null,
"year": null
},
"name": "Acme Studio",
"notes": "Weekly client delivery team.",
"onboarding": {
"assignMembers": {
"done": true,
"viewed": true
},
"inviteMembers": {
"done": true,
"viewed": true
},
"organization": {
"done": true,
"viewed": true
},
"preferences": {
"done": false,
"viewed": true
},
"projects": {
"done": true,
"viewed": true
}
},
"plan": "free",
"rounding": {
"enabled": false,
"interval": 900000,
"mode": "NEAREST"
},
"timeZone": "Europe/Warsaw"
}Delete the current organization
Deletes the current organization. This action is restricted to administrators and may return a redirect URL for follow-up account cleanup.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/organization' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"domain": "acme",
"redirectUrl": "https://sandtime.io/offboarding-thank-you"
}Organization rename
Rename the current organization subdomain to a new available workspace hostname.
Rename the organization subdomain
Starts an organization rename from the current subdomain to the new desired subdomain.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/organization/rename' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"domain": "acme-europe"
}'Request body example
{
"domain": "acme-europe"
}Response example
{
"domain": "acme-europe"
}Activities
Time entry CRUD for manual logging, timers, and admin corrections.
Activity collection
List all activities visible to the current workspace context or create a new time entry.
List activities
Returns an ID-keyed map of activity records visible to the current user.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/activities' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302": {
"billable": true,
"endedAt": "2026-07-03T08:30:00.000Z",
"id": "c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302",
"name": "Implement API docs page",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"startedAt": "2026-07-03T07:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}
}Create an activity
Creates a new activity. Send `pending: true` with no `endedAt` when you want an open timer.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/activities' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"billable": true,
"endedAt": "2026-07-03T10:30:00+02:00",
"name": "Implement API docs page",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"startedAt": "2026-07-03T09:00:00+02:00"
}'Request body example
{
"billable": true,
"endedAt": "2026-07-03T10:30:00+02:00",
"name": "Implement API docs page",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"startedAt": "2026-07-03T09:00:00+02:00"
}Response example
{
"billable": true,
"endedAt": "2026-07-03T08:30:00.000Z",
"id": "c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302",
"name": "Implement API docs page",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"startedAt": "2026-07-03T07:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}Single activity
Read, update, or delete a single activity by ID.
Path parameters
activityId: The activity identifier.
Get an activity
Returns one activity record when the ID exists and the current user can see it.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/activities/c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"billable": true,
"endedAt": "2026-07-03T08:30:00.000Z",
"id": "c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302",
"name": "Implement API docs page",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"startedAt": "2026-07-03T07:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}Update an activity
Updates one activity. Typical changes include timestamps, billable status, title, and project assignment.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/activities/c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"billable": false,
"endedAt": "2026-07-03T11:00:00+02:00",
"name": "Polish the REST API guide"
}'Request body example
{
"billable": false,
"endedAt": "2026-07-03T11:00:00+02:00",
"name": "Polish the REST API guide"
}Response example
{
"billable": false,
"endedAt": "2026-07-03T09:00:00.000Z",
"id": "c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302",
"name": "Polish the REST API guide",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"startedAt": "2026-07-03T07:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}Delete an activity
Deletes one activity by ID.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/activities/c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}Projects
Projects, memberships, and project-specific revenue rates.
Project collection
List all projects visible to the user or create a new project.
List projects
Returns an ID-keyed map of projects.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/projects' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001": {
"archived": false,
"avatar": null,
"billable": true,
"id": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"name": "Website refresh",
"notes": "Main client delivery project."
}
}Create a project
Creates a project and automatically adds the creating administrator as a project member.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/projects' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"billable": true,
"name": "Website refresh",
"notes": "Main client delivery project."
}'Request body example
{
"billable": true,
"name": "Website refresh",
"notes": "Main client delivery project."
}Response example
{
"archived": false,
"avatar": null,
"billable": true,
"id": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"name": "Website refresh",
"notes": "Main client delivery project."
}Single project
Read, update, or delete a single project.
Path parameters
projectId: The project identifier.
Get a project
Returns one project by ID.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"archived": false,
"avatar": null,
"billable": true,
"id": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"name": "Website refresh",
"notes": "Main client delivery project."
}Update a project
Updates project metadata such as notes, billable status, archived state, or avatar.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"billable": false,
"notes": "Internal redesign and QA support."
}'Request body example
{
"billable": false,
"notes": "Internal redesign and QA support."
}Response example
{
"archived": false,
"avatar": null,
"billable": false,
"id": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"name": "Website refresh",
"notes": "Internal redesign and QA support."
}Delete a project
Deletes a project permanently.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}Project members
List or create project members inside one project.
Path parameters
projectId: The project identifier.
List project members
Returns an ID-keyed map of members assigned to the project.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04": {
"archived": false,
"assignedBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04",
"notes": "Frontend owner",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"role": "Administrator",
"tags": [
"design-system",
"client-facing"
],
"title": "Frontend Lead",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}
}Create a project member
Assigns a user to the project and optionally stores role, title, notes, and tags.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"notes": "Frontend owner",
"role": "Administrator",
"tags": [
"design-system",
"client-facing"
],
"title": "Frontend Lead",
"userId": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af"
}'Request body example
{
"notes": "Frontend owner",
"role": "Administrator",
"tags": [
"design-system",
"client-facing"
],
"title": "Frontend Lead",
"userId": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af"
}Response example
{
"archived": false,
"assignedBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04",
"notes": "Frontend owner",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"role": "User",
"tags": [
"design-system",
"client-facing"
],
"title": "Product Designer",
"userId": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af"
}Single project member
Read, update, or remove a single project member record.
Path parameters
projectId: The project identifier.memberId: The project member identifier.
Get a project member
Returns one project membership by member ID.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"archived": false,
"assignedBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04",
"notes": "Frontend owner",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"role": "Administrator",
"tags": [
"design-system",
"client-facing"
],
"title": "Frontend Lead",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}Update a project member
Updates role, title, tags, notes, or archived state for one project member.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"notes": "Delivery owner",
"role": "User",
"tags": [
"handover",
"qa"
],
"title": "Delivery Manager"
}'Request body example
{
"notes": "Delivery owner",
"role": "User",
"tags": [
"handover",
"qa"
],
"title": "Delivery Manager"
}Response example
{
"archived": false,
"assignedBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04",
"notes": "Delivery owner",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"role": "User",
"tags": [
"handover",
"qa"
],
"title": "Delivery Manager",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}Delete a project member
Removes the member from the project.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}Member revenue rates
List or create revenue rates for one project member.
Path parameters
projectId: The project identifier.memberId: The project member identifier.
List member revenue rates
Returns an ID-keyed map of revenue rates for the selected project member.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04/rates/revenue' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"e6dd7425-f0ef-403c-8f21-5fe1931cc9a9": {
"currency": "USD",
"from": "2026-07-01T00:00:00.000Z",
"id": "e6dd7425-f0ef-403c-8f21-5fe1931cc9a9",
"memberId": "3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"taxRate": 23,
"to": "2026-12-31T23:59:59.000Z",
"value": 145
}
}Create a member revenue rate
Creates a dated revenue rate window for a project member.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04/rates/revenue' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 23,
"to": "2026-12-31T23:59:59+01:00",
"value": 145
}'Request body example
{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 23,
"to": "2026-12-31T23:59:59+01:00",
"value": 145
}Response example
{
"currency": "USD",
"from": "2026-07-01T00:00:00.000Z",
"id": "e6dd7425-f0ef-403c-8f21-5fe1931cc9a9",
"memberId": "3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"taxRate": 23,
"to": "2026-12-31T23:59:59.000Z",
"value": 145
}Single member revenue rate
Read, update, or delete one revenue rate window.
Path parameters
projectId: The project identifier.memberId: The project member identifier.revenueId: The revenue rate identifier.
Get a member revenue rate
Returns one revenue rate record.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04/rates/revenue/e6dd7425-f0ef-403c-8f21-5fe1931cc9a9' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"currency": "USD",
"from": "2026-07-01T00:00:00.000Z",
"id": "e6dd7425-f0ef-403c-8f21-5fe1931cc9a9",
"memberId": "3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"taxRate": 23,
"to": "2026-12-31T23:59:59.000Z",
"value": 145
}Update a member revenue rate
Updates one revenue rate window.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04/rates/revenue/e6dd7425-f0ef-403c-8f21-5fe1931cc9a9' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 23,
"to": "2026-12-31T23:59:59+01:00",
"value": 155
}'Request body example
{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 23,
"to": "2026-12-31T23:59:59+01:00",
"value": 155
}Response example
{
"currency": "USD",
"from": "2026-07-01T00:00:00.000Z",
"id": "e6dd7425-f0ef-403c-8f21-5fe1931cc9a9",
"memberId": "3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"taxRate": 23,
"to": "2026-12-31T23:59:59.000Z",
"value": 155
}Delete a member revenue rate
Deletes one revenue rate record.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04/rates/revenue/e6dd7425-f0ef-403c-8f21-5fe1931cc9a9' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}Users
Users, personal preferences, and organization-level cost rates.
User collection
List all users in the current organization or invite a new member.
List users
Returns an ID-keyed map of organization users.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/users' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d": {
"archived": false,
"avatar": null,
"email": "alex.rivera@example.com",
"id": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"name": "Alex Rivera",
"phone": "+1 415 555 0102",
"role": "Administrator",
"title": "Operations Lead"
}
}Create or invite a user
Invites a user to the current organization. Existing users are re-invited instead of duplicated.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/users' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"email": "sam.lee@example.com",
"name": "Sam Lee",
"role": "User",
"title": "Product Designer"
}'Request body example
{
"email": "sam.lee@example.com",
"name": "Sam Lee",
"role": "User",
"title": "Product Designer"
}Response example
{
"archived": false,
"avatar": null,
"email": "sam.lee@example.com",
"id": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"name": "Sam Lee",
"phone": "+1 415 555 0102",
"role": "User",
"title": "Product Designer"
}Single user
Read, update, or remove a single user.
Path parameters
userId: The user identifier.
Get a user
Returns one user record.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"archived": false,
"avatar": null,
"email": "alex.rivera@example.com",
"id": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"name": "Alex Rivera",
"phone": "+1 415 555 0102",
"role": "Administrator",
"title": "Operations Lead"
}Update a user
Updates one user. Administrators can change role and archived state. Users can update their own profile fields.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"archived": false,
"phone": "+1 415 555 0188",
"role": "Administrator",
"title": "Head of Operations"
}'Request body example
{
"archived": false,
"phone": "+1 415 555 0188",
"role": "Administrator",
"title": "Head of Operations"
}Response example
{
"archived": false,
"avatar": null,
"email": "alex.rivera@example.com",
"id": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"name": "Alex Rivera",
"phone": "+1 415 555 0188",
"role": "Administrator",
"title": "Head of Operations"
}Delete a user
Permanently removes a user and their associated workspace data after server-side validations pass.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}User preferences
Read or update personal preferences for one user.
Path parameters
userId: The user identifier.
Get user preferences
Returns the preference document for the user. Users can only read their own preferences.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d/preferences' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"dateTimeFormat": {
"clock24Hour": true,
"numeric": true,
"showSeconds": false
},
"desktop": {
"startTrackingOnStartup": false,
"stopTrackingOnShutdown": true
},
"durationFormat": {
"compact": false,
"mode": "HOURS_MINUTES",
"showSeconds": false
},
"locale": "en-US",
"notifications": {
"activityCreated": {
"dashboard": true,
"email": false,
"popup": true
},
"monthlyGoalReached": {
"dashboard": true,
"email": true,
"popup": true
}
},
"timeZone": "Europe/Warsaw"
}Update user preferences
Updates the user preference document with locale, formatting, desktop, notification, or time-zone changes.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d/preferences' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"locale": "pl-PL",
"notifications": {
"monthlyGoalReached": {
"dashboard": true,
"email": true,
"popup": false
}
},
"timeZone": "Europe/Warsaw"
}'Request body example
{
"locale": "pl-PL",
"notifications": {
"monthlyGoalReached": {
"dashboard": true,
"email": true,
"popup": false
}
},
"timeZone": "Europe/Warsaw"
}Response example
{
"dateTimeFormat": {
"clock24Hour": true,
"numeric": true,
"showSeconds": false
},
"desktop": {
"startTrackingOnStartup": false,
"stopTrackingOnShutdown": true
},
"durationFormat": {
"compact": false,
"mode": "HOURS_MINUTES",
"showSeconds": false
},
"locale": "pl-PL",
"notifications": {
"activityCreated": {
"dashboard": true,
"email": false,
"popup": true
},
"monthlyGoalReached": {
"dashboard": true,
"email": true,
"popup": true
}
},
"timeZone": "Europe/Warsaw"
}User cost rates
List or create cost-rate windows for one user.
Path parameters
userId: The user identifier.
List user cost rates
Returns an ID-keyed map of cost rates for the user.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d/rates/cost' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"7bc0f6d1-d6a8-4718-8e64-b3ddcfe35334": {
"currency": "USD",
"from": "2026-07-01T00:00:00.000Z",
"id": "7bc0f6d1-d6a8-4718-8e64-b3ddcfe35334",
"taxRate": 0,
"to": "2026-12-31T23:59:59.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"value": 65
}
}Create a user cost rate
Creates a dated cost-rate window for the user.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d/rates/cost' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 0,
"to": "2026-12-31T23:59:59+01:00",
"value": 65
}'Request body example
{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 0,
"to": "2026-12-31T23:59:59+01:00",
"value": 65
}Response example
{
"currency": "USD",
"from": "2026-07-01T00:00:00.000Z",
"id": "7bc0f6d1-d6a8-4718-8e64-b3ddcfe35334",
"taxRate": 0,
"to": "2026-12-31T23:59:59.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"value": 65
}Single user cost rate
Read, update, or delete one cost-rate window.
Path parameters
userId: The user identifier.costId: The cost rate identifier.
Get a user cost rate
Returns one user cost-rate record.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d/rates/cost/7bc0f6d1-d6a8-4718-8e64-b3ddcfe35334' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"currency": "USD",
"from": "2026-07-01T00:00:00.000Z",
"id": "7bc0f6d1-d6a8-4718-8e64-b3ddcfe35334",
"taxRate": 0,
"to": "2026-12-31T23:59:59.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"value": 65
}Update a user cost rate
Updates one user cost-rate window.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d/rates/cost/7bc0f6d1-d6a8-4718-8e64-b3ddcfe35334' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 0,
"to": "2026-12-31T23:59:59+01:00",
"value": 72
}'Request body example
{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 0,
"to": "2026-12-31T23:59:59+01:00",
"value": 72
}Response example
{
"currency": "USD",
"from": "2026-07-01T00:00:00.000Z",
"id": "7bc0f6d1-d6a8-4718-8e64-b3ddcfe35334",
"taxRate": 0,
"to": "2026-12-31T23:59:59.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"value": 72
}Delete a user cost rate
Deletes one user cost-rate record.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/users/2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d/rates/cost/7bc0f6d1-d6a8-4718-8e64-b3ddcfe35334' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}Reports
Saved report definitions for dashboards, billing, and exports.
Report collection
List saved reports or create a new report definition.
List reports
Returns an ID-keyed map of saved reports.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/reports' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"6b0dfe58-9c80-4d8d-8a9f-9e48983f4e01": {
"dimensions": [
"project"
],
"end": "2026-07-31T21:59:59.000Z",
"filters": [],
"hideEmptyRows": true,
"id": "6b0dfe58-9c80-4d8d-8a9f-9e48983f4e01",
"metrics": [
"time",
"billable"
],
"name": "July project summary",
"period": "custom",
"pinned": true,
"selectedProjectMembers": null,
"selectedProjects": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"showArchivedMembers": false,
"showArchivedProjects": false,
"start": "2026-06-30T22:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}
}Create a report
Creates a saved report configuration for the current user.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/reports' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"dimensions": [
"project"
],
"end": "2026-07-31T23:59:59+02:00",
"filters": [],
"hideEmptyRows": true,
"metrics": [
"time",
"billable"
],
"name": "July project summary",
"period": "custom",
"selectedProjectMembers": null,
"selectedProjects": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"showArchivedMembers": false,
"showArchivedProjects": false,
"start": "2026-07-01T00:00:00+02:00"
}'Request body example
{
"dimensions": [
"project"
],
"end": "2026-07-31T23:59:59+02:00",
"filters": [],
"hideEmptyRows": true,
"metrics": [
"time",
"billable"
],
"name": "July project summary",
"period": "custom",
"selectedProjectMembers": null,
"selectedProjects": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"showArchivedMembers": false,
"showArchivedProjects": false,
"start": "2026-07-01T00:00:00+02:00"
}Response example
{
"dimensions": [
"project"
],
"end": "2026-07-31T21:59:59.000Z",
"filters": [],
"hideEmptyRows": true,
"id": "6b0dfe58-9c80-4d8d-8a9f-9e48983f4e01",
"metrics": [
"time",
"billable"
],
"name": "July project summary",
"period": "custom",
"pinned": true,
"selectedProjectMembers": null,
"selectedProjects": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"showArchivedMembers": false,
"showArchivedProjects": false,
"start": "2026-06-30T22:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}Single report
Read, update, or delete a single report definition.
Path parameters
reportId: The report identifier.
Get a report
Returns one report configuration.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/reports/6b0dfe58-9c80-4d8d-8a9f-9e48983f4e01' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"dimensions": [
"project"
],
"end": "2026-07-31T21:59:59.000Z",
"filters": [],
"hideEmptyRows": true,
"id": "6b0dfe58-9c80-4d8d-8a9f-9e48983f4e01",
"metrics": [
"time",
"billable"
],
"name": "July project summary",
"period": "custom",
"pinned": true,
"selectedProjectMembers": null,
"selectedProjects": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"showArchivedMembers": false,
"showArchivedProjects": false,
"start": "2026-06-30T22:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}Update a report
Updates one saved report.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/reports/6b0dfe58-9c80-4d8d-8a9f-9e48983f4e01' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"dimensions": [
"project"
],
"end": "2026-07-31T23:59:59+02:00",
"filters": [],
"hideEmptyRows": true,
"metrics": [
"time",
"billable"
],
"name": "July project summary",
"period": "custom",
"selectedProjectMembers": null,
"selectedProjects": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"showArchivedMembers": false,
"showArchivedProjects": false,
"start": "2026-07-01T00:00:00+02:00",
"pinned": true
}'Request body example
{
"dimensions": [
"project"
],
"end": "2026-07-31T23:59:59+02:00",
"filters": [],
"hideEmptyRows": true,
"metrics": [
"time",
"billable"
],
"name": "July project summary",
"period": "custom",
"selectedProjectMembers": null,
"selectedProjects": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"showArchivedMembers": false,
"showArchivedProjects": false,
"start": "2026-07-01T00:00:00+02:00",
"pinned": true
}Response example
{
"dimensions": [
"project"
],
"end": "2026-07-31T21:59:59.000Z",
"filters": [],
"hideEmptyRows": true,
"id": "6b0dfe58-9c80-4d8d-8a9f-9e48983f4e01",
"metrics": [
"time",
"billable"
],
"name": "July project summary",
"period": "custom",
"pinned": true,
"selectedProjectMembers": null,
"selectedProjects": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"showArchivedMembers": false,
"showArchivedProjects": false,
"start": "2026-06-30T22:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}Delete a report
Deletes a saved report.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/reports/6b0dfe58-9c80-4d8d-8a9f-9e48983f4e01' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}Geofences
Geofence definitions plus mobile enter and exit triggers.
Geofence collection
List geofences or create a new geofence rule.
List geofences
Returns an ID-keyed map of geofences.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/geofences' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"cf6b0bd6-dbbf-4ef5-98a7-7ae04e0eb18c": {
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"id": "cf6b0bd6-dbbf-4ef5-98a7-7ae04e0eb18c",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 120
}
}Create a geofence
Creates a geofence with enter and exit actions.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/geofences' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 120
}'Request body example
{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 120
}Response example
{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"id": "cf6b0bd6-dbbf-4ef5-98a7-7ae04e0eb18c",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 120
}Single geofence
Read, update, or delete one geofence.
Path parameters
geofenceId: The geofence identifier.
Get a geofence
Returns one geofence by ID.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/geofences/cf6b0bd6-dbbf-4ef5-98a7-7ae04e0eb18c' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"id": "cf6b0bd6-dbbf-4ef5-98a7-7ae04e0eb18c",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 120
}Update a geofence
Updates one geofence.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/geofences/cf6b0bd6-dbbf-4ef5-98a7-7ae04e0eb18c' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 150
}'Request body example
{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 150
}Response example
{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"id": "cf6b0bd6-dbbf-4ef5-98a7-7ae04e0eb18c",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 150
}Delete a geofence
Deletes one geofence.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/geofences/cf6b0bd6-dbbf-4ef5-98a7-7ae04e0eb18c' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}Geofence enter trigger
Signal that a device entered a geofence and let Sandtime.io run its configured enter action.
Send a geofence-enter event
Processes a geofence enter event. This is mainly used by mobile clients and location automations.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/geofencing/enter' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"latitude": 52.2297,
"longitude": 21.0122,
"source": "ios-geofence"
}'Request body example
{
"latitude": 52.2297,
"longitude": 21.0122,
"source": "ios-geofence"
}Response example
{
"endedAt": null,
"name": "geofencing test",
"projectId": null,
"startedAt": "2026-07-03T10:00:00.000Z"
}Geofence exit trigger
Signal that a device left a geofence and let Sandtime.io stop pending work where configured.
Send a geofence-exit event
Processes a geofence exit event and returns the pending activities that were stopped.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/geofencing/exit' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"latitude": 52.2297,
"longitude": 21.0122,
"source": "ios-geofence"
}'Request body example
{
"latitude": 52.2297,
"longitude": 21.0122,
"source": "ios-geofence"
}Response example
[
{
"billable": true,
"endedAt": "2026-07-03T08:30:00.000Z",
"id": "c2dbd56f-0f09-4bf8-87ae-a1c8d7e5f302",
"name": "Implement API docs page",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"startedAt": "2026-07-03T07:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d"
}
]Requests
Approval and assignment workflows live under /requests.
Create role-change request
Create a project role-change request for a member.
Path parameters
projectId: The project identifier.memberId: The project member identifier.
Create a role-change request
Creates a request to change the selected project member role.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/requests/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members/3b13dd8f-bc60-4db8-a2bc-5eb16ca31a04/role' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"role": "Administrator"
}'Request body example
{
"role": "Administrator"
}Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"role": "Administrator"
}Resolve role-change request
Resolve a role-change request by marking it RESOLVED or REJECTED.
Path parameters
requestId: The workflow request identifier.
Resolve a role-change request
Applies or rejects the role change for an existing request.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/requests/1fbbd48d-176f-4b32-a98d-c8cf1eb291c5/projects/members/role' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"status": "RESOLVED"
}'Request body example
{
"status": "RESOLVED"
}Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Create project-member assignment request
Create a project-member assignment request.
Path parameters
projectId: The project identifier.
Create a project-member assignment request
Creates a request to assign one or more users to a project.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/requests/projects/9d58c4ce-3e6f-4d06-bf47-f70d8c4af001/members' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"userIds": [
"8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af"
]
}'Request body example
{
"userIds": [
"8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af"
]
}Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Resolve project-member assignment request
Resolve a project-member assignment request.
Path parameters
requestId: The workflow request identifier.
Resolve a project-member assignment request
Marks the request RESOLVED or REJECTED. Resolved requests assign the selected users to the project.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/requests/1fbbd48d-176f-4b32-a98d-c8cf1eb291c5/projects/members' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"status": "RESOLVED"
}'Request body example
{
"status": "RESOLVED"
}Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Create project-assignment request
Create a request for assignment to one or more projects.
Create a project-assignment request
Creates a self-service request asking administrators to assign the current user to projects.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/requests/projects/request-assignment' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Resolve project-assignment request
Resolve a request for assignment to projects.
Path parameters
requestId: The workflow request identifier.
Resolve a project-assignment request
Marks the request RESOLVED or REJECTED. Resolved requests use `projectIds` to assign the requester to projects.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/requests/1fbbd48d-176f-4b32-a98d-c8cf1eb291c5/projects/assign' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"projectIds": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"status": "RESOLVED"
}'Request body example
{
"projectIds": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"status": "RESOLVED"
}Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Resolve impersonation request
Resolve an impersonation request raised elsewhere in the product.
Path parameters
requestId: The workflow request identifier.
Resolve an impersonation request
Marks the impersonation request RESOLVED or REJECTED. A resolved request triggers a one-time support sign-in link.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/requests/1fbbd48d-176f-4b32-a98d-c8cf1eb291c5' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"status": "RESOLVED"
}'Request body example
{
"status": "RESOLVED"
}Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Create timesheet-unlock request
Create an unlock request for a locked weekly timesheet.
Path parameters
year: ISO week-numbering year.week: ISO week number in the organization time zone.
Create a timesheet-unlock request
Creates a request asking administrators to unlock one weekly timesheet.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/requests/timesheets/2026/27/unlock' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Resolve timesheet-unlock request
Resolve a timesheet-unlock request.
Path parameters
requestId: The workflow request identifier.
Resolve a timesheet-unlock request
Marks the unlock request RESOLVED or REJECTED. A resolved request opens the timesheet for a temporary editing window.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/requests/1fbbd48d-176f-4b32-a98d-c8cf1eb291c5/timesheets/unlock' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"status": "RESOLVED"
}'Request body example
{
"status": "RESOLVED"
}Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Create timesheet-approval request
Create an approval request for a weekly timesheet.
Path parameters
year: ISO week-numbering year.week: ISO week number in the organization time zone.
Create a timesheet-approval request
Creates a request asking administrators to approve a weekly timesheet.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/requests/timesheets/2026/27/approvals' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Resolve timesheet-approval request
Resolve a timesheet-approval request.
Path parameters
requestId: The workflow request identifier.
Resolve a timesheet-approval request
Marks the approval request RESOLVED or REJECTED.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/requests/1fbbd48d-176f-4b32-a98d-c8cf1eb291c5/timesheets/approvals' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"status": "RESOLVED"
}'Request body example
{
"status": "RESOLVED"
}Response example
{
"createdAt": "2026-07-03T09:02:11.000Z",
"createdBy": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"id": "1fbbd48d-176f-4b32-a98d-c8cf1eb291c5",
"resolvedAt": "2026-07-03T09:08:45.000Z",
"resolvedBy": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af",
"status": "RESOLVED"
}Timesheets
Explicit timesheet locks, automatic lock execution, and reminder delivery.
Auto-lock runner
Run the organization auto-lock routine against the current time zone and lock settings.
Run auto-lock
Evaluates whether the next weekly lock should run and updates organization lock metadata when it does.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/timesheets/auto-lock' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"reason": "scheduled-reminder-run"
}'Request body example
{
"reason": "scheduled-reminder-run"
}Response example
{
"coreHours": {
"end": "17:00",
"start": "09:00"
},
"currency": "USD",
"holidays": {
"country": "US",
"excluded": []
},
"id": "8a4affba-df59-47bd-8173-d175e76efd15",
"lockingTimesheets": {
"enabled": false,
"timeZone": null,
"week": null,
"year": null
},
"name": "Acme Studio",
"notes": "Weekly client delivery team.",
"onboarding": {
"assignMembers": {
"done": true,
"viewed": true
},
"inviteMembers": {
"done": true,
"viewed": true
},
"organization": {
"done": true,
"viewed": true
},
"preferences": {
"done": false,
"viewed": true
},
"projects": {
"done": true,
"viewed": true
}
},
"plan": "free",
"rounding": {
"enabled": false,
"interval": 900000,
"mode": "NEAREST"
},
"timeZone": "Europe/Warsaw"
}Timesheet lock collection
Create a lock or temporary unlock window for one user and one ISO week.
Create a timesheet lock
Creates or replaces one timesheet lock for the selected user/week combination.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/timesheets/lock' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"unlockedTo": "2026-07-04T20:00:00+02:00",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"week": 27,
"year": 2026
}'Request body example
{
"unlockedTo": "2026-07-04T20:00:00+02:00",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"week": 27,
"year": 2026
}Response example
{
"createdAt": "2026-07-03T10:00:00.000Z",
"id": "5c27ad51-cbb7-4f96-84c7-f19dd3750a42",
"unlockedTo": "2026-07-04T18:00:00.000Z",
"updatedAt": "2026-07-03T10:00:00.000Z",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"week": 27,
"year": 2026
}Single timesheet lock
Delete one explicit timesheet lock or unlock window.
Path parameters
lockId: The timesheet lock identifier.
Delete a timesheet lock
Deletes one timesheet lock by ID.
cURL example
curl -X DELETE 'https://your-organization.sandtime.io/api/timesheets/lock/5c27ad51-cbb7-4f96-84c7-f19dd3750a42' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
{}Timesheet reminder runner
Trigger the reminder flow that asks users to fill timesheets before the automatic lock runs.
Send timesheet reminders
Runs the reminder logic for the current organization.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/timesheets/reminder' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"reason": "friday-evening-check"
}'Request body example
{
"reason": "friday-evening-check"
}Response example
nullBilling
Billing, plan changes, and checkout helpers.
Subscription collection
Read the current subscription collection for the organization.
List subscriptions
Returns subscription records for the current organization.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/subscriptions' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
[
{
"id": "sub_01J1YB3TQK5K9S2H4E5T6U7V8W",
"nextBillDate": "2026-08-01",
"plan": "monthly",
"quantity": 1,
"status": "active"
}
]Single subscription
Update one subscription, usually to change quantity or payment state.
Path parameters
subscriptionId: The external subscription identifier.
Update a subscription
Updates one existing subscription. This route is limited to administrators.
cURL example
curl -X PUT 'https://your-organization.sandtime.io/api/subscriptions/sub_01J1YB3TQK5K9S2H4E5T6U7V8W' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"quantity": 2
}'Request body example
{
"quantity": 2
}Response example
{}Checkout
Create a checkout link for a plan change.
Create a checkout link
Creates a Paddle checkout link for the selected product and quantity.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/checkout' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"product": 123456,
"quantity": 1
}'Request body example
{
"product": 123456,
"quantity": 1
}Response example
{
"url": "https://pay.paddle.com/pay/cpl_example"
}Billing history
Read the billing transaction history for the current organization.
List billing history
Returns the current billing history from the payment provider.
cURL example
curl -X GET 'https://your-organization.sandtime.io/api/billing-history' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Response example
[
{
"amount": 4900,
"currency": "USD",
"id": "txn_01J1YB6A0M2K8H5V7P9R4S3T2Q",
"paidAt": "2026-07-01T08:10:00.000Z",
"status": "paid"
}
]Receipt upload
Upload an App Store receipt for validation.
Upload a receipt
Submits a base64-encoded receipt payload to the billing backend.
cURL example
curl -X POST 'https://your-organization.sandtime.io/api/receipt' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"receiptBase64": "MIIT9QYJKoZIhvcNAQcCoIIT5jCCE+ICAQExCzAJBgUr..."
}'Request body example
{
"receiptBase64": "MIIT9QYJKoZIhvcNAQcCoIIT5jCCE+ICAQExCzAJBgUr..."
}Response example
{
"ok": true
}