Developers › Reference & tools
Developer Reference Availability & hours Knowing who handles a lead is only half a routing decision: qualifies tells you who covers it, and says nothing about whether anybody is at their desk. Every workspace, desk and person therefore carries an availability block — on get_workspace, list_lead_tags and list_crm_agents. Three planes, eight states, and one rule that surprises people.
The availability block The same shape on all three planes: workspace, desk, person. The shape is the same on all three planes. sources is always present and never empty; effective is a convenience derived from it, and is absent — not null — when no source reached a reading, because inventing one would look like a measurement. Key Meaning effective.state OPEN or CLOSED . Absent block means nothing concluded effective.basis Which sources entry it came from — always one that is present effective.timezone The zone the instants below belong to. ⚠ Render with this — “reopens at 13:00Z” is not a sentence you can say to a caller effective.opensAt When the next opening begins. ⚠ Can be null even on a real reading — no opening within eight days effective.closesAt When the current opening ends. null when the desk never closes sources[].source WHAT KIND of answer: WORKSPACE_HOURS , DESK_HOURS , BUSINESS_HOURS , OPERATING_HOURS , WORKING_HOURS , LIVE_STATUS sources[].origin WHOSE SYSTEM said so: LEADVAL , SALESFORCE , HUBSPOT . You need both halves to judge an answer sources[].timezone The zone that entry was computed in. null on a no-answer sources[].asOf When the underlying data was read. null for hours held in LeadLogiX, which are read live sources[].connectionId WHICH connection answered. Two orgs of one product are two entries you can tell apart — source and origin alone do not separate them. null for LEADVAL sources[].connectionLabel A name for that connection you can say out loud, where the id is only for telling two apart sources[].describes WHICH SETTING this entry is, in words. Always present, never null — including on a real reading, whose note is null. ⚠ Choosing which source to act on is your decision; this is how you know what you are choosing between. It names the screen for a LeadLogiX setting (“set in LeadLogiX on Company Profile”) and the connection’s own label for a CRM (“set in HubSpot”). Two pairs are invisible to source or origin alone: WORKING_HOURS arrives from BOTH LEADVAL and HUBSPOT , and BUSINESS_HOURS vs OPERATING_HOURS are two different records inside one Salesforce org sources[].inheritedFrom The parent workspace id when a sub-workspace inherited this. Inheritance is one hop sources[].note A sentence you can relay to a caller. Present on every no-answer workspaceAvailability The workspace plane, once per response, on list_lead_tags and list_crm_agents Hours inform. They never gate — a closed desk returns the same contact details A closed desk returns byte-identical contact details to an open one, and that is deliberate. One address serves two different jobs: transferring a live caller (wrong at nine in the evening) and sending a message that will be read when the desk next opens (exactly right at nine in the evening). Which one fits is your decision, so we never make it for you by withholding the address. If hours could hide a contact, the after-hours enquiry — the one nobody was there to take — is the one your agent would silently drop.
The eight states Two carry a reading. Five mean nobody can say — and each names a different fix. State Means What to do OPEN Answered now Transfer, or read the number out. Use the email freely CLOSED Not answered now Do not transfer. Offer a callback and, if opensAt is present, say when they reopen. ⚠ Still send the email NOT_CONFIGURED Nobody has set hours here No claim either way. ⚠ Never say “they are closed” NO_DATA We hold no hours from that system As above. Connect it, or schedule the pull RECONNECT_REQUIRED Connected, but not permitted to read hours As above. The workspace must reconnect that CRM NOT_SUPPORTED That system cannot answer at all As above, and stop asking it STALE What we hold is not usable — a failed read, or a stored schedule that will not parse Treat presence as unknown: offer, do not promise. note says which WITHHELD_NO_PERMISSION Person plane only: you lack workspace:read.contact Says nothing about whether hours exist. Request the scope A no-answer is never a CLOSED A workspace that never filled in its opening hours is not shut. Five of the eight states mean “we cannot say”, and they are separate because each has a different remedy — collapsing them into “closed” tells a caller something nobody claimed.
Two rules you must not re-derive Both are legal, and both look like mistakes. State is computed server-side in the source’s own zone, daylight saving included. If you are ever tempted to recompute it from raw times: an opening time equal to its closing time means open twenty-four hours , not a zero-length window — it is how Salesforce expresses its 24×7 default. And a closing time earlier than its opening time crosses midnight : a 22:00–06:00 desk is open all night, and the carry-over belongs to the previous day.
Which sources are emitted What is emitted today Emitted today: WORKSPACE_HOURS , DESK_HOURS , WORKING_HOURS , BUSINESS_HOURS , OPERATING_HOURS , LIVE_STATUS . Every source in the vocabulary now carries a real reading, so there is nothing left to wait for. By origin: WORKSPACE_HOURS and DESK_HOURS from LEADVAL ; WORKING_HOURS from both LEADVAL and HUBSPOT ; BUSINESS_HOURS and OPERATING_HOURS from SALESFORCE ; LIVE_STATUS from HUBSPOT . ⚠ BUSINESS_HOURS and OPERATING_HOURS are both SALESFORCE and are not the same thing — the first is the organisation’s default support hours and can never describe one person, the second is that person’s own Field Service schedule. ⚠ One source can arrive from more than one origin — WORKING_HOURS now does — so branch on the PAIR, never on source alone. ⚠ LIVE_STATUS is a REPORTED flag rather than a schedule: OPEN when the person is marked available for assignment, CLOSED when they have marked themselves away. Its timezone is null because no zone was involved in working it out, so weigh it by asOf — an hour-old “available” may simply be stale. It appears only on the person plane, only for a person that system knows, and only for a caller holding workspace:read.contact . ⚠ Several systems may answer and LeadLogiX does NOT reconcile them — two entries disagreeing is a normal payload, and which to trust is your judgement. effective is LeadLogiX’s own reading only; basis never names a CRM entry, so its absence means we hold no hours rather than that nobody knows. sources[] order is stable presentation, not a ranking. And a CRM’s untouched factory default reports NOT_CONFIGURED , never OPEN .