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.

Carerix integration

Sync Carerix employees, companies and placements into TimeTracking with external-ID upserts and batches, and report approved hours back with GET /days.

Last updated: · Markdown version

1. Summary

Status: Recipe (no native connector).

Direction: Carerix to TimeTracking for master data. Optional: TimeTracking to Carerix for approved hours.

Carerix is a staffing ATS/CRM widely used by Dutch agencies. The recipe upserts placed employees, client companies and placements into TimeTracking by their Carerix ids, and optionally writes approved hours back.

2. Mechanism

  • Carerix side. Read through the Carerix API (REST/XML "CxAPI" on older instances, REST/GraphQL on newer). Typical entities: CREmployee, CRCompany, CRVacancy, CRMatch / placement (CRJob in some setups). Detect changes by polling on modification date, or with Carerix notifications if your contract includes them.
  • TimeTracking side. PUT /{clients|people|placements}/by-external/carerix/{id} or POST /{clients|people|placements}/batch with externalSource: "carerix".
  • Hours back. GET /days?from&to&status=approved&updated_since=… (cursor-paginated), triggered by timesheet.approved or a schedule.

Assumption — verify with your Carerix admin/consultant: entity names and API flavour differ per Carerix version and licence.

3. Prerequisites

  • Carerix API credentials with read access to employees, companies and placements.
  • TimeTracking API key with scope write.
  • For webhooks: an admin user or an admin-scope API key.
  • Storage for the back-sync checkpoint (updated_since).

4. Entity mapping

Carerix object.field TimeTracking field Notes
CREmployee id person external ref (/people/by-external/carerix/{id})
CREmployee payroll number employeeNumber Must equal the payroll number used in exports.
CREmployee first / last name firstName / lastName Put Dutch prefixes in lastName ("de Vries").
CREmployee email, mobile, language email, phone, locale locale drives the app language (nl, pl, en, …).
CRCompany id client external ref (/clients/by-external/carerix/{id})
CRCompany name name
Contact who signs timesheets client contact Dashboard only; no API for contacts.
Placement / CRMatch id placement external ref; also ref
Employee id / company id of the placement personExternalRef / clientExternalRef Same source carerix.
Placement start / end startsOn / endsOn YYYY-MM-DD; omit endsOn for open-ended.
Function title roleTitle
Placement ended DELETE /placements/{id} (deactivate) or active: false
TimeTracking day (GET /days item) Carerix hours/timesheet record Assumption: depends on the Carerix timesheet module. Key on the day id.

External-ID strategy. source = carerix, ref = Carerix id. Upserts are idempotent and full replaces (omitted optional fields become null). Responses include created: true|false.

5. Step-by-step setup

export TT=https://app.timetracking.tech/api/v1
export KEY=tt_live_...

curl -s -X PUT "$TT/clients/by-external/carerix/2201" -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"name":"VDL Montage","externalRef":"2201","approvalMode":"both","mailDomains":"vdl-montage.example"}'

curl -s -X PUT "$TT/people/by-external/carerix/50017" -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"employeeNumber":"1001","firstName":"Jan","lastName":"de Vries","email":"jan@example.com","locale":"nl"}'

curl -s -X PUT "$TT/placements/by-external/carerix/90311" -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
  -d '{"personExternalRef":"50017","clientExternalRef":"2201","ref":"CX-90311","roleTitle":"Monteur","startsOn":"2026-09-01"}'

Initial load: use POST /clients/batch, /people/batch, /placements/batch (≤500 rows each, rows {externalSource:"carerix", externalRef, …}), in that order. Check results[] for ok: false rows. The script structure is the same as the Bullhorn sync.

Hours back:

curl -s "$TT/days?from=2026-11-01&to=2026-11-30&status=approved,exported&updated_since=2026-11-20T00:00:00Z&limit=500" \
  -H "Authorization: Bearer $KEY"

6. Sync schedule and triggering events

Trigger Action
Poll Carerix every 15 min on modification date Upsert changed employees, companies, placements.
Nightly Re-upsert everything active (idempotent).
timesheet.approved webhook or schedule GET /days?updated_since=…, write to Carerix.
placement.updated {active:false} Optional: reflect office deactivations.

7. Corrections, conflicts and locked periods

  • TimeTracking owns hours. conflict.created tells you a conflict exists; resolve it in TimeTracking.
  • A correction moves an approved day back to submitted and bumps its version; overwrite by day id in Carerix.
  • Exported/locked days return 423 locked. Corrections are new entries in an open period.
  • Shortening a placement before existing hours returns 409.

8. Testing checklist

  • First upsert returns created: true, the repeat created: false.
  • Batch with one bad row still writes the rest.
  • Ending a placement deactivates it.
  • GET /days?updated_since= returns only changed days.

9. Troubleshooting

Error Fix
401 invalid key New key from a current admin.
403 "API key is read-only" Use a write key.
422 "Person and client must exist (by id or external ref) before the placement" Upsert person and client first, same source.
422 with issues Check issues[].path; dates YYYY-MM-DD.
409 "N registration(s) exist after …" Do not shorten before existing hours.
429 Wait Retry-After (60 s).

10. Limits and known gaps

  • No API for client contacts.
  • The master-data CSV import (POST /import) still matches clients by name; prefer the external-ID API for ongoing sync.

11. Build it with Claude

Build a Carerix → TimeTracking sync (TypeScript, Node 20). Ask me for the Carerix API flavour (XML CxAPI or
REST/GraphQL) and sample responses for an employee, a company and a placement before writing the mapping.
TimeTracking: https://app.timetracking.tech/api/v1, Bearer $TT_API_KEY, responses { data } / { error }.
Use PUT /clients|/people|/placements/by-external/carerix/{id} (full replace), placements with personExternalRef/clientExternalRef, POST /…/batch for bulk (≤500, per-row
results), DELETE /placements/{id} to deactivate, Idempotency-Key on writes, 429 handling. Back-sync approved
hours with GET /days?from&to&status=approved&updated_since&limit=500 following next_cursor.
Dry-run mode and tests with mocked HTTP. Never delete data.