Skip to content

Request an integration

Tell us which system you want to connect. We review every request weekly and publish a step-by-step guide or build the connection.

Make recipes

Use TimeTracking with Make (Integromat) today: custom webhooks with signature checks via sha256 HMAC, and HTTP modules for API calls.

Last updated: · Markdown version

1. Summary

Status: Recipe. A native TimeTracking app on Make is Planned.

Direction: Both. Triggers: TimeTracking webhooks. Actions: REST API calls.

2. Mechanism

  • Trigger: Webhooks → Custom webhook with JSON pass-through enabled and Get request headers on, so you receive the raw body and the tt-signature header.
  • Verify: a Set variable or Filter using Make's built-in sha256(text; "hex"; key) function (HMAC when a key is given).
  • Action: HTTP → Make a request with Authorization: Bearer tt_live_….

Assumption — verify in your Make account: option names ("JSON pass-through", "Get request headers") follow the current Make UI.

3. Prerequisites

  • Make account; an admin user (dashboard Regels & koppelingen) or an API key with scope admin to create webhooks (POST /webhooks from an HTTP module works with an admin key); a write key for the scenario itself.

4. Entity mapping

Scenario Source TimeTracking call
ATS/CRM hire → placement candidate, company, dates PUT /{clients,people,placements}/by-external/{source}/{ref} (idempotent upsert)
Spreadsheet/terminal hours → claims placement id, date, minutes POST /claims with source:"import", sourceRef, client-generated id
timesheet.approved → ERP/billing data.dayIds GET /days?from&to&status=approved&updated_since=…
export.completed → store file data.runId, range GET /exports/runs/{runId}/file returns the exact committed CSV (read key OK).

Upserts by external ID are full replaces. Batch endpoints (POST /{people|clients|placements|claims}/batch, ≤500 rows) cut operations per run.

5. Step-by-step setup

Webhook trigger with verification

  1. Add Webhooks → Custom webhook, enable JSON pass-through and request headers. Copy the URL.
  2. Create the TimeTracking webhook (admin) with that URL; save the secret in a Make Data store or scenario variable tt_secret.
  3. Add a Tools → Set multiple variables module:
    • sig = the tt-signature header value
    • t = {{get(split(get(split(sig; ","); 1); "="); 2)}}
    • v1 = {{get(split(get(split(sig; ","); 2); "="); 2)}}
    • expected = {{sha256(t + "." + value; "hex"; tt_secret)}} (where value is the raw pass-through body)
  4. Add a Filter after it: expected equals v1, and {{abs(timestamp - t)}} less than 300.
  5. JSON → Parse JSON on the raw body; route by type with a Router.

Make arrays are 1-based (get(array; 1) is the first item).

HTTP action

HTTP → Make a request:

  • URL https://app.timetracking.tech/api/v1/claims, method POST
  • Headers Authorization: Bearer tt_live_…, Idempotency-Key: make-{{1.row}}
  • Body type Raw, content type application/json:
{"id":"{{uuid}}","placementId":"{{1.placement_id}}","workDate":"{{formatDate(1.date; "YYYY-MM-DD")}}","minutes":{{round(1.hours * 60)}},"source":"import","sourceRef":"make-{{1.row}}"}
  • Parse response on; enable Evaluate all states as errors off and handle 4xx with an error route. Store {{uuid}} with the source row before calling, so a re-run sends the same id.

6. Sync schedule and triggering events

Instant scenarios on webhooks (TimeTracking delivers every 5 minutes). Scheduled scenarios can poll incrementally with updated_since and next_cursor (use a Repeater until next_cursor is empty).

7. Corrections, conflicts and locked periods

  • 409 (state does not allow, for example placement shortened before hours) and 423 (exported/locked day) are business errors: send them to a human, do not retry.
  • Disagreeing sources create conflicts; resolve in TimeTracking.

8. Testing checklist

  • Tampered secret blocks the scenario at the filter.
  • Same source row run twice yields one claim (same id).
  • Error route catches 422/423 and notifies.

9. Troubleshooting

Problem Fix
Hash never matches Body was parsed and re-serialised; use JSON pass-through raw value.
401 / 403 Wrong header or read-only key.
422 with issues Map issues[].path in the error route.
429 Add Sleep 60 s and retry.

10. Limits and known gaps

No native app or OAuth (Planned); ID-only webhook payloads; webhook management needs an admin user or admin-scope key.

11. Build it with Claude

Write step-by-step Make scenario instructions (module by module, with exact formulas) that receive TimeTracking
webhooks via Custom webhook (JSON pass-through + headers), verify tt-signature with sha256(t + "." + raw; "hex";
secret) and a 300 s freshness check, then route: timesheet.approved → GET
https://app.timetracking.tech/api/v1/days?from&to&status=approved&updated_since (Bearer key, follow next_cursor) → upsert rows
in Google Sheets keyed on day id;
conflict.created → email the office. Include an error route for 409/422/423/429.