Developers
The Clerq API
The short version
- Push leads in, poll summaries out. One write (create a lead), three reads (leads, clients, matters). That is the whole surface, on purpose.
- Auth is a bearer key a practice admin creates on the Integrations page. The key is the practice: everything runs inside that firm’s data boundary, nothing else is reachable.
- Reads are summaries, never files. Names, stages, references, timestamps. Documents, notes and message bodies are not on this surface.
- There are no outbound webhooks — polling with
?since=is the supported pattern, and it is what Zapier’s triggers do natively. Why, below.
Base URL and versioning
https://app.clerq.nz/api/public/v1
The version lives in the path. v1 will not change shape under you: fields may be added to responses, but nothing documented here will be renamed, retyped or removed. Anything that would break a caller becomes v2.
Authentication
A practice admin creates a key in Clerq under Integrations → API keys.
The full key — it looks like clerq_sk_… — is shown exactly
once at creation; Clerq stores only a hash. Send it as a bearer token on every request:
curl -H "Authorization: Bearer clerq_sk_YOUR_KEY" \ https://app.clerq.nz/api/public/v1/clients
A missing, malformed, unknown or revoked key is the same 401 in every case
— the response never says which. Keys are revocable on the same page, and each key
shows when it was last used, so a practice can audit which of its keys are alive.
Create a lead
POST /leads — the write. It lands on the practice’s intake board
exactly like a website enquiry, and the audit trail records which key wrote it.
curl -X POST https://app.clerq.nz/api/public/v1/leads \
-H "Authorization: Bearer clerq_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Aroha",
"last_name": "Ngata",
"email": "[email protected]",
"phone": "+64211234567",
"visa_interest": "Skilled Migrant",
"source": "website",
"notes": "Enquiry from the pricing page"
}'
Only first_name is required. The response is 201 with the new
lead’s id and stage (always new).
Read summaries
| Endpoint | Each item carries | Typical use |
|---|---|---|
GET /leads |
id, first_name, last_name, email, stage, source, created_at, updated_at | “New lead” and “lead changed stage” triggers |
GET /clients |
id, display_name, kind, email, created_at, updated_at | Keeping a mailing list or CRM in step |
GET /matters |
id, case_ref, status, stage, visa_type, created_at, updated_at | “Matter changed stage” notifications |
Every list is newest-first by updated_at and capped at
200 items per request. That cap plus ?since= is the paging
model — there are no page numbers to fall out of sync with.
Polling with ?since=
Remember the newest updated_at you have seen, and pass it back on the next
poll as an ISO 8601 time with an offset:
curl -H "Authorization: Bearer clerq_sk_YOUR_KEY" \ "https://app.clerq.nz/api/public/v1/leads?since=2026-08-20T00:00:00Z"
The filter is at-or-after (>=), so the boundary row comes
back one more time — deduplicate by id, which is exactly what
Zapier’s polling triggers do without being asked. A record’s
updated_at equals its created_at until it changes, so the same
loop serves both “newly created” and “recently changed” triggers.
Why there are no webhooks (yet)
Clerq’s production network can only reach an explicit, reviewed list of hosts — that allow-list is a real security control on a system holding immigration files, not a formality. Webhooks mean delivering to arbitrary customer URLs, which would put a hole in exactly that control. Until an egress design earns webhooks on purpose, polling is the supported pattern — and at the volumes an advisory practice generates, a poll every few minutes is indistinguishable from push.
The rules of the surface
- One practice per key. A key can never see or write another firm’s data — that boundary is enforced in the database, not the application code.
- Summaries only. If you need a document or the contents of a note, that stays inside Clerq where access is logged per staff member.
- Treat the key like a password. Server-side only — never in a browser, an app binary, or a repository. Revoke and reissue in seconds if one leaks.
Questions, or something you need this API to do that it doesn’t? Get in touch — v1 is deliberately small, and real integrations are what grow it.