Help / Integrations

The API and webhooks

Time Trakkr has a public REST API for reading and writing your data, plus outbound webhooks that notify your own systems when things happen. This article is a short pointer to both; the full, always-current details live in the reference.

Where the full reference lives

The complete API reference, with every endpoint and its parameters, is at timetrakkr.com/developers. A machine-readable OpenAPI spec is served at /api/v1/openapi.json and imports straight into tools like Postman.

Token kinds

Every request sends Authorization: Bearer <token>. There are two kinds of token, both created on the in-app Developer page:

  • Personal access tokens act as you. Time entries created with one land on your timesheet, your role applies, and a member-grade token only ever sees its owner's own time and expenses.
  • Organization keys act org-wide with no person attached. Writes that need a person, such as logging time, require an explicit user_id.

Endpoints marked manager+ or admin refuse lower-grade personal tokens, so money such as rates, invoices, and reports never reaches a member token. This mirrors the roles and permissions that apply throughout the app. Requests are rate-limited (100 requests per 15 seconds per token), returning 429 with a Retry-After header when you go over.

Safe retries with Idempotency-Key

Because network calls can fail after the server has already acted, POST requests accept an Idempotency-Key header — any unique string up to 255 characters. Retrying with the same key and the same payload within 24 hours replays the original response (marked Idempotency-Replayed: true) instead of creating a duplicate. Reusing the same key with a different payload is refused, so a mistaken retry can never overwrite something.

Webhooks with signed payloads

Webhook endpoints are managed on the same Developer page, by a manager or admin. Add an endpoint URL, tick the events you want, and Time Trakkr will POST to it when they happen.

Events you can subscribe to

EventWhat arrives
time_entry.createdA time entry was logged. Sends the whole entry.
time_entry.updatedA time entry changed. Sends the entry as it now stands.
time_entry.deletedA time entry was removed. Sends only its id.
invoice.createdAn invoice was drafted. Sends the invoice; it has not been sent to anyone.
invoice.sentAn invoice was sent to its client. Sends the invoice.
invoice.paidAn invoice was marked paid. Sends the invoice as it now stands.

An endpoint only receives the events it is subscribed to. The body is always { "event": "...", "data": ..., "sentAt": "..." }, and the event name is repeated in an X-TT-Event header so you can route without parsing the body.

What to rely on, and what not to

  • Every payload is signed. Time Trakkr sends an X-TT-Signature header containing an HMAC-SHA256 signature of the raw request body. Verify it against your endpoint's signing secret to be sure the request really came from Time Trakkr.
  • The secret is shown once. When you create an endpoint, its signing secret is displayed a single time — copy it then and store it safely.
  • Test before you rely on it. Each endpoint has a Test button that sends a sample delivery so you can confirm your receiver verifies the signature and responds.
  • Your endpoint must be reachable over HTTPS at a public address. A URL that resolves to a private or internal address is refused, and it is re-checked on every delivery rather than only when you add it.
  • Delivery is attempted once and is not retried. A failure is recorded in the deliveries list on the Developer page, and the action that triggered it still succeeds — a webhook your receiver rejected never blocks someone's time entry. If you need guaranteed delivery, poll the API for anything you may have missed rather than assuming every event arrived.

For connecting an AI client such as Claude or Cursor over MCP rather than the plain REST API, see MCP and AI clients.

Updated 2026-07-20. Still stuck? Contact support or return to the Help Center.