Directory & Contractors
Directory & Contractors
Directory & Contractors
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.
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.
client.client_contact.createdEmitted when the client-contact relationship is first established. This covers both of the ways a client contact can come into existence:
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.registeredEmitted 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_completedEmitted 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_updatedEmitted 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.
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:
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_fields is the full current snapshot of all custom fields after the updatedata.changes.fields lists only the fields touched by this eventdata.changes.fields carries old and new value snapshots so the exact before-and-after can be read directlyIn 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.