Aperçu pour développeurs

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"
L'authentification est encore en préversion développeur. Aujourd'hui, vous obtenez le jeton Bearer en le copiant depuis le cookie de session Sandtime.io. Cela correspond au flux d'authentification MCP actuel, et un flux de jeton dédié est encore en cours de développement.

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.json

SKILL.md

Guide d'intégration lisible par machine pour les agents qui choisissent entre MCP et HTTP brut.

https://sandtime.io/SKILL.md

Documentation MCP

Le chemin d'intégration de plus haut niveau pour Claude Code, Codex et les autres clients MCP.

https://sandtime.io/mcp

Conventions 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.

Reports

Saved report definitions for dashboards, billing, and exports.

Geofences

Geofence definitions plus mobile enter and exit triggers.

Timesheets

Explicit timesheet locks, automatic lock execution, and reminder delivery.

Workspace

Workspace discovery, organization settings, and authentication helpers.

/auth

Authentication snapshot

Read the current cookie-backed auth snapshot or list the organizations available to the signed-in user.

GET

Get the current auth snapshot

Returns the current user email, active organization domain, and the same Bearer token currently extracted from the session cookie.

Statut de réponse: 200ID d'opération: get-auth
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

Organizations

List the active organizations available to the signed-in user account.

GET

List active organizations

Returns the active workspaces available to the current user across Sandtime.io.

Statut de réponse: 200ID d'opération: get-organizations
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

Organization settings

Read, update, or permanently remove the current organization.

GET

Get organization settings

Returns the organization settings loaded for the current hostname.

Statut de réponse: 200ID d'opération: get-organization
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"
}
PUT

Update organization settings

Updates mutable organization settings such as currency, notes, core hours, holidays, rounding, and timesheet locking.

Statut de réponse: 200ID d'opération: put-organization
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

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.

Statut de réponse: 200ID d'opération: delete-organization
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

Organization rename

Rename the current organization subdomain to a new available workspace hostname.

POST

Rename the organization subdomain

Starts an organization rename from the current subdomain to the new desired subdomain.

Statut de réponse: 200ID d'opération: post-organization-rename
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.

/activities

Activity collection

List all activities visible to the current workspace context or create a new time entry.

GET

List activities

Returns an ID-keyed map of activity records visible to the current user.

Statut de réponse: 200ID d'opération: get-activities
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"
  }
}
POST

Create an activity

Creates a new activity. Send `pending: true` with no `endedAt` when you want an open timer.

Statut de réponse: 200ID d'opération: post-activities
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"
}
/activities/{activityId}

Single activity

Read, update, or delete a single activity by ID.

Paramètres de chemin

  • activityId: The activity identifier.
GET

Get an activity

Returns one activity record when the ID exists and the current user can see it.

Statut de réponse: 200ID d'opération: get-activities-activityId
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"
}
PUT

Update an activity

Updates one activity. Typical changes include timestamps, billable status, title, and project assignment.

Statut de réponse: 200ID d'opération: put-activities-activityId
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

Delete an activity

Deletes one activity by ID.

Statut de réponse: 200ID d'opération: delete-activities-activityId
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.

/projects

Project collection

List all projects visible to the user or create a new project.

GET

List projects

Returns an ID-keyed map of projects.

Statut de réponse: 200ID d'opération: get-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."
  }
}
POST

Create a project

Creates a project and automatically adds the creating administrator as a project member.

Statut de réponse: 200ID d'opération: post-projects
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."
}
/projects/{projectId}

Single project

Read, update, or delete a single project.

Paramètres de chemin

  • projectId: The project identifier.
GET

Get a project

Returns one project by ID.

Statut de réponse: 200ID d'opération: get-projects-projectId
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."
}
PUT

Update a project

Updates project metadata such as notes, billable status, archived state, or avatar.

Statut de réponse: 200ID d'opération: put-projects-projectId
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

Delete a project

Deletes a project permanently.

Statut de réponse: 200ID d'opération: delete-projects-projectId
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
{}
/projects/{projectId}/members

Project members

List or create project members inside one project.

Paramètres de chemin

  • projectId: The project identifier.
GET

List project members

Returns an ID-keyed map of members assigned to the project.

Statut de réponse: 200ID d'opération: get-projects-projectId-members
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"
  }
}
POST

Create a project member

Assigns a user to the project and optionally stores role, title, notes, and tags.

Statut de réponse: 200ID d'opération: post-projects-projectId-members
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"
}
/projects/{projectId}/members/{memberId}

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

Get a project member

Returns one project membership by member ID.

Statut de réponse: 200ID d'opération: get-projects-projectId-members-memberId
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"
}
PUT

Update a project member

Updates role, title, tags, notes, or archived state for one project member.

Statut de réponse: 200ID d'opération: put-projects-projectId-members-memberId
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

Delete a project member

Removes the member from the project.

Statut de réponse: 200ID d'opération: delete-projects-projectId-members-memberId
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
{}
/projects/{projectId}/members/{memberId}/rates/revenue

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.
GET

List member revenue rates

Returns an ID-keyed map of revenue rates for the selected project member.

Statut de réponse: 200ID d'opération: get-projects-projectId-members-memberId-rates-revenue
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
  }
}
POST

Create a member revenue rate

Creates a dated revenue rate window for a project member.

Statut de réponse: 200ID d'opération: post-projects-projectId-members-memberId-rates-revenue
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
}
/projects/{projectId}/members/{memberId}/rates/revenue/{revenueId}

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

Get a member revenue rate

Returns one revenue rate record.

Statut de réponse: 200ID d'opération: get-projects-projectId-members-memberId-rates-revenue-revenueId
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
}
PUT

Update a member revenue rate

Updates one revenue rate window.

Statut de réponse: 200ID d'opération: put-projects-projectId-members-memberId-rates-revenue-revenueId
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

Delete a member revenue rate

Deletes one revenue rate record.

Statut de réponse: 200ID d'opération: delete-projects-projectId-members-memberId-rates-revenue-revenueId
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.

/users

User collection

List all users in the current organization or invite a new member.

GET

List users

Returns an ID-keyed map of organization users.

Statut de réponse: 200ID d'opération: get-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"
  }
}
POST

Create or invite a user

Invites a user to the current organization. Existing users are re-invited instead of duplicated.

Statut de réponse: 200ID d'opération: post-users
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"
}
/users/{userId}

Single user

Read, update, or remove a single user.

Paramètres de chemin

  • userId: The user identifier.
GET

Get a user

Returns one user record.

Statut de réponse: 200ID d'opération: get-users-userId
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"
}
PUT

Update a user

Updates one user. Administrators can change role and archived state. Users can update their own profile fields.

Statut de réponse: 200ID d'opération: put-users-userId
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

Delete a user

Permanently removes a user and their associated workspace data after server-side validations pass.

Statut de réponse: 200ID d'opération: delete-users-userId
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
{}
/users/{userId}/preferences

User preferences

Read or update personal preferences for one user.

Paramètres de chemin

  • userId: The user identifier.
GET

Get user preferences

Returns the preference document for the user. Users can only read their own preferences.

Statut de réponse: 200ID d'opération: get-users-userId-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"
}
PUT

Update user preferences

Updates the user preference document with locale, formatting, desktop, notification, or time-zone changes.

Statut de réponse: 200ID d'opération: put-users-userId-preferences
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"
}
/users/{userId}/rates/cost

User cost rates

List or create cost-rate windows for one user.

Paramètres de chemin

  • userId: The user identifier.
GET

List user cost rates

Returns an ID-keyed map of cost rates for the user.

Statut de réponse: 200ID d'opération: get-users-userId-rates-cost
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
  }
}
POST

Create a user cost rate

Creates a dated cost-rate window for the user.

Statut de réponse: 200ID d'opération: post-users-userId-rates-cost
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
}
/users/{userId}/rates/cost/{costId}

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

Get a user cost rate

Returns one user cost-rate record.

Statut de réponse: 200ID d'opération: get-users-userId-rates-cost-costId
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
}
PUT

Update a user cost rate

Updates one user cost-rate window.

Statut de réponse: 200ID d'opération: put-users-userId-rates-cost-costId
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

Delete a user cost rate

Deletes one user cost-rate record.

Statut de réponse: 200ID d'opération: delete-users-userId-rates-cost-costId
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.

/reports

Report collection

List saved reports or create a new report definition.

GET

List reports

Returns an ID-keyed map of saved reports.

Statut de réponse: 200ID d'opération: get-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"
  }
}
POST

Create a report

Creates a saved report configuration for the current user.

Statut de réponse: 200ID d'opération: post-reports
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"
}
/reports/{reportId}

Single report

Read, update, or delete a single report definition.

Paramètres de chemin

  • reportId: The report identifier.
GET

Get a report

Returns one report configuration.

Statut de réponse: 200ID d'opération: get-reports-reportId
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"
}
PUT

Update a report

Updates one saved report.

Statut de réponse: 200ID d'opération: put-reports-reportId
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

Delete a report

Deletes a saved report.

Statut de réponse: 200ID d'opération: delete-reports-reportId
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.

/geofences

Geofence collection

List geofences or create a new geofence rule.

GET

List geofences

Returns an ID-keyed map of geofences.

Statut de réponse: 200ID d'opération: get-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
  }
}
POST

Create a geofence

Creates a geofence with enter and exit actions.

Statut de réponse: 200ID d'opération: post-geofences
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
}
/geofences/{geofenceId}

Single geofence

Read, update, or delete one geofence.

Paramètres de chemin

  • geofenceId: The geofence identifier.
GET

Get a geofence

Returns one geofence by ID.

Statut de réponse: 200ID d'opération: get-geofences-geofenceId
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
}
PUT

Update a geofence

Updates one geofence.

Statut de réponse: 200ID d'opération: put-geofences-geofenceId
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

Delete a geofence

Deletes one geofence.

Statut de réponse: 200ID d'opération: delete-geofences-geofenceId
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
{}
/geofencing/enter

Geofence enter trigger

Signal that a device entered a geofence and let Sandtime.io run its configured enter action.

POST

Send a geofence-enter event

Processes a geofence enter event. This is mainly used by mobile clients and location automations.

Statut de réponse: 200ID d'opération: post-geofencing-enter
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"
}
/geofencing/exit

Geofence exit trigger

Signal that a device left a geofence and let Sandtime.io stop pending work where configured.

POST

Send a geofence-exit event

Processes a geofence exit event and returns the pending activities that were stopped.

Statut de réponse: 200ID d'opération: post-geofencing-exit
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.

/requests/projects/{projectId}/members/{memberId}/role

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.
POST

Create a role-change request

Creates a request to change the selected project member role.

Statut de réponse: 200ID d'opération: post-requests-projects-projectId-members-memberId-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"
}
/requests/{requestId}/projects/members/role

Resolve role-change request

Resolve a role-change request by marking it RESOLVED or REJECTED.

Paramètres de chemin

  • requestId: The workflow request identifier.
PUT

Resolve a role-change request

Applies or rejects the role change for an existing request.

Statut de réponse: 200ID d'opération: put-requests-requestId-projects-members-role
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"
}
/requests/projects/{projectId}/members

Create project-member assignment request

Create a project-member assignment request.

Paramètres de chemin

  • projectId: The project identifier.
POST

Create a project-member assignment request

Creates a request to assign one or more users to a project.

Statut de réponse: 200ID d'opération: post-requests-projects-projectId-members
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"
}
/requests/{requestId}/projects/members

Resolve project-member assignment request

Resolve a project-member assignment request.

Paramètres de chemin

  • requestId: The workflow request identifier.
PUT

Resolve a project-member assignment request

Marks the request RESOLVED or REJECTED. Resolved requests assign the selected users to the project.

Statut de réponse: 200ID d'opération: put-requests-requestId-projects-members
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"
}
/requests/projects/request-assignment

Create project-assignment request

Create a request for assignment to one or more projects.

POST

Create a project-assignment request

Creates a self-service request asking administrators to assign the current user to projects.

Statut de réponse: 200ID d'opération: post-requests-projects-request-assignment
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"
}
/requests/{requestId}/projects/assign

Resolve project-assignment request

Resolve a request for assignment to projects.

Paramètres de chemin

  • requestId: The workflow request identifier.
PUT

Resolve a project-assignment request

Marks the request RESOLVED or REJECTED. Resolved requests use `projectIds` to assign the requester to projects.

Statut de réponse: 200ID d'opération: put-requests-requestId-projects-assign
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"
}
/requests/{requestId}

Resolve impersonation request

Resolve an impersonation request raised elsewhere in the product.

Paramètres de chemin

  • requestId: The workflow request identifier.
PUT

Resolve an impersonation request

Marks the impersonation request RESOLVED or REJECTED. A resolved request triggers a one-time support sign-in link.

Statut de réponse: 200ID d'opération: put-requests-requestId
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"
}
/requests/timesheets/{year}/{week}/unlock

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.
POST

Create a timesheet-unlock request

Creates a request asking administrators to unlock one weekly timesheet.

Statut de réponse: 200ID d'opération: post-requests-timesheets-year-week-unlock
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"
}
/requests/{requestId}/timesheets/unlock

Resolve timesheet-unlock request

Resolve a timesheet-unlock request.

Paramètres de chemin

  • requestId: The workflow request identifier.
PUT

Resolve a timesheet-unlock request

Marks the unlock request RESOLVED or REJECTED. A resolved request opens the timesheet for a temporary editing window.

Statut de réponse: 200ID d'opération: put-requests-requestId-timesheets-unlock
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"
}
/requests/timesheets/{year}/{week}/approvals

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.
POST

Create a timesheet-approval request

Creates a request asking administrators to approve a weekly timesheet.

Statut de réponse: 200ID d'opération: post-requests-timesheets-year-week-approvals
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"
}
/requests/{requestId}/timesheets/approvals

Resolve timesheet-approval request

Resolve a timesheet-approval request.

Paramètres de chemin

  • requestId: The workflow request identifier.
PUT

Resolve a timesheet-approval request

Marks the approval request RESOLVED or REJECTED.

Statut de réponse: 200ID d'opération: put-requests-requestId-timesheets-approvals
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.

/timesheets/auto-lock

Auto-lock runner

Run the organization auto-lock routine against the current time zone and lock settings.

PUT

Run auto-lock

Evaluates whether the next weekly lock should run and updates organization lock metadata when it does.

Statut de réponse: 200ID d'opération: put-timesheets-auto-lock
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"
}
/timesheets/lock

Timesheet lock collection

Create a lock or temporary unlock window for one user and one ISO week.

POST

Create a timesheet lock

Creates or replaces one timesheet lock for the selected user/week combination.

Statut de réponse: 200ID d'opération: post-timesheets-lock
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
}
/timesheets/lock/{lockId}

Single timesheet lock

Delete one explicit timesheet lock or unlock window.

Paramètres de chemin

  • lockId: The timesheet lock identifier.
DELETE

Delete a timesheet lock

Deletes one timesheet lock by ID.

Statut de réponse: 200ID d'opération: delete-timesheets-lock-lockId
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
{}
/timesheets/reminder

Timesheet reminder runner

Trigger the reminder flow that asks users to fill timesheets before the automatic lock runs.

POST

Send timesheet reminders

Runs the reminder logic for the current organization.

Statut de réponse: 200ID d'opération: post-timesheets-reminder
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
null

Billing

Billing, plan changes, and checkout helpers.

/subscriptions

Subscription collection

Read the current subscription collection for the organization.

GET

List subscriptions

Returns subscription records for the current organization.

Statut de réponse: 200ID d'opération: get-subscriptions
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"
  }
]
/subscriptions/{subscriptionId}

Single subscription

Update one subscription, usually to change quantity or payment state.

Paramètres de chemin

  • subscriptionId: The external subscription identifier.
PUT

Update a subscription

Updates one existing subscription. This route is limited to administrators.

Statut de réponse: 200ID d'opération: put-subscriptions-subscriptionId
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

Checkout

Create a checkout link for a plan change.

POST

Create a checkout link

Creates a Paddle checkout link for the selected product and quantity.

Statut de réponse: 200ID d'opération: post-checkout
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

Billing history

Read the billing transaction history for the current organization.

GET

List billing history

Returns the current billing history from the payment provider.

Statut de réponse: 200ID d'opération: get-billing-history
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

Receipt upload

Upload an App Store receipt for validation.

POST

Upload a receipt

Submits a base64-encoded receipt payload to the billing backend.

Statut de réponse: 200ID d'opération: post-receipt
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
}