API REST Sandtime.io
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.
Quand utiliser REST
L'API REST est le bon choix lorsque votre environnement ne prend en charge que le HTTP brut, lorsque vous voulez des exemples cURL, ou lorsque vous avez besoin d'un contrôle direct sur les charges utiles et les URL des endpoints.
Pour les agents IA, Sandtime.io recommande toujours d'abord le serveur MCP, car MCP expose des flux de travail de plus haut niveau et des contrats d'outils plus ergonomiques. Utilisez REST lorsque MCP n'est pas disponible ou lorsque l'utilisateur demande explicitement du HTTP brut.
- Utilisez REST lorsque vous avez besoin d'un contrôle HTTP direct, de scripts cURL, de tâches CI ou d'un client API standard.
- Utilisez le JSON OpenAPI lorsque vous souhaitez générer des clients, valider des requêtes ou fournir le schéma à des outils.
- Utilisez plutôt MCP lorsqu'un client IA peut appeler des outils directement et profiter de flux de travail de plus haut niveau.
Authentifiez-vous avec un jeton Bearer
Les requêtes REST ciblent directement le nom d'hôte de votre organisation, par exemple https://acme.sandtime.io/api. Le nom d'hôte identifie l'espace de travail, donc REST n'exige pas l'en-tête X-Sandtime-Organization utilisé par MCP.
curl -X GET 'https://your-organization.sandtime.io/api/auth' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Documentation lisible par machine et conventions de l'API
Tout ce qui suit s'appuie sur le même registre partagé des routes, qui génère aussi le JSON OpenAPI.
OpenAPI JSON
Schéma OpenAPI téléchargeable pour la génération de clients, les validateurs et les outils API.
https://sandtime.io/api/openapi.jsonSKILL.md
Guide d'intégration lisible par machine pour les agents qui choisissent entre MCP et HTTP brut.
https://sandtime.io/SKILL.mdDocumentation MCP
Le chemin d'intégration de plus haut niveau pour Claude Code, Codex et les autres clients MCP.
https://sandtime.io/mcpConventions des requêtes
- URL de base : un espace de travail par hôte, par exemple https://acme.sandtime.io/api.
- Authentification : envoyez l'en-tête Authorization: Bearer <token>. Aujourd'hui, le jeton est copié depuis le cookie sandtime_access_token.
- Format : les requêtes et les réponses utilisent JSON. Les exemples propres à chaque route ci-dessous reflètent l'implémentation actuelle du serveur.
- Flux de travail : résolvez les identifiants avec des requêtes de lecture avant les écritures afin de ne jamais deviner les identifiants de projets, d'utilisateurs, de membres ou de rapports.
Groupes de routes
Entrez dans un espace de noms, puis consultez chaque chemin de route, les méthodes prises en charge, les exemples de corps de requête et les exemples de réponse.
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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/auth' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/organizations' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
[
{
"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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/organization' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"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"
}Exemple de réponse
{
"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.
exemple cURL
curl -X DELETE 'https://your-organization.sandtime.io/api/organization' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"domain": "acme-europe"
}Exemple de réponse
{
"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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/activities' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"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"
}Exemple de réponse
{
"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.
Paramètres de chemin
activityId: The activity identifier.
Get an activity
Returns one activity record when the ID exists and the current user can see it.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"billable": false,
"endedAt": "2026-07-03T11:00:00+02:00",
"name": "Polish the REST API guide"
}Exemple de réponse
{
"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.
exemple cURL
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"Exemple de réponse
{}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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/projects' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
exemple cURL
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."
}'Exemple de corps de requête
{
"billable": true,
"name": "Website refresh",
"notes": "Main client delivery project."
}Exemple de réponse
{
"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.
Paramètres de chemin
projectId: The project identifier.
Get a project
Returns one project by ID.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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."
}'Exemple de corps de requête
{
"billable": false,
"notes": "Internal redesign and QA support."
}Exemple de réponse
{
"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.
exemple cURL
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"Exemple de réponse
{}Project members
List or create project members inside one project.
Paramètres de chemin
projectId: The project identifier.
List project members
Returns an ID-keyed map of members assigned to the project.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"notes": "Frontend owner",
"role": "Administrator",
"tags": [
"design-system",
"client-facing"
],
"title": "Frontend Lead",
"userId": "8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af"
}Exemple de réponse
{
"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.
Paramètres de chemin
projectId: The project identifier.memberId: The project member identifier.
Get a project member
Returns one project membership by member ID.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"notes": "Delivery owner",
"role": "User",
"tags": [
"handover",
"qa"
],
"title": "Delivery Manager"
}Exemple de réponse
{
"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.
exemple cURL
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"Exemple de réponse
{}Member revenue rates
List or create revenue rates for one project member.
Paramètres de chemin
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.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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
}'Exemple de corps de requête
{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 23,
"to": "2026-12-31T23:59:59+01:00",
"value": 145
}Exemple de réponse
{
"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.
Paramètres de chemin
projectId: The project identifier.memberId: The project member identifier.revenueId: The revenue rate identifier.
Get a member revenue rate
Returns one revenue rate record.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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
}'Exemple de corps de requête
{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 23,
"to": "2026-12-31T23:59:59+01:00",
"value": 155
}Exemple de réponse
{
"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.
exemple cURL
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"Exemple de réponse
{}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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/users' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"email": "sam.lee@example.com",
"name": "Sam Lee",
"role": "User",
"title": "Product Designer"
}Exemple de réponse
{
"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.
Paramètres de chemin
userId: The user identifier.
Get a user
Returns one user record.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"archived": false,
"phone": "+1 415 555 0188",
"role": "Administrator",
"title": "Head of Operations"
}Exemple de réponse
{
"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.
exemple cURL
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"Exemple de réponse
{}User preferences
Read or update personal preferences for one user.
Paramètres de chemin
userId: The user identifier.
Get user preferences
Returns the preference document for the user. Users can only read their own preferences.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"locale": "pl-PL",
"notifications": {
"monthlyGoalReached": {
"dashboard": true,
"email": true,
"popup": false
}
},
"timeZone": "Europe/Warsaw"
}Exemple de réponse
{
"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.
Paramètres de chemin
userId: The user identifier.
List user cost rates
Returns an ID-keyed map of cost rates for the user.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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
}'Exemple de corps de requête
{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 0,
"to": "2026-12-31T23:59:59+01:00",
"value": 65
}Exemple de réponse
{
"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.
Paramètres de chemin
userId: The user identifier.costId: The cost rate identifier.
Get a user cost rate
Returns one user cost-rate record.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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
}'Exemple de corps de requête
{
"currency": "USD",
"from": "2026-07-01T00:00:00+02:00",
"taxRate": 0,
"to": "2026-12-31T23:59:59+01:00",
"value": 72
}Exemple de réponse
{
"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.
exemple cURL
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"Exemple de réponse
{}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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/reports' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"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"
}Exemple de réponse
{
"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.
Paramètres de chemin
reportId: The report identifier.
Get a report
Returns one report configuration.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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
}'Exemple de corps de requête
{
"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
}Exemple de réponse
{
"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.
exemple cURL
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"Exemple de réponse
{}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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/geofences' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
exemple cURL
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
}'Exemple de corps de requête
{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 120
}Exemple de réponse
{
"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.
Paramètres de chemin
geofenceId: The geofence identifier.
Get a geofence
Returns one geofence by ID.
exemple cURL
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"Exemple de réponse
{
"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.
exemple cURL
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
}'Exemple de corps de requête
{
"enterAction": "START_TRACKING_PROJECT",
"exitAction": "STOP_TRACKING",
"latitude": 52.2297,
"longitude": 21.0122,
"name": "Warsaw office",
"projectId": "9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"radius": 150
}Exemple de réponse
{
"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.
exemple cURL
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"Exemple de réponse
{}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.
exemple cURL
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"
}'Exemple de corps de requête
{
"latitude": 52.2297,
"longitude": 21.0122,
"source": "ios-geofence"
}Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"latitude": 52.2297,
"longitude": 21.0122,
"source": "ios-geofence"
}Exemple de réponse
[
{
"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.
Paramètres de chemin
projectId: The project identifier.memberId: The project member identifier.
Create a role-change request
Creates a request to change the selected project member role.
exemple cURL
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"
}'Exemple de corps de requête
{
"role": "Administrator"
}Exemple de réponse
{
"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.
Paramètres de chemin
requestId: The workflow request identifier.
Resolve a role-change request
Applies or rejects the role change for an existing request.
exemple cURL
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"
}'Exemple de corps de requête
{
"status": "RESOLVED"
}Exemple de réponse
{
"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.
Paramètres de chemin
projectId: The project identifier.
Create a project-member assignment request
Creates a request to assign one or more users to a project.
exemple cURL
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"
]
}'Exemple de corps de requête
{
"userIds": [
"8eb3c82f-420d-4a7d-b4e5-689f6cf9c8af"
]
}Exemple de réponse
{
"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.
Paramètres de chemin
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.
exemple cURL
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"
}'Exemple de corps de requête
{
"status": "RESOLVED"
}Exemple de réponse
{
"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.
exemple cURL
curl -X POST 'https://your-organization.sandtime.io/api/requests/projects/request-assignment' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
{
"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.
Paramètres de chemin
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.
exemple cURL
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"
}'Exemple de corps de requête
{
"projectIds": [
"9d58c4ce-3e6f-4d06-bf47-f70d8c4af001",
"58f5aa89-aed2-4a67-8808-d85ef4034f42"
],
"status": "RESOLVED"
}Exemple de réponse
{
"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.
Paramètres de chemin
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.
exemple cURL
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"
}'Exemple de corps de requête
{
"status": "RESOLVED"
}Exemple de réponse
{
"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.
Paramètres de chemin
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.
exemple cURL
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"Exemple de réponse
{
"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.
Paramètres de chemin
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.
exemple cURL
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"
}'Exemple de corps de requête
{
"status": "RESOLVED"
}Exemple de réponse
{
"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.
Paramètres de chemin
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.
exemple cURL
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"Exemple de réponse
{
"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.
Paramètres de chemin
requestId: The workflow request identifier.
Resolve a timesheet-approval request
Marks the approval request RESOLVED or REJECTED.
exemple cURL
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"
}'Exemple de corps de requête
{
"status": "RESOLVED"
}Exemple de réponse
{
"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.
exemple cURL
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"
}'Exemple de corps de requête
{
"reason": "scheduled-reminder-run"
}Exemple de réponse
{
"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.
exemple cURL
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
}'Exemple de corps de requête
{
"unlockedTo": "2026-07-04T20:00:00+02:00",
"userId": "2f9fd8a8-9f6d-4b2b-a4f4-1f1f2a7d9b9d",
"week": 27,
"year": 2026
}Exemple de réponse
{
"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.
Paramètres de chemin
lockId: The timesheet lock identifier.
Delete a timesheet lock
Deletes one timesheet lock by ID.
exemple cURL
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"Exemple de réponse
{}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.
exemple cURL
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"
}'Exemple de corps de requête
{
"reason": "friday-evening-check"
}Exemple de réponse
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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/subscriptions' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
[
{
"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.
Paramètres de chemin
subscriptionId: The external subscription identifier.
Update a subscription
Updates one existing subscription. This route is limited to administrators.
exemple cURL
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
}'Exemple de corps de requête
{
"quantity": 2
}Exemple de réponse
{}Checkout
Create a checkout link for a plan change.
Create a checkout link
Creates a Paddle checkout link for the selected product and quantity.
exemple cURL
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
}'Exemple de corps de requête
{
"product": 123456,
"quantity": 1
}Exemple de réponse
{
"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.
exemple cURL
curl -X GET 'https://your-organization.sandtime.io/api/billing-history' \
-H "Authorization: Bearer YOUR_SANDTIME_ACCESS_TOKEN" \
-H "Accept: application/json"Exemple de réponse
[
{
"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.
exemple cURL
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..."
}'Exemple de corps de requête
{
"receiptBase64": "MIIT9QYJKoZIhvcNAQcCoIIT5jCCE+ICAQExCzAJBgUr..."
}Exemple de réponse
{
"ok": true
}