Directory & Contractors
Directory & Contractors
What is the Directory?
On the YunoJuno platform, the directory is your view of the contractors you work with. It is built around the client contact record: a stable entity that represents the long-term relationship between your organisation and a single contractor.
Unlike a contractor’s global profile, the client contact belongs to the relationship itself. Client-contact custom fields and directory-level lifecycle state all sit on this record. As a contractor moves through registration and onboarding with you, the same client_contact_id remains the stable anchor across every lifecycle event.
This matters because the contractor lifecycle and the client-contact lifecycle are related but not identical. A client contact can be created for a brand-new invitee, or it can be created for a contractor who is already registered and onboarded elsewhere on YunoJuno. Directory events describe what is happening for your specific relationship with a contractor, not for the contractor globally.
Actors
Lifecycle Overview
Each client-contact relationship progresses through a sequence of directory lifecycle events:
Not every relationship passes through every event. A contractor who is already registered and onboarded when you add them will trigger created with a lifecycle snapshot that already shows them as registered and finished onboarding — no separate registered or onboarding_completed event will follow.
Lifecycle Events
client.client_contact.created
Emitted when the client-contact relationship is first established. This covers both of the ways a client contact can come into existence:
- you invite a new contractor into your directory
- you add a contractor who already exists on YunoJuno
Because both routes share this event, created does not imply that the contractor is still invited. The webhook snapshot may already show registration_state = REGISTERED and onboarding_state = FINISHED if the contractor was already established on-platform when the relationship began.
client.client_contact.registered
Emitted only for invite-driven flows, once the contractor completes account registration. In platform terms, this is the point at which the contractor leaves the invited state, becomes registered, and begins onboarding for your organisation.
client.client_contact.onboarding_completed
Emitted when an invited contractor finishes onboarding. Consumers should treat status.bookability_state on the payload as the source of truth for bookability, rather than inferring it from the event name alone. In most directory-invite flows this event coincides with the contractor becoming bookable, but the payload remains authoritative.
client.client_contact.custom_fields_updated
Emitted whenever client-contact custom fields are updated. This event shares the same data.object snapshot as the other lifecycle events, and additionally carries data.changes so the exact fields touched in this update are visible.
Status Fields
Every lifecycle webhook carries a status object describing the current state of the client-contact relationship. The shape is intended to be integration-friendly rather than a raw mirror of internal model names.
The onboarding states exposed today are:
Custom Field Diffs
When client-contact custom fields change, the webhook carries both the full current snapshot and a diff of what changed in this event:
data.object.custom_fieldsis the full current snapshot of all custom fields after the updatedata.changes.fieldslists only the fields touched by this event- each entry in
data.changes.fieldscarriesoldandnewvalue snapshots so the exact before-and-after can be read directly
Change Types
In current directory flows these are the common change types. The webhook primitives are intentionally future-friendly so the API can support richer custom-field change semantics over time without changing the outer event shape.