Skip to content

Sync clients and sites into your system

By the end of this guide you will have a local copy of your agency’s clients and their sites, and a defensible way of keeping it current.

  • A client-credentials access token — see the Quickstart.
  • Somewhere to store the records, keyed on the ids the API returns.
  • A read of Multi-tenancy: what you get back is scoped to your agency and narrowed to the accessible branches of the user your API app acts as.

Clients and sites can be fetched together or separately, and the right choice depends on your shape.

  • Together — the combined listing returns each client with its sites nested, which is one pass and no correlation work. Use it for a full sync.
  • Separately — list clients, then list the sites under a given client. Use it when you only need sites for a subset, or when the combined payload is larger than you want to hold.

Start with the combined call. Move to the split only if payload size becomes a real problem.

List endpoints for clients and sites are paged, and the envelope is the same one described in Responses and pagination:

GET /v1/clients/with-sites?pageNumber=1&pageSize=100
Authorization: Bearer {accessToken}

pageSize is capped at 100 — asking for more silently gives you 100, so do not assume your requested size was honoured. Loop until nextPage is null rather than computing the page count yourself; that way a record added mid-sync does not truncate your run.

Both listings also accept a name filter, a branch filter, a client status filter and sort parameters. Use them to narrow a sync, not to paginate — filtering is not a substitute for following nextPage.

Key your local records on the ids the API returns. They are opaque, they are the only way to fetch a record again, and they are the only thing that will still match on the next run — see Identifiers, audit and timestamps.

Store modifiedOn alongside each record. You will need it in the next step, and it is a UK-local timestamp rather than UTC.

4. Re-sync by comparing, not by asking for changes

Section titled “4. Re-sync by comparing, not by asking for changes”

This is the part that surprises people, so plan for it rather than looking for the endpoint that does not exist.

There is no incremental feed. No list endpoint takes a modified-since parameter, and there are no webhooks. A refresh means reading the set again and diffing it against what you hold.

That is workable because these sets are small and change slowly. A practical pattern:

  1. Read the full set on a schedule that matches how fast your agency’s client list actually moves — nightly is usually generous.
  2. Compare each record’s modifiedOn against your stored value, and update only what moved.
  3. Treat an id that is present locally but absent from the fresh read as removed or no longer visible — not necessarily deleted. A record can also leave your view because it was soft-deleted or because branch access changed. Mark it inactive rather than destroying your copy.
  • The number of clients you stored equals totalCount from the first page of the run.
  • Re-running the sync immediately changes nothing — every modifiedOn matches.
  • A client you edit in the Recruso UI shows a newer modifiedOn on the next run.
What you see Why What to do
Fewer records than colleagues see in the UI The listing is narrowed to the accessible branches of the user behind your API app Check that user’s branch access in the Recruso UI
pageSize=500 returns 100 records The cap is 100 Follow nextPage rather than requesting large pages
A 404 fetching a client whose id you hold It was soft-deleted, or it left your branch access Mark it inactive locally; do not delete the id
Timestamps an hour out for half the year modifiedOn is UK local time and was parsed as UTC Parse as Europe/London
A 401 partway through a long run The access token expired mid-sync Re-authenticate and resume from the current page

Work with agency lookups — the configuration data these records refer to by id.