Workers
A worker is a person record in your organisation — a staff member, volunteer, or contractor whose compliance you track. Workers hold the person's identifying details and link to every credential, Recruitment Check, ban, and check that's ever been run for them.
A person whose journey started via a Recruitment Check (and hasn't been formally onboarded yet) is called an applicant instead. The two are closely related — see Applicants vs. workers below.
What a worker represents
One person. Examples:
- A nurse you employ, with an active AHPRA registration and a current WWC.
- A teacher at your school, with a registration plus a police check.
- A contractor with NDIS worker screening and right-to-work documentation.
A worker always belongs to exactly one organisation. Two organisations that both employ the same physical person each have their own worker record for them — same human, different records. There is no global identity that crosses tenants (and there can't be, because tenant isolation is absolute).
Applicants vs. workers
The platform separates people you're considering from people you've onboarded:
| Applicant | Worker | |
|---|---|---|
| When created | Automatically by a Recruitment Check | Imported from your HRIS, created directly, or promoted from an applicant after onboard_constituent |
| Lifecycle stage | Onboarding / pre-employment | Active / employed |
| URN | urn:li:applicant:<id> | urn:li:worker:<id> |
| Counts toward active headcount | No | Yes |
| Eligible for renewal flows | No (still being onboarded) | Yes |
The promotion happens when an admin calls onboard_constituent on a completed Recruitment Check. Most of this guide talks about workers; everything carries over to applicants unless noted.
Core fields
| Field | Required | Notes |
|---|---|---|
first_name, last_name | ✓ | Used for matching during credential verification. |
email | ✓ | Must be unique within your organisation. Used as the destination for Recruitment Check emails. |
phone / mobile_number | — | Recommended for SMS-based flows and identity verification. |
date_of_birth | conditional | Required for some credential types (NSW WWC, SA WWC, NDIS Worker Screening, etc.). |
external_id | — | Strongly recommended. Your internal employee/contractor ID. Becomes the join key with your HRIS. |
active | ✓ | Boolean. Defaults to true. |
id / URN | auto | Assigned by Oho on creation. |
If you don't have a DOB at create time, submit without it — you can update later, and Oho can also auto-enrich the worker's DOB from data the person provides during a Recruitment Check or a successful registry check.
Active vs. inactive
active | Behaviour |
|---|---|
true | Shows in active staff lists. Eligible for new checks, Recruitment Checks, and renewal reminders. Counts toward compliance metrics. |
false | Read-only. History preserved, but the worker is excluded from active reports and no new operations are run against them. |
Deactivating is the right move when employment ends — it preserves the audit trail without cluttering live reports. A hard delete is also possible but rarely the right answer.
Relationships
Organisation
└── Worker (one person)
├── Credentials (their checks, licences, clearances)
├── Recruitment Checks (information requests sent to them)
├── Bans (any disqualifying register entries)
└── Checks history (police checks, etc.)
- Worker → Organisation (N:1) — every worker belongs to one organisation, can't be moved between them.
- Worker → Credentials (1:N) — a person can hold many credentials, in any combination, with their own statuses and expiries.
- Worker → Recruitment Checks (1:N) — a person can have any number of Recruitment Checks sent to them over time. Each one is a distinct event.
- Worker → Bans (0:N) — bans are surfaced as flags but stored separately so they preserve their public-register provenance.
Lifecycle
Onboard
│ Create applicant via Check ─┐
│ OR ├── First compliance picture
│ Create worker directly ─┘
▼
Active
│ Receive webhooks as credential statuses change
│ Periodically re-check or send renewal Recruitment Checks
▼
Offboard
Deactivate (`active = false`) — history preserved
OR Delete — only for genuine errors (e.g. wrong person created)
Common operations
These are the conceptual operations — the exact REST/GraphQL syntax is in the API Reference.
Create
Create a worker before doing anything else with them. Even minimal details (name + email) are enough — you can enrich later.
ensure_exists(first_name, last_name, email, [external_id], [date_of_birth])
→ returns Worker with id and URN
The "ensure exists" semantics mean: if a worker matching the identifying fields already exists, return the existing record instead of creating a duplicate. Match keys are typically email within your organisation, with external_id as a strong override.
Read
Fetch a worker by id (or URN). The response includes their fields plus links to their credentials, Recruitment Checks, and any bans.
Update
Patch any of the editable fields. Sensitive updates (DOB after creation) require admin role.
Deactivate
Patch active to false. Use this on offboarding.
Delete
Hard-delete a worker. Reserved for genuine errors. Removes the person record but preserves audit log entries. Prefer deactivation in almost every case.
Linking to your HR system
Every customer eventually needs to join Oho's worker records back to their HRIS. Two reliable joins exist:
| Field | Strength | Notes |
|---|---|---|
external_id | Strongest | Your authoritative employee ID. Set at create time and never reuse it. |
email | Strong | Unique within an organisation. Watch for email changes when staff change surname. |
Avoid relying on first/last name combinations — they're not unique and they change.
Auto-enrichment
When the platform receives new identifying data about a worker (from a successful registry check, from a Recruitment Check submission, from a state-government webhook), it can update the worker record. Examples:
- A WWC verification returns a different DOB than you supplied → the worker's DOB is corrected.
- A Recruitment Check submission supplies a phone number you didn't have → it's added.
Enrichment is non-destructive by default: missing fields are filled in, existing fields aren't overwritten unless the new value comes from a higher-trust source (e.g. a government registry overrides a self-asserted value).
Enrichment is auditable — every change is recorded.
Validation rules
- Email uniqueness — within your organisation only. The same email can exist in another organisation.
- DOB format —
YYYY-MM-DD. Required for state checks that match on DOB. - External ID — opaque string, your choice. Recommended to be globally unique within your HR system.
Privacy & access
Worker records store personally identifiable information (PII). Your responsibilities under the Australian Privacy Principles (and any other applicable law) apply.
- Only users in your organisation can see worker records. Tenant isolation guarantees this.
- Roles (Admin / Manager / Staff) further restrict who can read PII, edit it, or delete records.
- Subject-access requests are served by
GETon the worker. - Correction requests are served by
PATCH. - Right-to-erasure requests can be served by deactivation; full deletion may have audit implications — check with
support@weareoho.combefore hard-deleting for compliance reasons.
Best practice
- Create the record first. Always create the worker (or let a Recruitment Check create the applicant) before submitting their first credential. It costs you nothing and gives you a clean history.
- Always set
external_id. Future-you, debugging a webhook 18 months from now, will thank you. - Deactivate, don't delete. Hard deletion is for genuine mistakes.
- Re-use, don't recreate. Before creating, call "ensure exists" — duplicates are the most common avoidable error.
URN form
- Worker:
urn:li:worker:<id> - Applicant:
urn:li:applicant:<id>
Next
- Credentials → — the credentials that hang off a worker.
- Applicants → — people in recruitment, before they become workers.
- API Reference → — the exact endpoints for managing workers.