Reference data and agency lookups
Almost every request you make refers to something by id — a job category, a shift, a title, a worker type. Those ids come from three different kinds of configuration data, and the difference between them decides whether you can change a value, who it applies to, and whether you can even read it.
Getting these three confused is the most common source of “why is this id rejected” and is worth five minutes now.
The three tiers
Section titled “The three tiers”Global reference data. Platform-wide controlled vocabularies, identical for every agency and read-only to everyone: titles, genders, nationalities, ethnic origins, marital statuses, NI categories, payment frequencies and methods, bank account types, holiday accrual and calculation methods, worker and client types and statuses, invoice methods. Nobody can add to these — they exist so that the same concept means the same thing across the platform.
Agency lookups. Per-tenant vocabularies your agency owns and configures: activity types, shifts, job categories, compliance items, availability statuses, transports, recruitment sources, logging and receiving hours, day rate rules. These are yours to create, rename and remove. Another agency’s list is completely different, and an id from it is meaningless to you.
Agency settings. Per-tenant operational configuration rather than a vocabulary: bank holidays, rate types, AWR alert rules, SMS templates, work detail labels, the Key Information Document templates for PAYE and subcontractor workers, and the numbering sequences that allocate worker and invoice numbers.
The practical test: if two agencies would reasonably disagree about the list, it is not global.
What you can read, and what you can change
Section titled “What you can read, and what you can change”All three tiers are on the published surface, but not with the same access.
Global reference data is read-only. You can list each vocabulary and fetch a single entry by id. There is no create, update or delete, and there never will be through this API — the whole point of the tier is that the values mean the same thing for everyone.
Agency lookups and agency settings are yours. List, read, create, update and, for most of them, delete.
Read the vocabularies rather than hardcoding them. The ids are stable, but a mapping you transcribed from a sample response is a copy that nothing keeps current — and a value added to a vocabulary will not appear in it.
One shape, repeated
Section titled “One shape, repeated”The agency lookup and settings endpoints are deliberately near-identical. Learn one and you have learned the family: each is a small collection you can list, read one of by id, create, update and — for most of them — delete.
Two consequences of that sameness:
- The list endpoints are not paged. These sets are bounded by your own configuration, so they return every record in a named array. Sending paging parameters does nothing.
- The differences that do exist are per-endpoint, not per-family. A few carry no delete, and a couple are single-record configuration rather than a collection. The reference states which; do not assume the full set exists because a sibling has it.
Deleting a lookup that is in use
Section titled “Deleting a lookup that is in use”A lookup value is referenced by the records that use it, so removing one is not a free action — and the family does not delete uniformly. Each operation’s reference page states which of these it does; the shape of the difference is worth knowing before you read one.
- Three lookups delete by flagging the record: activity types, job categories and shifts. The row is retained and existing references keep resolving, but it stops appearing in list and get-by-id responses.
- Most of the rest remove the row outright. That cannot be undone, and anything still referring to the value keeps the raw id it was given.
- There is no restore. No lookup or vocabulary has a restore operation, including the three that delete by flagging — a delete you did not mean is not recoverable through this API.
- The name is released either way. Duplicate checks skip flagged records, so a new value may reuse the name of a deleted one and creating it succeeds.
Cost centres and sites behave differently — they do offer restore, and a soft-deleted one holds its name until it is restored or purged, so creating a clashing one is rejected rather than silently succeeding. They are records, not lookups; do not carry that expectation across. See Errors for what that rejection looks like and how to recover.
Common misconceptions
Section titled “Common misconceptions”“Reference data means anything I look up.” It means the global, read-only tier specifically. Your own job categories are agency lookups, and the two behave nothing alike.
“These ids are stable across agencies.” Only the global ones are. An agency lookup id is meaningful inside one tenant and nowhere else, so never carry one between agencies.
“I can cache the lookup lists indefinitely.” Your own colleagues change agency lookups through the Recruso UI. Cache them for convenience, not as a source of truth, and re-read when a write is rejected for an unknown id.
“An empty list means something is wrong.” It means your agency has not configured that lookup. That is a normal state.
Identifiers, audit and timestamps — how to handle the ids these lists hand you.

