Skip to content

Work with agency lookups

By the end of this guide you will be able to work with any of your agency’s lookup lists, having learned the pattern once.

The examples below use job categories. Activity types, shifts, compliance items, availability statuses, transports, recruitment sources, rate types, bank holidays and the rest follow the same five operations against their own path.

1. Read the list before you write anything

Section titled “1. Read the list before you write anything”

Lookup lists are small, bounded by your own configuration, and not paged — the whole set comes back in one named array.

GET /v1/job-categories
Authorization: Bearer {accessToken}

Do this first for two reasons: it tells you whether the value you were about to create already exists, and it gives you the ids that every other resource refers to these by.

2. Cache them, but not as a source of truth

Section titled “2. Cache them, but not as a source of truth”

These lists change rarely, so caching them is worth it. They change through the Recruso UI though, where your colleagues work — so your cache goes stale without any signal from your side.

Refresh on a schedule, and always refresh on a rejection: a write refused for an unknown id is the clearest evidence your copy is out of date. Do not treat a cached list as authoritative when the API has just disagreed with it.

Creating takes the fields the reference lists for that lookup and returns the new record with its id. Store that id — it is what other resources will reference.

Before you update, check whether the operation is a full replacement or a partial merge. The reference states which per operation, and it matters: under a full replacement, a field you omit is set to null rather than left alone. Read the current record, change what you mean to change, and send the whole thing back.

A lookup value is referenced by every record that uses it, so removing one is not free — and the family does not delete uniformly. Each operation’s reference page states which of these it does.

Three lookups delete by flagging the record — activity types, job categories and shifts. The row is retained and existing references keep resolving, but the value stops appearing in list and get-by-id responses. The rest remove the row outright, and anything still referring to the value keeps the raw id it was given.

No lookup has a restore operation, including the three that flag. A delete you did not mean is not recoverable through this API, so read the list and confirm the id before you call it.

The name is released either way. Duplicate checks skip flagged records, so creating a value with a deleted one’s name succeeds — and produces a new id. Records that referenced the old value do not move to the new one; if you meant to bring a value back, that is the consequence to plan for.

Not every lookup offers a delete at all. Check the reference for the specific one rather than assuming the full set exists because a sibling has it.

  • The list call returns your new value with the id you were given.
  • A record referencing a retired value still carries that value’s id — retiring does not rewrite history.
  • Re-creating a retired value’s name succeeds and returns a new id, not the old one.
What you see Why What to do
400 on create with a duplicate name An active record already uses that name Read the list first; reuse the existing id
A recreated value has a different id from the one it replaced Deleting released the name; creating made a new record Expected. Update your own mapping — existing references keep the old id
404 on a lookup id that works elsewhere The id belongs to another agency, or to another lookup type Lookup ids are per-tenant and per-type; re-read the list
A field silently becomes null after an update The update was a full replacement and the field was omitted Read, modify, send the whole record
405 or a missing delete That lookup has no delete operation Check the reference for the operations that exist

Onboard a worker — a task that consumes several of these lists at once.