Employee) is the central API resource. It is a person’s record in a
specific tenant: scalar fields and references to related entities. Fetch it as a
list with GET /employees or one at a time with GET /employees/{employee_id}. The
list is returned newest first.
Fields
Identifiers are UUID strings, timestamps are RFC 3339 in UTC, and calendar dates are
YYYY-MM-DD. Absent values are present in the response (an empty string or null)
rather than dropped from the object. Ignore unfamiliar fields and enum values — the
response shape grows additively.Related objects
Theperson, department, job_title, and manager fields are separate entities,
available only on request via expand. The base response does not include them, only
the *_id references. How to traverse these relationships is on the
Employee graph page. The record’s custom fields are
also returned only via expand — see Custom fields.
person (expand=person)
department and job_title
Both objects are minimal references: id + title. There are no other fields
(department head, hierarchy, headcount) in them.
manager (expand=manager)
A reference to the manager: id + full_name. This object is deliberately
narrow — to get the manager’s full profile, request
GET /employees/{manager.id} with your key, so permissions and field redaction
apply to it.
Custom fields
Fields the company added to the employee record itself (shirt size, badge number, grade) come incustom_fields with expand=custom_fields. It is an
object: the key is the field’s api_name, the value is JSON shaped by the field
type. Without expand=custom_fields the object is empty.
Field catalog
GET /employee_custom_fields describes the fields: api_name, title, type,
options for lists and columns for tables. The title comes in the
Accept-Language language when a translation exists. The scope is the same —
employees:read.
Value types
type is shortened in the table: the response carries the CUSTOM_FIELD_TYPE_
prefix. Ignore unknown types — the list will grow.
Good to know
- No key, no value. When a field is in the catalog but its key is missing
from
custom_fields, the value is empty. Fields outside the catalog never appear, even on the key owner’s own record. Fields hidden by permissions may be listed inredacted_fieldsasemployees.<api_name>, but rely on the catalog, not on that list. - Files and images are not returned yet. Fields of these types are absent from both the catalog and the values; such columns are removed from tables too.
- Formula (computed) fields are not returned.
- Values are not translated. You get the value as it was entered.
- No filtering by custom fields. Select employees on your side.
- Changes. Editing a value changes the record’s
update_timeand sendsemployee.changed, soupdated_sincepicks it up. Changing the field itself (title, options, visibility) does not touch records. The catalog and records are read in separate requests, so a key missing from your copy of the catalog means it is time to re-read the catalog. - Employee record only. Custom fields of the person (
person) are not returned yet.
Access model
Even with theemployees:read scope, a key does not see everything. Effective
access is the intersection of the key’s scopes and the key owner’s permissions. A
scope is necessary but not sufficient: employees and fields unavailable to the owner’s
permission profile stay invisible to the key.
Fields the owner is not allowed to see (for example the IIN) are dropped from the
response, and their keys are listed in redacted_fields in object.field form. So,
with expand=person but without the permission for the IIN:
A single record is indistinguishable by reason of unavailability: “does not exist,” “no
access,” and “draft/deleted” all return the same
404 EMPLOYEE_NOT_FOUND. The
response code cannot tell you whether an employee hidden from you exists.Next
Employee graph
Employee relationships and traversal via
expand.Statuses and lifecycle
EmployeeStatus values and transitions.Pagination
Paging through lists and incremental sync.