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-signatureheader. - 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
adminto create webhooks (POST /webhooksfrom an HTTP module works with an admin key); awritekey 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
- Add Webhooks → Custom webhook, enable JSON pass-through and request headers. Copy the URL.
- Create the TimeTracking webhook (admin) with that URL; save the secret in a Make Data store or scenario variable
tt_secret. - Add a Tools → Set multiple variables module:
sig= thett-signatureheader valuet={{get(split(get(split(sig; ","); 1); "="); 2)}}v1={{get(split(get(split(sig; ","); 2); "="); 2)}}expected={{sha256(t + "." + value; "hex"; tt_secret)}}(wherevalueis the raw pass-through body)
- Add a Filter after it:
expectedequalsv1, and{{abs(timestamp - t)}}less than300. - JSON → Parse JSON on the raw body; route by
typewith 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, methodPOST - 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
4xxwith an error route. Store{{uuid}}with the source row before calling, so a re-run sends the sameid.
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) and423(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/423and 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.