# BambooHR Documentation > Documentation for BambooHR Append .md to any documentation page URL to get its markdown version. ## Guides - [Getting Started With The API](https://documentation.bamboohr.com/docs/getting-started.md): Our open API makes it easy to integrate other applications into BambooHR. Use this guide to get started sharing your data across systems. - [Postman Collection](https://documentation.bamboohr.com/docs/postman-collection.md): We offer a downloadable version of the BambooHR API as an OpenAPI specification file. This file can be used to generate a Postman Collection or interact with the OpenAPI definition directly in your preferred tools. - [Technical Overview](https://documentation.bamboohr.com/docs/api-details.md) - [Field Types](https://documentation.bamboohr.com/docs/field-types.md) - [Field Names](https://documentation.bamboohr.com/docs/list-of-field-names.md) - [Table Name & Fields](https://documentation.bamboohr.com/docs/table-name-fields.md) - [Webhooks](https://documentation.bamboohr.com/docs/webhooks.md) - [Global Webhooks](https://documentation.bamboohr.com/docs/global-webhooks.md) - [Permissioned Webhooks](https://documentation.bamboohr.com/docs/permissioned-webhooks.md) - [Choosing a Payload Type](https://documentation.bamboohr.com/docs/choosing-a-payload-type.md) - [Event-Based Webhooks](https://documentation.bamboohr.com/docs/event-based-webhooks.md) - [Field-Based Webhooks](https://documentation.bamboohr.com/docs/field-based-webhooks.md) - [Official SDKs](https://documentation.bamboohr.com/docs/sdks.md): Official BambooHR SDKs to accelerate your API integration. - [BambooHR and AI](https://documentation.bamboohr.com/docs/bamboohr-and-ai.md) - [Claude Connector](https://documentation.bamboohr.com/docs/claude-connector.md) - [ChatGPT Connector](https://documentation.bamboohr.com/docs/chatgpt-connector.md) - [MCP Server](https://documentation.bamboohr.com/docs/mcp-server.md) - [Planned Changes to the API](https://documentation.bamboohr.com/docs/planned-changes-to-the-api.md) - [Historical Changes to the API](https://documentation.bamboohr.com/docs/past-changes-to-the-api.md): Changes to the BambooHR API, newest first. Covers new endpoints, behavior and response changes, deprecations, and updates to the API reference. - [API Support](https://documentation.bamboohr.com/docs/api-support.md) - [Give API Feedback](https://documentation.bamboohr.com/docs/give-api-feedback.md) ## API Reference - [Account Information](https://documentation.bamboohr.com/reference/account-information.md) - [Get company properties](https://documentation.bamboohr.com/reference/get-meta-company.md): Get company properties including ID, name, domain, and base API URL. Provides essential company metadata for API access. OAuth Scopes: company:info - [List Fields](https://documentation.bamboohr.com/reference/list-fields.md): Returns a list of all employee fields available in the account, including field ID, display name, data type, and whether the field is deprecated. Use this endpoint to discover which field names are valid for use with the Get Employee, Datasets, and other field-based endpoints. The response includes standard BambooHR fields as well as any custom fields configured in the account. OAuth Scopes: employee, field - [List Tabular Fields](https://documentation.bamboohr.com/reference/list-tabular-fields.md): Returns a list of all tabular (table-based) fields available in the account. Each table includes its alias and the fields it contains with their IDs, names, and types. Use this endpoint to discover which table names are valid for the table row endpoints (e.g., jobInfo, compensation, employmentStatus). For fields whose type is `list`, `multilist`, or another option-backed type, the field `id` can be matched to `fieldId` from `list-list-fields` to retrieve the account-level option list. OAuth Scopes: field - [List List Fields](https://documentation.bamboohr.com/reference/list-list-fields.md): Returns details for all list fields in the account. Each list includes its field ID, alias, options, and whether it is manageable (editable). Lists with the `manageable` attribute set to `yes` can be modified via the PUT endpoint. Lists with the `multiple` attribute set to `yes` are fields that can have multiple values. Options with the `archived` attribute set to `yes` are soft-deleted and included so that historical data can reference the value — filter by `archived: no` to show only active options to end users. OAuth Scopes: field - [Update List Field Values](https://documentation.bamboohr.com/reference/update-list-field-values.md): Create, update, or archive options for a list field. To update an existing option, specify its `id`. To create a new option, omit `id`. To archive an option, set `archived` to `yes` — the option is soft-deleted and will continue to appear in GET responses for historical data integrity. To reactivate an archived option, set `archived` to `no`. The `archivedDate` field is server-set when an option is first archived and is not cleared if the option is later reactivated. Options on list fields with `manageable: no` cannot be modified and will return a 405. OAuth Scopes: field.write - [List Users](https://documentation.bamboohr.com/reference/list-users.md): Returns all users for the company, optionally filtered by status. Each user entry includes a user ID, associated employee ID, name, email address (resolved in priority order: work, home, account), account status, and last login time when available. Pass a comma-separated list of status values via the `status` query parameter to filter results. Valid values are `enabled` and `disabled`. If the parameter is omitted or contains only unrecognized values, users of all statuses are returned. Support admin accounts are always excluded from the response. The response format is determined by the `Accept` request header. Send `Accept: application/json` to receive JSON; omit the header or send any other value to receive XML. OAuth Scopes: user, user:management - [List Industries](https://documentation.bamboohr.com/reference/list-industries.md): Returns every industry in BambooHR's reference data as a JSON array. To set a company's industry, pass a returned entry's `id` to Update Company Industry Codes (`put-company-industry-codes`). OAuth Scopes: meta - [Get Countries](https://documentation.bamboohr.com/reference/get-countries-options.md): Returns a JSON array of every country in the catalog, or a single country object when `isoCode` is supplied. Each element has `id` (Country ID), `name` (Country Name), and `isoCode` (ISO 3166-1 alpha-2 code or null when unset). OAuth Scopes: field, meta - [Get Country by ID](https://documentation.bamboohr.com/reference/get-country-by-id.md): Returns a single country from the catalog as a JSON object, identified by its numeric id. Each field matches the corresponding element returned by Get Countries (`get-countries-options`). Use this for a single country lookup by id. For ISO 3166-1 code lookup or the full country list, use Get Countries (`get-countries-options`) instead. OAuth Scopes: meta - [Get All Provinces](https://documentation.bamboohr.com/reference/get-all-provinces.md): Returns a flat list of all states and provinces across every country. Each entry includes a numeric ID, the countryId it belongs to, an abbreviation label (e.g. "UT"), an ISO 3166-2 code (e.g. "US-UT"), and a full name. Use the countryId field to filter client-side. OAuth Scopes: meta - [List states and provinces for a country by Country ID](https://documentation.bamboohr.com/reference/get-states-by-country-id.md): Returns the list of states or provinces for the specified country, sorted alphabetically by abbreviation (`options[].label`). Each item follows StateProvinceSchema: `label` is the subdivision abbreviation (e.g. "UT"), not the full name; `name` is the full subdivision name; `iso` is the ISO 3166-2 code (e.g. "US-UT"). Use a `countryId` from `GET /api/v1/meta/countries/options` (the `id` field on the row for the country) so it matches the countries list. OAuth Scopes: field - [List timezones](https://documentation.bamboohr.com/reference/5c5fb0f1211ae1c9451753f92f1053b6.md): Retrieves a paginated list of timezones. Supports pagination, filtering, sorting, and field projection via OData query parameters. - [Get timezone by ID](https://documentation.bamboohr.com/reference/baa7162824294d030115568d1d8e6ca7.md): Retrieves a single timezone by its numeric ID. Returns the same timezone resource shape used by the list endpoint. OAuth Scopes: meta - [Get timezone by ZIP code](https://documentation.bamboohr.com/reference/10d66d8561dd7dac50ff9c21ef63d83b.md): Retrieves the timezone for a US ZIP code. Returns the same timezone resource shape used by the list endpoint. Only US ZIP codes are supported; valid 5-digit ZIPs that are not present in our reference data return a 404. OAuth Scopes: meta - [List Bank Holidays](https://documentation.bamboohr.com/reference/list-bank-holidays.md): Returns global bank holiday reference dates (US federal and related bank holidays maintained by BambooHR), not company-configured holidays. The response is a JSON array of holiday objects sorted by date in ascending order. Provide `year` to return only holidays whose dates fall within that calendar year; omit it to return the full multi-year reference set. OAuth Scopes: meta - [Get all currency types](https://documentation.bamboohr.com/reference/get-all-currency-types.md): Returns a JSON array of supported currency catalog entries. Each object includes `id`, `code`, `name`, `symbol` (display symbol), and `symbolPosition`—an integer discriminator: `0` = symbol before the amount (prefix) and `1` = after the amount (postfix), matching the values returned in the JSON body. - [Get Currency Conversion Rates](https://documentation.bamboohr.com/reference/get-currency-conversions.md): Returns the latest currency conversion rate snapshot for a single base currency. The response is a single JSON object whose `rates` field is a map of ISO 4217 currency codes to conversion rates relative to the base currency; the base currency itself maps to `1`. The rate-map keys match the `code` values from **Get All Currency Types** (`get-all-currency-types`). A well-formed base currency code that has no stored snapshot returns 404 rather than an empty object. OAuth Scopes: meta - [Alerts](https://documentation.bamboohr.com/reference/alerts.md): The Alerts API manages BambooHR's email alerts: the scheduled notifications a company sends to employees, managers, and administrators about events such as upcoming birthdays, work anniversaries, expiring certifications, and completed onboarding tasks. An alert *template* is one of the alert types BambooHR supports; the catalog is the same for every account. An alert *configuration* is one company's instance of a template, carrying its own schedule, recipients, filters, and message overrides. Start from the template catalog to find the `bambooAlertId` you want, then create a configuration from it. All operations require that the authenticated caller has view access to the company's Email Alerts settings in BambooHR; callers without it receive a `403` rather than a filtered result. - [List Alert Configurations](https://documentation.bamboohr.com/reference/list-alert-configurations.md): Returns every alert configuration the company has set up: which alert template each one uses, when it runs, who receives it, and any custom subject, message, or list-value filters. The response is a top-level JSON array with no wrapper, empty when the company has no configured alerts, and in no guaranteed order. Use this to enumerate or search a company's own configured alerts. To read a single configuration whose `id` is already known, use **Get Alert Configuration** (`get-alert-configuration`) instead. For the catalog of alert types that *can* be configured, rather than what this company has configured, use **List Alert Templates** (`list-alert-templates`). The `bambooAlertId` on each entry returned here is the same identifier that `list-alert-templates` returns as `id`. Access is all-or-nothing rather than per-record. An authenticated caller without view access to the company's Email Alerts settings receives `403` instead of a filtered list, so a successful response always contains the company's complete set. OAuth Scopes: alerts - [Create Alert Configuration](https://documentation.bamboohr.com/reference/create-alert-configuration.md): Creates an alert configuration for the authenticated company from one of BambooHR's alert templates, and returns the stored configuration, including its server-assigned `id`, as a single JSON object. Use this to add a configuration the company does not have yet. To overwrite one that already exists, use **Replace Alert Configuration** (`replace-alert-configuration`) instead; to see what is already configured, use **List Alert Configurations** (`list-alert-configurations`). `bambooAlertId` names the alert template the configuration is built on and comes from **List Alert Templates** (`list-alert-templates`). An alert configuration sends scheduled email to people; to receive a programmatic HTTP callback when employee data changes instead, use **Webhooks > Create Webhook** (`create-webhook`). The configuration is live as soon as it is created and begins sending on the schedule it defines. Nothing limits a template to one configuration, so repeating this call with the same `bambooAlertId` adds a second configuration rather than replacing the first, and no endpoint deletes an alert configuration once it exists. The returned object also carries `additionalRecipientEmails`, `employeeIds`, `listValueIds`, and `userIds`; this API never stores those, so scope an alert's audience with `filterListValueIds` and the `sendTo*` properties instead. Access is all-or-nothing rather than per-record. An authenticated caller without view access to the company's Email Alerts settings receives `403` instead of a partial success. OAuth Scopes: alerts.write - [Get Alert Configuration](https://documentation.bamboohr.com/reference/get-alert-configuration.md): Returns one alert configuration the company has set up: which alert template it uses, when it runs, who receives it, and any custom subject, message, or list-value filters. The response is a single JSON object with no wrapper. Use this when the configuration's `id` is already known, either from **List Alert Configurations** (`list-alert-configurations`) or from the body **Create Alert Configuration** (`create-alert-configuration`) and **Replace Alert Configuration** (`replace-alert-configuration`) return. To enumerate or search a company's configured alerts, use `list-alert-configurations` instead. For the catalog of alert types that *can* be configured, rather than what this company has configured, use **List Alert Templates** (`list-alert-templates`). The `bambooAlertId` on the returned object identifies the underlying template, not this configuration, so the two identifiers are not interchangeable. Access is all-or-nothing rather than per-record. An authenticated caller without view access to the company's Email Alerts settings receives `403` rather than a partially redacted object. Only configurations belonging to the authenticated company are reachable, and an `id` from any other company is indistinguishable from one that never existed. OAuth Scopes: alerts - [Replace Alert Configuration](https://documentation.bamboohr.com/reference/replace-alert-configuration.md): Overwrites the alert configuration identified by `{id}` and returns the stored configuration as a single JSON object. Each call replaces the whole configuration: a property left out of the request body is reset to its default rather than kept at its current value, so send the full desired state and not only the properties that changed. Read the current state with **Get Alert Configuration** (`get-alert-configuration`) first when only part of a configuration should change. The response echoes the values submitted rather than re-reading the saved row, so read the configuration back with `get-alert-configuration` when the persisted state needs to be confirmed. Use this to change a configuration the company already has. To add one, use **Create Alert Configuration** (`create-alert-configuration`) instead; to find out what is already configured, use **List Alert Configurations** (`list-alert-configurations`). `bambooAlertId` names the alert template the configuration is built on, comes from **List Alert Templates** (`list-alert-templates`), and is required on every call even when the template is not changing. The configuration stays live throughout and sends on whatever schedule the call leaves it with, so an update that omits the `sendTo*` properties can re-enable delivery to recipients the previous state excluded. Changing `bambooAlertId` re-points this configuration at a different alert template rather than adding a second one, and no endpoint deletes an alert configuration once it exists. The returned object also carries `additionalRecipientEmails`, `employeeIds`, `listValueIds`, and `userIds`; this API never stores those, so scope an alert's audience with `filterListValueIds` and the `sendTo*` properties instead. Access is all-or-nothing rather than per-record. An authenticated caller without view access to the company's Email Alerts settings receives `403` instead of a partial success. OAuth Scopes: alerts.write - [List Alert Templates](https://documentation.bamboohr.com/reference/list-alert-templates.md): Returns the catalog of alert templates that company alert configurations are built from. These are the built-in alert types BambooHR supports (for example New Hire, Birthdays, Time Off Approved), each paired with the settings group it is filed under. The response is an object with a single `alerts` array, ordered by `groupName` and then `name`. The alert-configuration endpoints represent the same identifier as `bambooAlertId`. The catalog is global: it lists every alert BambooHR offers and is not narrowed to the features the authenticated company has enabled, so a template appearing here does not guarantee that the company can configure it. Use this to discover the `bambooAlertId` required by **Create Alert Configuration** (`create-alert-configuration`). For the alerts a company has already configured, use **List Alert Configurations** (`list-alert-configurations`) instead. Callers without view access to the company's Email Alerts settings receive `403` rather than a filtered result. OAuth Scopes: alerts - [Applicant Tracking](https://documentation.bamboohr.com/reference/applicant-tracking.md) - [Get Job Summaries](https://documentation.bamboohr.com/reference/get-job-summaries.md): Get a list of job opening summaries. The authenticated caller must have access to ATS settings. Results can be filtered by status group and sorted by various fields. By default returns all non-deleted job openings. OAuth Scopes: hiring:applications - [Get Job Applications](https://documentation.bamboohr.com/reference/get-applications.md): Get a list of applications. The authenticated caller must have access to ATS settings. Combine as many different optional parameter filters as you like. OAuth Scopes: hiring:applications - [Get Job Application Details](https://documentation.bamboohr.com/reference/get-application-details.md): Get the full details of a single application including applicant info, job details, questions and answers, and status history. The authenticated caller must have access to ATS settings. OAuth Scopes: hiring:applications - [Create Job Application Comment](https://documentation.bamboohr.com/reference/create-application-comment.md): Add a comment to an application. The authenticated caller must have access to ATS settings. The `type` field defaults to `comment` if omitted. OAuth Scopes: hiring:applications.write - [Get Applicant Statuses](https://documentation.bamboohr.com/reference/get-statuses.md): Get a list of applicant statuses configured for the company. The authenticated caller must have access to ATS settings. Returns both system-defined and custom statuses. OAuth Scopes: hiring:applications - [Update Applicant Status](https://documentation.bamboohr.com/reference/update-applicant-status.md): Update the status of an application. The authenticated caller must have access to ATS settings. Use the Get Applicant Statuses endpoint to obtain valid status IDs. OAuth Scopes: hiring:applications.write - [Get Company Locations](https://documentation.bamboohr.com/reference/get-company-locations.md): Get all company locations available for use when creating a job opening. The authenticated caller must have access to ATS settings. Use the returned location IDs as the `jobLocation` field when calling the Create Job Opening endpoint. OAuth Scopes: hiring:applications - [Get Hiring Leads](https://documentation.bamboohr.com/reference/get-hiring-leads.md): Get the list of employees who can be assigned as a hiring lead when creating a new job opening. The authenticated caller must have access to ATS settings. Use the returned `employeeId` values as the `hiringLead` field when calling the Create Job Opening endpoint. - [Create Candidate](https://documentation.bamboohr.com/reference/create-candidate.md): Create a new candidate application for a job opening. The authenticated caller must have access to ATS settings. On success, returns the new candidate ID. Only fields required by the target job opening's standard questions need to be provided beyond firstName, lastName, and jobId. OAuth Scopes: hiring:applications.write - [Create Job Opening](https://documentation.bamboohr.com/reference/create-job-opening.md): Create a new job opening. The authenticated caller must have access to ATS settings. Use the Get Company Locations and Get Hiring Leads endpoints to obtain valid IDs for `jobLocation` and `hiringLead`. On success, returns the new job opening ID. - [Benefits](https://documentation.bamboohr.com/reference/benefits.md) - [List Company Benefits](https://documentation.bamboohr.com/reference/list-company-benefits.md): Returns all active (non-deleted) company benefit plans for the account. Each plan includes summary-level fields such as name, benefit category type, associated vendor and deduction IDs, effective date range, and catch-up eligibility flags. Deleted plans are excluded. To retrieve full detail for a specific plan (including SSO URL, description, and ACA fields), use "Get a company benefit". OAuth Scopes: benefit - [List Benefit Coverages](https://documentation.bamboohr.com/reference/list-benefit-coverages.md): Returns all benefit coverage levels configured in the company, such as Employee Only, Employee + Spouse, and Employee + Family. The JSON response wraps results under a "Benefit Coverages" key. Each coverage level includes an ID, short name, optional description, sort order, and an associated benefit plan ID (null for company-wide levels). Requires Benefits Administration permissions or owner/admin access. OAuth Scopes: benefit - [List Benefit Deduction Types](https://documentation.bamboohr.com/reference/list-benefit-deduction-types.md): Returns all benefit deduction types available in the system. Each deduction type describes a category of payroll deduction (e.g. 401(k), HSA, Section 125) along with its allowable benefit plan types, default deduction code, and optional sub-types. Some deduction types are grouped under a parent with sub-types (e.g. Pre-Tax groups Health, Dental, etc.); in that case the parent entry has a non-empty `subTypes` array. Requires Benefits Administration permissions. OAuth Scopes: benefit - [List Employee Benefits](https://documentation.bamboohr.com/reference/list-employee-benefits.md): Returns current and scheduled-future benefit enrollment records, grouped by employee. The response is a JSON object with a single `employeeBenefits` array where each entry contains the internal employee ID, the employee's current pay frequency (null when no pay schedule is set), and an `employeeBenefit` array of per-plan records that includes both the current enrollment record and any scheduled future-change records for that plan. Each record includes enrollment status, deduction date range, currency, occurrences-per-year, and the full employee/employer cost-sharing fields. A JSON request body with a `filters` object is required, and the `filters` object must contain at least one of `employeeId`, `companyBenefitId`, or `enrollmentStatusEffectiveDate`. Any combination is accepted. Providing no `filters` object or an empty `filters` object returns a 400 validation error. Filtering by `companyBenefitId` or `enrollmentStatusEffectiveDate` returns enrollments for every accessible employee, so the response can contain many entries. Use **List Company Benefits** (`list-company-benefits`) to look up valid `companyBenefitId` values. Future-enrollment records are silently omitted when the authenticated user lacks permission to view scheduled benefit changes. Current enrollment records continue to be returned. An empty `employeeBenefit` array on a known employee can mean either no enrollments or that the caller cannot view them. Note: This endpoint accepts filters inside a JSON request body on a `GET` request, which is non-standard. Some HTTP clients, proxies, and gateways may strip request bodies from GET requests, which can produce confusing missing-filter behavior. Callers experiencing validation errors should verify that the request body is being preserved. A query-parameter-based endpoint will be released in the future. OAuth Scopes: benefit - [List Member Benefit Events](https://documentation.bamboohr.com/reference/list-member-benefit-events.md): Returns benefit enrollment events for all employees and their dependents over the past year, organized by member. Each entry identifies a member (employee or dependent) and lists their per-plan coverage events (eligibility granted, enrolled, or loss of coverage), sorted chronologically. Requires benefit settings access. OAuth Scopes: benefit - [List Employee Dependents](https://documentation.bamboohr.com/reference/list-employee-dependents.md): Returns employee dependents for the company. When `employeeid` is provided, only dependents for that employee are returned. When omitted, all dependents across all employees are returned. The response is a JSON object with a top-level key "Employee Dependents" containing an array of dependent objects. SSN and SIN are returned as masked values (e.g. "xxx-xx-1234"). State and country are returned as full names. Supports both JSON and XML response formats via the Accept header. Requires Benefits Administration permissions. OAuth Scopes: employee:dependent, employee:dependent:ssn - [Get Employee Dependent](https://documentation.bamboohr.com/reference/get-employee-dependent.md): Returns the details of a single employee dependent by their dependent ID. The response is a JSON object with a top-level key "Employee Dependents" containing a single-element array. SSN and SIN are returned as masked values (e.g. "xxx-xx-1234"). State and country are returned as full names. Supports both JSON and XML response formats via the Accept header. Requires Benefits Administration permissions. OAuth Scopes: employee:dependent, employee:dependent:ssn - [Create Employee Dependent](https://documentation.bamboohr.com/reference/create-employee-dependent.md): Creates a new dependent record for an employee. `employeeId` is required and must reference a valid employee. `relationship` must be a valid relationship type and `gender` must be a valid gender value. `isUsCitizen` and `isStudent` accept "yes" or "no". `state` accepts a state code (e.g. "UT") and `country` accepts an ISO 3166-1 alpha-2 country code (e.g. "US"). `dateOfBirth` must be in YYYY-MM-DD format. SSN and SIN are accepted as plain text and stored encrypted. Accepts both `application/json` and `application/xml` request bodies. The response format mirrors the request `Content-Type` (not the `Accept` header): JSON request bodies receive a JSON response; XML request bodies receive an XML response. A successful creation fires an internal dependent-created event that may trigger downstream benefit enrollment processing. OAuth Scopes: employee:dependent.write, employee:dependent:ssn.write - [Update Employee Dependent](https://documentation.bamboohr.com/reference/update-employee-dependent.md): Replaces all fields on an existing employee dependent record. The request body must contain the full desired state of the dependent — omitted fields are written as empty or null, not preserved. `employeeId` is required and must reference a valid employee. `relationship` must be a valid relationship type and `gender` must be a valid gender value. `isUsCitizen` and `isStudent` accept "yes" or "no". `state` accepts a state code (e.g. "UT") and `country` accepts an ISO 3166-1 alpha-2 country code (e.g. "US"). `dateOfBirth` must be in YYYY-MM-DD format. SSN and SIN are accepted as plain text and stored encrypted. Accepts both `application/json` and `application/xml` request bodies. The response format mirrors the request `Content-Type` (not the `Accept` header): JSON request bodies receive a JSON response; XML request bodies receive an XML response. A successful update fires an internal dependent-updated event that may trigger downstream benefit enrollment processing. OAuth Scopes: employee:dependent.write, employee:dependent:ssn.write - [List Member Benefits](https://documentation.bamboohr.com/reference/list-member-benefits.md): Returns a paginated list of benefit enrollment records for all members (employees and dependents) in the company for a given calendar year. Each record represents one member and includes the plans they held and the date ranges during which they held each enrollment status. Dependents appear alongside their subscribing employee via subscriberId. Use "List Company Benefits" to get valid planId values. OAuth Scopes: benefit - [Get Changed Employee IDs](https://documentation.bamboohr.com/reference/get-changed-employee-ids.md): Returns a list of employee IDs that have changed since the given timestamp. This allows for efficient syncing of employee data — rather than downloading all employees, only those that have changed are returned. A change in ANY individual field in the employee record, as well as any change to the employment status, job info, or compensation tables, will cause that employee to be returned. Each entry includes the employee ID, the type of change (Inserted, Updated, or Deleted), and the last-changed timestamp. OAuth Scopes: public.integration, public.user - [Get Changed Employee Table Data](https://documentation.bamboohr.com/reference/get-changed-employee-table-data.md): Returns table data for employees that have changed since the given timestamp. This is an optimization to avoid downloading all table data for all employees. It operates on an employee-last-changed-timestamp, which means that a change in ANY field in the employee record will cause ALL of that employee's table rows to show up via this API. The response includes the table rows grouped by employee ID with their last-changed timestamps. OAuth Scopes: employee, employee:assets, employee:compensation, employee:custom_fields, employee:custom_fields_encrypted, employee:education, employee:emergency_contacts, employee:job, sensitive_employee:creditcards - [Delete Company File](https://documentation.bamboohr.com/reference/delete-company-file.md): Permanently removes a company file and its associated storage. The company must have the Files tool enabled; otherwise the file is treated as not found. Read-only file types (e.g. e-signature templates) are silently skipped. No response body is returned on success. Use "Company Files > List Company Files" to obtain file IDs. OAuth Scopes: company_file.write - [Get Company File](https://documentation.bamboohr.com/reference/get-company-file.md): Downloads a company file by its ID. The response body is the raw file content. The `Content-Type` header reflects the file's MIME type and `Content-Disposition` is set to `attachment` with the original filename. Access is permitted if the file or its category is shared with employees, shared directly with the requesting user, or the user has view permission on the file section. OAuth Scopes: company_file - [Get Company Files and Categories](https://documentation.bamboohr.com/reference/list-company-files.md): Returns all company file categories and the files within each category that the requesting user is permitted to see. The response format is determined by the `Accept` request header: send `application/json` for JSON or omit it (or send `application/xml`) for XML. OAuth Scopes: company_file - [Update Company File](https://documentation.bamboohr.com/reference/update-company-file.md): Updates metadata for an existing company file. Supports renaming the file, moving it to a different category, and toggling employee visibility. Accepts JSON or XML. Only fields included in the request body are updated. OAuth Scopes: company_file.write - [Upload Company File](https://documentation.bamboohr.com/reference/upload-company-file.md): Uploads a file to a company file category. The request must be a `multipart/form-data` POST. On success, a `Location` header is returned with the URL of the newly created file resource. The file must be under 20MB and use a supported extension. Uploading to read-only categories is not permitted. Uploading to implementation categories is not permitted on companies that have completed implementation. OAuth Scopes: company_file.write - [Create Company File Category](https://documentation.bamboohr.com/reference/create-company-file-category.md): Creates one or more company file categories. Accepts a JSON array of category name strings or an equivalent XML document. An empty payload returns 200 without creating anything. Returns 400 if a name is empty or already exists, 403 if the caller lacks permission or the name is reserved, and 500 on an internal error. OAuth Scopes: company_file.write - [Get Company Profile Integrations](https://documentation.bamboohr.com/reference/get-company-profile-integrations.md): Returns the list of integration feature identifiers currently enabled for the company. Each identifier is an uppercase string key (e.g. `BAMBOOHR_PAYROLL`, `TIME_TRACKING`, `E_SIGNATURES`) representing a product feature or integration that has been activated on the account. The list reflects the company's current subscription and configuration. OAuth Scopes: company:details - [Update company information (phone, address, legal name)](https://documentation.bamboohr.com/reference/patch-company-profile-company-information.md): Updates legal name, phone, and/or address for the company (application/merge-patch+json). String fields must be JSON strings (not numbers). Response matches GET /api/v1/company-profile-data. OAuth Scopes: company:details.write - [Update company display name](https://documentation.bamboohr.com/reference/put-company-profile-display-name.md): Updates the company display name. Requires admin permissions and the company:details.write OAuth scope. The display name must be a non-empty string with a maximum length of 255 characters. Upon successful update, the system logs the change and broadcasts an event to notify other services. OAuth Scopes: company:details.write - [Get company equity settings](https://documentation.bamboohr.com/reference/db49fb29f9f04d59afad7c01ce860418.md): Retrieves company-level equity settings including calculation type, valuation, shares, pricing, and vesting-related configuration. OAuth Scopes: equity - [Update company equity settings](https://documentation.bamboohr.com/reference/c5880b509783cd9d7fce9ddf5d6af1be.md): Updates company-level equity settings including calculation type, valuation, shares, pricing, and vesting-related configuration. OAuth Scopes: equity.write - [List available compensation tools](https://documentation.bamboohr.com/reference/9f398e2652ea47a6dc5121ce5184222a.md): Returns the list of available compensation tools/settings for the company, including Levels & Bands, Compensation Benchmarking, Compensation Planning, and Total Rewards. Also returns upsell information if applicable. OAuth Scopes: compensation_tools - [List Compensation Benchmarks](https://documentation.bamboohr.com/reference/list-compensation-benchmarks.md): Returns every job/location pair the company tracks for compensation benchmarking. Each entry includes job and location identifiers, the benchmarks attached to that pair, the employees currently assigned to that job and location, and the company's configured internal pay band if one exists. Use the returned `jobDetails.id` and `locationDetails.id` values as the `jobId` and `locationId` inputs for `GET /api/v1/compensation/benchmarks/details`. Top-level `dismiss*Banner` fields reflect UI banner state and are not part of the benchmark data contract. OAuth Scopes: compensation_benchmarks - [Get Compensation Benchmark Details](https://documentation.bamboohr.com/reference/get-compensation-benchmark-details.md): Returns detailed benchmark data for a single company job title, optionally scoped to a specific location. The response includes the company pay range derived from current employees, the internal pay band configured for the job (if any), Mercer benchmark details when a Mercer benchmark is linked, every saved benchmark for the job/location (empty when none exist), and per-employee salary and compensation stats. Use `GET /api/v1/compensation/benchmarks` to find valid `jobId` and `locationId` values. OAuth Scopes: compensation_benchmarks - [Export Compensation Benchmark Details](https://documentation.bamboohr.com/reference/export-compensation-benchmark-details.md): Returns a CSV export of the compensation benchmark detail view for a single job, optionally scoped to a specific location. Rows include employee-level data (name, location, annualized pay, compa-ratio, range penetration, years of experience) alongside the company's internal pay band for the job. Use `GET /api/v1/compensation/benchmarks` to find valid `jobId` and `locationId` values. When `locationId` is omitted, the export aggregates across all locations for the job. OAuth Scopes: compensation_benchmarks - [Create Compensation Benchmark](https://documentation.bamboohr.com/reference/create-compensation-benchmark.md): Creates a new compensation benchmark for a specific company job title (and optionally a specific job location). The `jobTitleId` value comes from `GET /api/v1/compensation/benchmarks` (`jobDetails.id`) or the company's job-title list. When `jobLocationId` is omitted, the benchmark applies to the job title at any location. Returns the saved benchmark wrapped in `savedBenchmark` along with a status `message`. OAuth Scopes: compensation_benchmarks.write - [Import Compensation Benchmarks From CSV](https://documentation.bamboohr.com/reference/import-compensation-benchmarks.md): Parses a CSV of compensation benchmarks uploaded as multipart/form-data and returns the parsed rows together with a suggested column-to-field mapping. The response is a preview payload — callers must follow up with the publish step in the UI/API to persist benchmarks. Returns `400` when no `file` part is provided and `422` when the CSV is malformed. OAuth Scopes: compensation_benchmarks.write - [Update Compensation Benchmark](https://documentation.bamboohr.com/reference/update-compensation-benchmark.md): Updates an existing compensation benchmark identified by `id`. The `id` of an existing benchmark can be obtained from `GET /api/v1/compensation/benchmarks/details`. Request fields that are omitted or `null` are cleared on the stored benchmark; callers should send the full benchmark payload to preserve values. On success, returns the saved benchmark row wrapped in `savedBenchmark` together with a status `message`. OAuth Scopes: compensation_benchmarks.write - [Delete Compensation Benchmark](https://documentation.bamboohr.com/reference/delete-compensation-benchmark.md): Permanently removes the compensation benchmark identified by `id`. The `id` is a numeric benchmark row identifier; non-numeric values are rejected by the handler. Valid values are returned by `GET /api/v1/compensation/benchmarks/details` under `benchmarkValues[].id` and by the create/update endpoints as `savedBenchmark.id`. OAuth Scopes: compensation_benchmarks.write - [List Compensation Benchmark Sources](https://documentation.bamboohr.com/reference/list-compensation-benchmark-sources.md): Returns every enabled benchmark source configured for the company. Each source identifies where a benchmark value came from (for example, a specific survey provider) and includes a display color and the count of benchmarks currently attached to that source. Use the returned `id` as the `sourceId` input when creating or updating a benchmark. OAuth Scopes: compensation_benchmarks - [Create Compensation Benchmark Source](https://documentation.bamboohr.com/reference/create-compensation-benchmark-source.md): Creates a new benchmark source the company can attach to its benchmarks. The `name` must be non-empty; the reserved name `mercer` (case-insensitive) is rejected because Mercer sources are managed separately. Returns the new source's ID and the trimmed name. OAuth Scopes: compensation_benchmarks.write - [Update Compensation Benchmark Sources](https://documentation.bamboohr.com/reference/update-compensation-benchmark-sources.md): Updates the name and sort order of one or more existing benchmark sources in a single call. Every item in `benchmarkSources` must include a non-empty `id` and `name`; any item with the reserved name `mercer` (case-insensitive) is rejected because Mercer sources are managed separately. Use `GET /api/v1/compensation/benchmarks/sources` to obtain the current `id` values. Returns `{ "result": "success" }` when all updates are applied. OAuth Scopes: compensation_benchmarks.write - [Delete Compensation Benchmark Source](https://documentation.bamboohr.com/reference/delete-compensation-benchmark-source.md): Deletes a benchmark source together with all benchmarks currently attached to it. The source `id` is taken from the request body. Use `GET /api/v1/compensation/benchmarks/sources` to look up the `id` of the source to delete. Returns `{ "result": "success" }` when the source is removed. OAuth Scopes: compensation_benchmarks.write - [List compensation planning cycles](https://documentation.bamboohr.com/reference/b65f246186b41a9783a9397c11c703b4.md): List all compensation planning cycles for the company, including status and employee counts. OAuth Scopes: planning_cycles - [Get compensation planning cycle details](https://documentation.bamboohr.com/reference/5c2b55158b0950b1e9211655666645b6.md): Get compensation planning cycle details and currency settings for a cycle. OAuth Scopes: planning_cycles - [Get compensation planning cycle summary](https://documentation.bamboohr.com/reference/9bc279d788f6e86b4cd8b2e0d3de91b1.md): Get compensation planning cycle summary (progress, stats). OAuth Scopes: planning_cycles - [List employees in compensation planning cycle](https://documentation.bamboohr.com/reference/a6b8da1348a3151fe95adc03aaf64447.md): List employees in the compensation planning cycle (picker data: company roster and membership). OAuth Scopes: planning_cycles - [Get compensation planning cycle budgets](https://documentation.bamboohr.com/reference/7efceaee2c010f88244dd01ee81e6e7b.md): Get budget guidelines and breakdown for the compensation planning cycle. OAuth Scopes: planning_cycles - [Get compensation planning approval flows](https://documentation.bamboohr.com/reference/4e886b18264480611f380805301c49c4.md): Get approval flows for the compensation planning cycle (grouped by department by default). OAuth Scopes: planning_cycles - [List compensation planning cycle admins](https://documentation.bamboohr.com/reference/b3c51254de6918637a971fe4af382a53.md): List compensation planning cycle admins. OAuth Scopes: planning_cycles - [Get change communication letter details](https://documentation.bamboohr.com/reference/d6987e300672a00c7cfe59afebb64156.md): Get change communication letter details for the compensation planning cycle. A cycle's letter is either a single message or assembled from ordered sections, and `hasSections` says which. When `hasSections` is false, `changeCommunicationMessageText` is the stored single message. When it is true, that field is the assembled letter instead: the bodies of the sections this cycle can use, joined in stored order. Sections describing a compensation type the cycle does not run are left out, as are sections with no visible content. It is neither everything stored nor any one employee's letter. A section for a compensation type this cycle does not run reaches nobody, so it is excluded; but a recipient also reads only the sections their own award qualifies them for, so a cycle running more than one compensation type assembles more than any single employee is sent. `sections` reports every stored section regardless, with `isActive` marking the ones that reach anyone, and is the precise read. `sections` is read-only; the PUT to `change_comm/template` cannot write it and returns 409 on a cycle that has sections. OAuth Scopes: planning_cycles - [Get compensation planning cycle worksheet](https://documentation.bamboohr.com/reference/329acecaa6df729733d0752aa9f6b204.md): Get compensation planning worksheet details for the cycle (recommendations, approvals, or overview context). Omit `type` to use the default view for the current user. OAuth Scopes: planning_cycles - [Export compensation planning cycle worksheet to CSV](https://documentation.bamboohr.com/reference/593d5bff120edf2a218a92022a682728.md): Download compensation planning worksheet data as a UTF-8 CSV (Excel-friendly BOM). Same data scope as GET worksheet; omit `type` for the default view. OAuth Scopes: planning_cycles - [Create compensation planning cycle](https://documentation.bamboohr.com/reference/e2ac4e1535f296cb8901f209e04caa83.md): Create a new compensation planning cycle with default settings. OAuth Scopes: planning_cycles.write - [Update compensation planning cycle](https://documentation.bamboohr.com/reference/100b0cf8c5207b35697ff10370fd5fe1.md): Update compensation planning cycle details and currency settings. OAuth Scopes: planning_cycles.write - [Delete compensation planning cycle](https://documentation.bamboohr.com/reference/22ad75be25455279e2987c80851af5fc.md): Delete a compensation planning cycle. OAuth Scopes: planning_cycles.write - [Add employees to cycle](https://documentation.bamboohr.com/reference/3958585c861325ea7a2cd30a8c74f042.md): Add employees to a compensation planning cycle. OAuth Scopes: planning_cycles.write - [Remove employees from cycle](https://documentation.bamboohr.com/reference/89a5068111ec499135c7d6e9a53d5a30.md): Remove employees from a compensation planning cycle. OAuth Scopes: planning_cycles.write - [Launch compensation planning cycle](https://documentation.bamboohr.com/reference/3a19f07aa737dc826ba43b9a1c1cd257.md): Launch a compensation planning cycle. Validates all cycle data and sets status to Live. OAuth Scopes: planning_cycles.write - [Complete compensation planning cycle](https://documentation.bamboohr.com/reference/f4b431363af6573af46750f32632e88b.md): Complete a compensation planning cycle and finalize employee compensation records. OAuth Scopes: planning_cycles.write - [Save budget guidelines](https://documentation.bamboohr.com/reference/dacd313af2106213fc4696175941ce65.md): Save budget guidelines for a compensation planning cycle. OAuth Scopes: planning_cycles.write - [Save budget breakdown](https://documentation.bamboohr.com/reference/1d64402ee192568adbd5e3179a91e6e2.md): Save budget breakdown for a compensation planning cycle. OAuth Scopes: planning_cycles.write - [Import budget breakdown](https://documentation.bamboohr.com/reference/1d1fc0f164cb51973a0206b8e2fb2d2d.md): Import budget breakdown from structured data and apply to allocations. OAuth Scopes: planning_cycles.write - [Add cycle admins](https://documentation.bamboohr.com/reference/c7c32ed5278ac67e2e518bf7484a75dc.md): Add one or more cycle admins by internal employee IDs. OAuth Scopes: planning_cycles.write - [Update approval flow](https://documentation.bamboohr.com/reference/cf87b8e09a001b6fb81dfce6c20ab9e3.md): Update an approval flow for a compensation planning cycle. Allows modifying recommenders and approvers for a specific approval flow template. OAuth Scopes: planning_cycles.write - [Set final approver](https://documentation.bamboohr.com/reference/5c4aab35a34f5760ec044104b5232bf5.md): Set or update the final approver for all approval flows in a cycle. OAuth Scopes: planning_cycles.write - [Remove from approval flow](https://documentation.bamboohr.com/reference/b1e467e0eef72350eec61fcfeaf4e19d.md): Remove an employee from all approval chains for a specific cycle. OAuth Scopes: planning_cycles.write - [Save recommendations](https://documentation.bamboohr.com/reference/f3883a522dadbe9e11b34f8b656e3adb.md): Save compensation recommendations for an employee in a cycle. OAuth Scopes: planning_cycles.write - [Send recommendations to next stage](https://documentation.bamboohr.com/reference/a05b6d5f564f805d688ff2c1e37c3990.md): Send recommendations to the next approval stage for a specific approval flow template. OAuth Scopes: planning_cycles.write - [Remove cycle admin](https://documentation.bamboohr.com/reference/ef7619b0ee4c8dc079aaea870cfbe81b.md): Remove a cycle admin by internal employee ID. Full account admins cannot be removed. OAuth Scopes: planning_cycles.write - [Save change comm template](https://documentation.bamboohr.com/reference/c79f9c5950f983e59d2626faa30c00a1.md): Save the change communication email template for a compensation planning cycle. Only applies to a cycle whose letter is a single message. On a cycle assembled from sections the letter body lives in those section rows, so this route returns 409 with `stringErrorCode` `CHANGE_COMM_SECTIONS_OWN_LETTER` and writes nothing at all, including the subject. Check `hasSections` on the `change_comm` GET to tell the two apart before writing. OAuth Scopes: planning_cycles.write - [List Custom Field Types](https://documentation.bamboohr.com/reference/list-custom-field-types.md): Returns an object containing the custom field types available when creating a custom field. OAuth Scopes: employee:custom_fields - [Get Custom Field](https://documentation.bamboohr.com/reference/get-custom-field.md): Returns one custom field definition. IDs are strings and each has a numeric `legacyId` companion for legacy integrations. Use this for a known custom field ID. For browsing active fields, use List Custom Fields (`list-custom-fields`) instead. For archived fields, use List Archived Custom Fields (`list-archived-custom-fields`) instead. OAuth Scopes: employee:custom_fields - [List Custom Fields](https://documentation.bamboohr.com/reference/list-custom-fields.md): Returns a paginated list of active custom fields. IDs are strings and each has a numeric `legacyId` companion for legacy integrations. Use this for active custom fields. For archived custom fields, use List Archived Custom Fields (`list-archived-custom-fields`) instead. OAuth Scopes: employee:custom_fields - [List Archived Custom Fields](https://documentation.bamboohr.com/reference/list-archived-custom-fields.md): Returns a paginated list of archived custom fields. IDs are strings and each has a numeric `legacyId` companion for legacy integrations. Use this for archived custom fields. For active custom fields, use List Custom Fields (`list-custom-fields`) instead. OAuth Scopes: employee:custom_fields - [Create Custom Field](https://documentation.bamboohr.com/reference/create-public-custom-field.md): Create a new custom field. OAuth Scopes: employee:custom_fields.write - [Edit Custom Field](https://documentation.bamboohr.com/reference/edit-public-custom-field.md): Edit an existing custom field. OAuth Scopes: employee:custom_fields.write - [Archive Custom Field](https://documentation.bamboohr.com/reference/archive-public-custom-field.md): Archive a custom field. OAuth Scopes: employee:custom_fields.write - [Unarchive Custom Fields](https://documentation.bamboohr.com/reference/unarchive-public-custom-fields.md): Unarchive custom fields. OAuth Scopes: employee:custom_fields.write - [List Custom Field List Values](https://documentation.bamboohr.com/reference/list-custom-field-list-values.md): Returns the dropdown options (and employee counts) for a list-type custom field. OAuth Scopes: employee:custom_fields - [Add Custom Field List Value](https://documentation.bamboohr.com/reference/add-custom-field-list-value.md): Adds one or more dropdown options to a list-type custom field. OAuth Scopes: employee:custom_fields.write - [Delete Custom Field List Value](https://documentation.bamboohr.com/reference/delete-custom-field-list-value.md): Deletes a dropdown option from a list-type custom field. OAuth Scopes: employee:custom_fields.write - [Edit Custom Field List Value](https://documentation.bamboohr.com/reference/edit-custom-field-list-value.md): Updates a dropdown option on a list-type custom field. OAuth Scopes: employee:custom_fields.write - [List Reports](https://documentation.bamboohr.com/reference/list-reports.md): Returns a paginated list of saved custom reports available in the account. Each report entry contains an `id` (integer) and a `name` (string). Pass a report's `id` to "Get Report by ID" to execute it and retrieve its data. Results default to page 1 with 500 records per page (maximum 1000). Out-of-range page numbers are clamped to the nearest valid page rather than returning an error. Invalid or zero values for `page` and `page_size` fall back to their defaults. The `pagination` object includes `total_records`, `current_page`, `total_pages`, and nullable `next_page`/`prev_page` links. When there is no next or previous page the corresponding value is `null`. OAuth Scopes: report - [Get Report by ID](https://documentation.bamboohr.com/reference/get-report-by-id.md): Executes a saved custom report and returns its data using the report's configured fields and filters. The `data` array contains employee record objects whose keys are determined by the fields selected when the report was created — each object is a flat key-value map where keys are field names (e.g. `firstName`, `status`, `hireDate`) and values are strings or `null`. The `aggregations` array is empty unless the report's underlying dataset configuration includes aggregation rules. Use "List Reports" to discover available report IDs. Response shape: Each element of `data` is a flat key-value object — field values are top-level keys (e.g. `row["firstName"]`). This differs from `get-data-from-dataset-v2`, where field values are nested under a `fields` key (e.g. `row["fields"]["firstName"]`). The top-level `fields` array lists the report's columns in the order the report shows them. Each entry's `name` is the key that column uses in every `data` record, and `label` is the column heading the customer sees in BambooHR — their own wording if they renamed the column. When `label` is `null`, display `name`. There is no schema-only response from this endpoint. The `pagination.total_records` value is the number of rows produced by the saved report after applying the report's configured filters, not necessarily the total number of employees in the account. Validate output before using in automated pipelines. Results default to page 1 with 500 records per page (maximum 1000). Out-of-range page numbers are clamped to the nearest valid page. Invalid or zero values for `page` and `page_size` fall back to their defaults. OAuth Scopes: report - [Get Legacy Report ID Map](https://documentation.bamboohr.com/reference/get-legacy-report-id-map.md): Returns a mapping from legacy custom report IDs to the new report IDs created by the report migration. Use this to update automations or integrations that still reference legacy report IDs. Pass a `newReportId` to Get Report by ID (`get-report-by-id`) to execute the migrated report. Administrators receive a mapping for every custom report in the account; other users receive mappings only for the custom reports they can access (reports they own or that are shared with them). Because the map for a non-administrator is silently limited to their accessible reports, a legacy ID that is absent may be outside that user's visibility rather than nonexistent in the account. Each entry pairs a `legacyReportId` with its `newReportId` and a `status`. When a report has not been migrated, `newReportId` is `null` and `status` is `notMigrated`; otherwise `newReportId` is the migrated report's ID and `status` is `migrated`. Returns an empty `mappings` array when the user has no accessible custom reports. OAuth Scopes: report - [Get Legacy Report Field Map](https://documentation.bamboohr.com/reference/get-legacy-report-field-map.md): Returns the mapping from the field identifiers the deprecated Reports > Get Company Report (`get-company-report`) endpoint emitted to the field names the Custom Reports and Datasets endpoints use today. Use it to repoint automations that still reference legacy identifiers — a field that came back as `location` before the report migration is `jobInformationLocation` afterward. To translate legacy report IDs rather than field identifiers, use Get Legacy Report ID Map (`get-legacy-report-id-map`) instead. The map covers the whole company and is not paginated. It is not scoped to the calling user's reports or field permissions, so a field appearing here does not mean the caller can read its data. A legacy identifier can map to more than one field. The legacy report emitted an amount column and its currency-code column under a single identifier, so `payRate` maps to both `compensationPayRate` and `compensationPayRateCurrencyCode`. The identifier alone cannot tell you which one a given report used, so compare `type` or `fieldLabel` against the column you are replacing. An identifier that is absent from the response has no equivalent field at all — that column was lost in the migration, and there is nothing to point an automation at. Some legacy fields encoded a category in the field itself: a legacy "Vacation" time off field returned only vacation hours. These map to a general field plus a `qualifier`, and you have to apply it. If you request the mapped `fieldName` on its own, you get every category rather than the one the legacy field returned. The operator differs by field — time off policy qualifiers use `equal`, while time off category, benefit plan, and training qualifiers use `includes` and expect the value wrapped in an array. To reproduce a legacy "Safety Training" due-date column, request `trainingDueDate` and filter `{"field": "trainingName", "operator": "includes", "value": ["Safety Training"]}`. Qualifier values are legacy names carried over without validation, so a category, plan, or training that has since been renamed or removed will produce a qualifier that matches nothing. Check the value against Datasets > Get Field Options (v1.2) (`get-field-options-v1_2`) before repointing an automation. The map is cached per account for up to an hour, so a field that was just added or renamed may not appear immediately. OAuth Scopes: report - [List Datasets (v1)](https://documentation.bamboohr.com/reference/list-datasets-v1.md): Deprecated. Use "List Datasets (v1.2)" instead. Returns the catalog of datasets available for querying via the Datasets API. Each entry includes a machine-readable `name` (used as the `datasetName` path parameter in "Get Fields from Dataset (v1.2)" and "Get Data from Dataset") and a human-readable `label`. Use this endpoint to discover which datasets the current account has access to before building queries. The response includes `Deprecation` and `Link` headers pointing to the v1.2 successor endpoint. OAuth Scopes: report - [Get Fields from Dataset (v1)](https://documentation.bamboohr.com/reference/get-fields-from-dataset-v1.md): Deprecated. Use "Get Fields from Dataset (v1.2)" instead. Returns a paginated list of field descriptors for the specified dataset. Each field includes its machine-readable `name`, human-readable `label`, `parentType`, `parentName`, and `entityName`. Use the returned field `name` values in the `fields` array when querying data via "Get Data from Dataset". Use "List Datasets (v1.2)" to discover valid dataset names. Pagination defaults to page 1 with 500 fields per page (maximum 1000). Out-of-range page numbers are clamped to the nearest valid page. The `next_page` and `prev_page` links in the pagination object are absolute URLs. Error responses (400, 403, 500) return plain-text bodies, not JSON. OAuth Scopes: report - [Get Field Options (v1)](https://documentation.bamboohr.com/reference/get-field-options-v1.md): Deprecated. Use "Get Field Options (v1.2)" instead. Returns the allowed values for one or more fields in a dataset, for use as filter values when querying data via "Get Data from Dataset". Pass field names in the `fields` array of the request body; the response is an object keyed by field name, where each value is an array of `{id, value}` option objects. Optionally supply `filters` to narrow the returned options (e.g. only options that exist for active employees) and `dependentFields` when one field's options depend on another field's selected value. Unrecognised field names may produce a `500` response with a plain-text body rather than structured JSON. OAuth Scopes: field - [Get Data from Dataset (v1)](https://documentation.bamboohr.com/reference/get-data-from-dataset-v1.md): Deprecated. Use "Get Data from Dataset (v2)" instead. Retrieves records from the specified dataset using the fields, filters, sorting, grouping, and aggregations supplied in the request body. Provide field names in the `fields` array; use "Get Fields from Dataset (v1.2)" to discover available names. The response contains paginated rows under `data`, an `aggregations` array (empty when none requested), and a `pagination` block with page navigation links. Results default to page 1 with 500 records per page (maximum 1000). Use "Get Field Options (v1.2)" to retrieve valid filter values. Filter fields do not need to appear in the `fields` list. Future hires have a status of `Inactive`; include it in your status filter to retrieve them. For `options`-type fields using `includes`/`does_not_include`, pass the filter value as an array enclosed in square brackets, for example `["Full-Time", "Part-Time"]`. When any requested fields are historical table fields, pass their entity names in `showHistory`; entity names are returned by "Get Fields from Dataset (v1.2)". Grouping (`groupBy`) currently supports only one field; when active, `data` becomes an object keyed by group value instead of an array. Sort priority follows the order of objects in `sortBy`. Aggregations accept a `defaultAggregation` applied to every field and/or per-field `overridingAggregations`. **Aggregations by field type:** text: count; date: count, min, max; int: count, min, max, sum, avg; bool: count; options: count; govIdText: count. **Filter operators by field type:** text: contains, does_not_contain, equal, not_equal, empty, not_empty; date: lt, lte, gt, gte (each accepts a YYYY-MM-DD date string or a relative object `{"duration": "N", "unit": "days|weeks|months|years"}` where duration is a number as a string — lt/lte are measured backward from today, gt/gte forward), equal, not_equal, empty, not_empty, last, next (relative object `{"duration": "N", "unit": "days|weeks|months|years"}`), range (object `{"start": "YYYY-MM-DD", "end": "YYYY-MM-DD"}`); int: equal, not_equal, gte, gt, lte, lt, empty, not_empty; bool: checked, not_checked; options: includes, does_not_include, empty, not_empty; govIdText: empty, not_empty. OAuth Scopes: report - [Get Data from Dataset (v2)](https://documentation.bamboohr.com/reference/get-data-from-dataset-v2.md): Queries the named dataset and returns the matching rows. The response is a JSON object with `data` (an array of row objects, each wrapping its values under a `fields` object whose keys match the requested field names), `links` (pagination navigation URLs; `prev` and/or `next`, omitted at boundaries), and `meta` (with `page`, `pageSize`, `totalPages`, `totalItems`). Use this for tabular reporting, custom field selection across many employees, and OData-style filtering against the full dataset field catalog. For multiple employees, use List Employees (`list-employees`). For the full set of fields on a single employee, use Get Employee (`get-employee`). Dataset access itself requires elevated permissions, so a caller without them receives `403` here regardless of which fields are requested. For information published in a coworker's company directory entry, such as job title, department, location, work contact details, or who they report to, use Get Employees Directory (`get-employees-directory`), which is governed by directory sharing settings rather than by per-employee record permissions and is available when directory or org-chart access is shared with the caller's access level. Discover valid `datasetName` values via List Datasets (v1.2) (`list-datasets-v1_2`). Discover valid field names for a dataset via Get Fields from Dataset (v1.2) (`get-fields-from-dataset-v1_2`); the field set is dataset-specific. Field-name vocabulary differs from the dedicated employee endpoints. The `employee` dataset uses fully qualified names such as `jobInformationJobTitle`, `jobInformationDepartment`, `jobInformationReportsTo`, and `employmentStatus`, where the employee endpoints use endpoint-specific shorter names — for example `jobTitleName` on List Employees (`list-employees`), and `jobTitle`, `department`, `supervisor`, and `workEmail` on Get Employee (`get-employee`). Identifier and contact fields also differ: the dataset's internal employee identifier is `eeid` (`get-employee` returns the same value as `id`, and `list-employees` as `employeeId`); the dataset's work-email field is `email` (`get-employee` uses `workEmail`). The dataset also exposes `employeeNumber` — the editable Employee # value, not the internal employee ID. Do not pass `employeeNumber` to employee ID inputs such as `filter[ids]` or `{id}` path parameters; it may fail with `404` or resolve to a different employee whose internal employee ID happens to match. Always source field names from Get Fields from Dataset (v1.2) (`get-fields-from-dataset-v1_2`) — names from the employee endpoints will not necessarily resolve here. For routine `employee` dataset lookups, a useful starter field set is: `firstName`, `lastName`, `eeid` (internal employee ID), `employeeNumber` (Employee # / editable employee number), `email` (work email), `mobilePhone`, `hireDate`, `employmentStatus`, `jobInformationJobTitle`, `jobInformationDepartment`, `jobInformationLocation`, `jobInformationReportsTo` (supervisor's name), and `supervisorEid` (supervisor's `eeid`). The full catalog (over 450 fields) is discoverable via Get Fields from Dataset (v1.2) (`get-fields-from-dataset-v1_2`) — use it when you need anything beyond this starter set. Filter expressions use OData-style syntax with comparison operators `eq`, `ne`, `lt`, `le`, `gt`, `ge`, the list-membership operator `in (...)`, and logical operators `and` / `or`. The parser does not support `not in`; use `ne` for the inverse of `eq`, and on options-type fields `ne` already applies set-membership negation under the hood. A single filter expression may use `and` or `or`, but not both; mixed logical expressions return `422` with code `INVALID_FILTER`. Operator support varies by field type: `eq` / `ne` work on text, numeric, date, and options-type (single-select enum) fields like `status`, `employmentStatus`, and `jobInformationDepartment`; ordering operators `lt`, `le`, `gt`, `ge` are supported on numeric and date fields. The list operator `in` is the natural fit on options-type fields (e.g. `status in ('Active','Inactive')`), and is also accepted on text, numeric, and date fields when used with a single value (e.g. `firstName in ('Ashley')`, equivalent to `firstName eq 'Ashley'`); multi-value `in` on non-options fields returns `422`. To check a field's type, see the `type` value returned by Get Fields from Dataset (v1.2). Filter fields do not need to appear in the `fields` array; rows are filtered server-side. String literals in filter expressions are wrapped in single quotes, e.g. `firstName eq 'Ashley'` or `status in ('Active','Inactive')`. On date fields, the ordering operators also accept a relative-date duration literal in OData v4 / ISO 8601 form, e.g. `hireDate ge duration'P30D'`. The literal resolves against today at query time: with `lt` / `le` it resolves to today minus the duration, with `gt` / `ge` to today plus the duration (so `terminationDate lt duration'P6M'` matches dates before six months ago, and `hireDate ge duration'P30D'` matches dates from 30 days in the future onward). A negative duration reverses the direction — `hireDate ge duration'-P30D'` matches hire dates from 30 days ago onward (i.e. anyone hired in the last 30 days), including any future-dated hires. Exactly one date component is required — `PY` (years), `PM` (months), `PW` (weeks), or `PD` (days). Combined components (`P1Y6M`), time components (`PT12H`), and duration literals with `eq` / `ne` / `in` return `422` with code `INVALID_FILTER`. `orderBy` is a comma-separated list of ` ` rules. Every field used in `orderBy` must also appear in the `fields` array; omitting it returns a `400` with code `UE-1001`. `orderBy` is optional; with no `orderBy` the row order is unspecified. Field-level access is enforced server-side based on the authenticated caller's permissions and OAuth scopes. When a caller lacks permission to read a requested field, the field is still returned in each row with an empty value, and its canonical name is listed in that row's `_restrictedFields` array (e.g., `_restrictedFields: ["employee_employeeNumber"]`) — the request is not rejected, and other requested fields still come back. This differs from Get Employee (`get-employee`), which silently omits unauthorized fields with no marker, leaving an absent field ambiguous between "not requested" and "not permitted". Callers without dataset-level access receive `403`, and a dataset the caller cannot see at all returns `404` ("not accessible" rather than disclosing existence). Bad field names in `fields` or `filter` return `400` with `code: INVALID_ARGUMENT` and the offending name in the `detail` field (e.g., `"Invalid field name: employee_workEmail"`). The reported name carries the internal `_` prefix; the actual misspelling is the unprefixed form. Confirm spelling against Get Fields from Dataset (v1.2) (`get-fields-from-dataset-v1_2`). Note: the field name appears in `detail` (singular); the `details` field (plural) remains empty in this error class. (Bad names in `orderBy` hit the must-be-in-`fields` check above first and return `UE-1001` rather than `INVALID_ARGUMENT`.) Pagination: `page` defaults to `1` and `pageSize` defaults to `100` (maximum `1000`). `meta.totalItems` is the count of rows matching the query across all pages, `meta.totalPages` is `ceil(totalItems / pageSize)`, and `data` contains at most `pageSize` rows for the requested page. `links.next` is present when more pages exist; `links.prev` is present when not on the first page. Errors follow RFC 7807 (`application/problem+json`). Note: Compared to Get Data from Dataset (v1) (`get-data-from-dataset-v1`), this version uses `filter` and `orderBy` request fields instead of the legacy `filters` and `sortBy` structures, moves pagination inputs to body fields (`page`, `pageSize`) instead of query parameters, returns pagination in `links` / `meta` objects instead of a legacy `pagination` object, and returns RFC 7807 compliant error responses with an `X-Request-ID` correlation header. OAuth Scopes: report - [List Datasets (v1.2)](https://documentation.bamboohr.com/reference/list-datasets-v1_2.md): Returns the catalog of datasets available for querying via the Datasets API. Each entry includes a machine-readable `name` (used as the `datasetName` path parameter in "Get Fields from Dataset (v1.2)" and "Get Data from Dataset (v2)") and a human-readable `label`. Use this endpoint to discover which datasets the current account has access to before building queries. Datasets are queryable reporting datasets for the Datasets API. They are not the same as saved custom reports (`list-reports`), employee tabular table aliases (`list-tabular-fields`), or account list-field definitions (`list-list-fields`). Note: Compared to "List Datasets (v1)", this version returns RFC 7807 `application/problem+json` error responses and includes an `X-Request-ID` correlation header. OAuth Scopes: report - [Get Fields from Dataset (v1.2)](https://documentation.bamboohr.com/reference/get-fields-from-dataset-v1_2.md): Returns a paginated list of field descriptors for the specified dataset. Each field includes its machine-readable `name`, human-readable `label`, parent section type and name, and `entityName`. Use the returned field `name` values in the `fields` array when querying data via "Get Data from Dataset (v2)". Use "List Datasets (v1.2)" to discover valid `datasetName` values. Pagination defaults to page 1 with 500 fields per page (maximum 1000). Out-of-range page numbers are clamped to the nearest valid page. Some datasets, especially `employee`, may return hundreds of fields. This endpoint does not support filtering by parent/entity/type; retrieve all pages and group client-side. The `employee` dataset field names are fully qualified with their section prefix and differ from the field names used by `list-employees` and `get-employee`. Do not assume a field name from one endpoint works in the other. For fields whose type is `list`, `multilist`, or another option-backed type, the field `id` can be matched to `fieldId` from `list-list-fields` to retrieve the account-level option list. Note: Compared to "Get Fields from Dataset (v1)", this version returns RFC 7807 `application/problem+json` error responses and includes an `X-Request-ID` correlation header. OAuth Scopes: report - [Get Field Options (v1.2)](https://documentation.bamboohr.com/reference/get-field-options-v1_2.md): Returns the allowed values for one or more fields in a dataset, for use as filter values when querying data via "Get Data from Dataset (v2)". Pass field names in the `fields` array of the request body; the response is an object keyed by field name, where each value is an array of `{id, value}` option objects. Optionally supply `filters` to narrow the returned options (e.g. only options that exist for active employees) and `dependentFields` when one field's options depend on another field's selected value. Use "Get Fields from Dataset (v1.2)" to discover valid field names for a dataset. Use this endpoint when you already have dataset field names from `get-fields-from-dataset-v1_2` and need valid filter/display options for those specific dataset fields. It is dataset-scoped: field names must be dataset field name values such as `jobInformationDepartment`, not account list aliases such as `department`. Note: Compared to "Get Field Options (v1)", error responses (`400`, `403`) use RFC 7807 `application/problem+json` format. Unrecognised field names may produce a `500` response with a plain-text body rather than structured JSON. OAuth Scopes: field - [Delete Employee File](https://documentation.bamboohr.com/reference/delete-employee-file.md): Permanently deletes an employee file. This action cannot be undone and removes the file from storage. The special employee ID of 0 resolves to the employee associated with the authenticated caller. Returns 200 even if the file was already deleted (idempotent). Returns 403 if the caller lacks permission or the file belongs to a BambooPayroll-managed section. Returns 404 if the file does not exist for the specified employee or the Files tool is not enabled for the company. Use 'List Employee Files' to obtain file IDs. OAuth Scopes: employee:file.write - [Get Employee File](https://documentation.bamboohr.com/reference/get-employee-file.md): Downloads the binary content of an employee file as an attachment. The response Content-Type header reflects the file's stored MIME type (e.g. application/pdf) and includes a Content-Disposition header with the original filename. The special employee ID of 0 resolves to the employee associated with the authenticated caller. Use "List Employee Files" to discover file IDs and their categories for a given employee. Archived or soft-deleted files are excluded and return 404. OAuth Scopes: employee:file - [List Employee Files](https://documentation.bamboohr.com/reference/list-employee-files.md): Lists the file categories and files visible to the caller for the specified employee. This is a metadata listing (names, sizes, permissions); to download a file's content use `get-employee-file`. The response format is controlled by the Accept header: send `application/json` for JSON or omit/send anything else for XML. Only categories and files the caller is permitted to see are included; employees viewing their own profile also see files shared with them. Returns 404 when the employee has no accessible categories. OAuth Scopes: employee:file - [Update Employee File](https://documentation.bamboohr.com/reference/update-employee-file.md): Updates metadata for an existing employee file. Supports renaming the file, moving it to a different category, and toggling employee visibility. Accepts JSON or XML; only fields present in the request body are updated. An empty XML document no-ops successfully, while an empty JSON body returns 400. The `categoryId` field is silently ignored when the caller authenticated as the file creator but lacks full file permissions. Moving a file to a new category requires view/edit access to both the current and target category. Returns 403 if the file belongs to a read-only file section. Use 'List Employee Files' to obtain file IDs and category IDs. OAuth Scopes: employee:file.write - [Upload Employee File](https://documentation.bamboohr.com/reference/upload-employee-file.md): Uploads a file to an employee's file section. The request must be a `multipart/form-data` POST. On success, a `Location` header is returned with the URL of the newly created file resource. The file must be under 20MB and use a supported extension. Pass `0` as the employee ID to use the employee associated with the authenticated caller. Employees may upload to their own folder if the company has employee document uploads enabled. OAuth Scopes: employee:file.write - [Create Employee File Category](https://documentation.bamboohr.com/reference/create-employee-file-category.md): Creates one or more employee file categories (not company file categories). The request body is a JSON array of category name strings or an equivalent XML document with `` elements. Each name must be non-empty and unique among existing employee file categories. An empty array returns 200 without creating anything. On success, returns 201 with no body. The admin user group is automatically granted edit permission on each new category. OAuth Scopes: employee:file.write - [Get Employee Table Data](https://documentation.bamboohr.com/reference/get-employee-table-data.md): Returns all rows for a given employee and table combination. The result is not sorted in any particular order. Each row contains the fields defined for that table, subject to field-level permission checks. Fields the caller does not have access to are omitted from the response. OAuth Scopes: employee, employee:assets, employee:compensation, employee:custom_fields, employee:custom_fields_encrypted, employee:education, employee:emergency_contacts, employee:job, employee:job.write, sensitive_employee:creditcards - [Delete Employee Table Row](https://documentation.bamboohr.com/reference/delete-employee-table-row.md): Deletes a specific row from an employee's tabular data. The table name identifies which tabular dataset to target (e.g., jobInfo, compensation, customTabularField). Returns `success: true` if the row was deleted, or `success: false` with an error message if the row was not found or could not be deleted. Deletion will fail with a 409 if the row has pending approval changes, or a 412 if the row is tied to an active pay schedule. Per-table field schemas are available as named OpenAPI components (e.g., `JobInfoTableRowRequest`, `CompensationTableRowRequest`). See the components/schemas section of this spec for the full list. OAuth Scopes: employee.write, employee:assets.write, employee:compensation.write, employee:custom_fields.write, employee:custom_fields_encrypted.write, employee:education.write, employee:emergency_contacts.write, employee:job.write, sensitive_employee:creditcards.write - [Update Table Row (v1)](https://documentation.bamboohr.com/reference/update-table-row-v1.md): Deprecated. Use **Update Table Row (v1.1)** instead (`update-table-row-v1_1`). Update an existing row in the specified employee table by submitting field name/value pairs for the fields to change in JSON or XML. OAuth Scopes: employee.write, employee:assets.write, employee:compensation.write, employee:custom_fields.write, employee:custom_fields_encrypted.write, employee:education.write, employee:emergency_contacts.write, employee:job.write, sensitive_employee:creditcards.write - [Create Table Row (v1)](https://documentation.bamboohr.com/reference/create-table-row-v1.md): Deprecated. Use **Create Table Row (v1.1)** instead (`create-table-row-v1_1`). Add a new row to the specified employee table by submitting field name/value pairs in JSON or XML. Use this endpoint to append records to tabular employee data such as job information or compensation history. OAuth Scopes: employee, employee.write, employee:assets.write, employee:compensation.write, employee:custom_fields.write, employee:custom_fields_encrypted.write, employee:education.write, employee:emergency_contacts.write, employee:job, employee:job.write, sensitive_employee:creditcards.write - [Update Table Row (v1.1)](https://documentation.bamboohr.com/reference/update-table-row-v1_1.md): Update an existing row in the specified employee table using the v1.1 table-row update endpoint. Submit the field changes in JSON or XML. This version is largely compatible with v1 and is intended for the same tabular employee data use cases. OAuth Scopes: employee.write, employee:assets.write, employee:compensation.write, employee:custom_fields.write, employee:custom_fields_encrypted.write, employee:education.write, employee:emergency_contacts.write, employee:job.write, sensitive_employee:creditcards.write - [Create Table Row (v1.1)](https://documentation.bamboohr.com/reference/create-table-row-v1_1.md): Add a new row to the specified employee table using the v1.1 table-row creation endpoint. Submit the new row in JSON or XML. This version is largely compatible with v1 and supports the same tabular employee data use cases. OAuth Scopes: employee.write, employee:assets.write, employee:compensation.write, employee:custom_fields.write, employee:custom_fields_encrypted.write, employee:education.write, employee:emergency_contacts.write, employee:job.write, sensitive_employee:creditcards.write - [List employee verification records for an employee](https://documentation.bamboohr.com/reference/list-employee-verifications-by-employee.md): Returns every employee verification row for the given employee (including archived), newest first. Intended for admin-level API consumers with the employee verifications OAuth scope; callers must have onboarding access and permission to view the employee (same rules as the active-verification employee verification API), except when the OAuth context is the employee themselves. OAuth Scopes: employee_verifications - [Get employee verification integration status](https://documentation.bamboohr.com/reference/get-employee-verification-integration.md): Returns the install state and partner metadata for the company's employee verification integration. Scoped to the authenticated OAuth company context. The `enabled` flag reflects whether the partner app is installed and usable; `integrationType` identifies the configured verification partner. OAuth Scopes: employee_verifications - [Enable or disable the employee verification integration](https://documentation.bamboohr.com/reference/update-employee-verification-integration.md): Enables or disables the company's employee verification integration. Enabling installs the configured partner app and schedules the daily sync; the company must have a valid US work location before enabling, otherwise a 400 is returned. Disabling tears down the partner app. The call is idempotent: a request to enable when already enabled (or disable when already disabled) returns 200 with the current state. Requires the employee_verifications.write OAuth scope, intended for admin-level API consumers. OAuth Scopes: employee_verifications.write - [Send employee verification lifecycle email by user and email type](https://documentation.bamboohr.com/reference/send-employee-verification-lifecycle-email-by-user.md): Accepts a Bamboo `userId` (path) and an `emailType` (body) and queues the corresponding employee verification lifecycle email—the same templates as the in-app auth listener (`signup_survey` after signup, `app_installed` after the integration app is installed). Delivered to the company owner contact with template context for that user id. Not an employee I-9 reminder. Requires the employee verification integration enabled, onboarding edit access, and `employee_verifications.write`. OAuth Scopes: employee_verifications.write - [Update an employee verification record](https://documentation.bamboohr.com/reference/update-employee-verification.md): Partial update of a single employee verification row. Any field omitted from the request body is left unchanged. Returns 404 when the verification id does not exist or does not belong to {employeeId}. Most verification updates flow in via partner webhooks; this endpoint exists for admin-level integrations that need to correct or annotate a record out-of-band, and requires onboarding view-and-edit permission on the employee. OAuth Scopes: employee_verifications.write - [Get Company Information](https://documentation.bamboohr.com/reference/get-company-information.md): Returns basic profile information for the company, including its legal name, display name, primary address, and contact phone number. For companies using BambooHR Payroll, the legal name and address are sourced from the active payroll client metadata; for all other companies, the data comes from the company's account settings. This information is treated as non-sensitive, publicly-derivable business information (comparable to what's on public business registries or a paycheck) and is available to any authenticated caller holding the company:info scope, regardless of admin status. OAuth Scopes: company:info - [Get Employee](https://documentation.bamboohr.com/reference/get-employee.md): Returns a single employee record as a JSON object (or XML when `Accept: application/xml`). The `id` field is always present and is returned as a string; it is the internal employee ID — see the `id` and `employeeNumber` field documentation in the response schema for the distinction between the internal ID and the editable Employee # value. Pass the id `0` to read the authenticated caller's own record. **Requesting fields.** Every other field is included only when explicitly named in the `fields` query parameter. With no `fields` parameter, the response contains only `id` — there is no implicit default field set. Field names come from List Fields (`list-fields`), which also exposes custom-field aliases usable here. The maximum number of fields per request is 400. **Field-name vocabulary.** The names used here differ from the `employee` dataset (queried via Get Data from Dataset (v2) (`get-data-from-dataset-v2`)): this endpoint uses short names (`workEmail`, `jobTitle`, `department`, `supervisor`) where the dataset uses qualified names (`email`, `jobInformationJobTitle`, `jobInformationDepartment`, `jobInformationReportsTo`). **Effective-dated values.** By default only currently effective values from historical tables (job title, compensation, employment status, etc.) are returned; pass `onlyCurrent=false` to include future-dated values. **Permissions.** Field-level permissions are applied silently: any requested field the authenticated caller cannot view is omitted from the response with no marker — an absent field may indicate either that it was not requested or that the caller lacks permission to view it. This differs from `get-data-from-dataset-v2` for the `employee` dataset, which always returns every requested field but represents inaccessible values as empty and lists the withheld field names in a per-record `_restrictedFields` array. Record-level permissions apply in addition to field-level ones. Which employees a caller can view depends on their access-level configuration, which may be limited to themselves, to their direct or indirect reports, or to another configured set. If the caller cannot view the requested employee, the endpoint returns `403` with `Insufficient Permissions to view this employee` rather than a partial record. **Related endpoints.** Use this for fetching arbitrary fields on a single known employee. For multiple employees, use `list-employees`. For complex filtering or tabular reports, use `get-data-from-dataset-v2`. To look up information published in a coworker's company directory entry, such as job title, department, location, work contact details, or who they report to, use Get Employees Directory (`get-employees-directory`), which is governed by directory sharing settings rather than by per-employee record permissions and is available when directory or org-chart access is shared with the caller's access level. OAuth Scopes: employee, employee:assets, employee:compensation, employee:contact, employee:custom_fields, employee:custom_fields_encrypted, employee:demographic, employee:dependent, employee:dependent:ssn, employee:education, employee:emergency_contacts, employee:identification, employee:job, employee:job.write, employee:management, employee:name, employee:photo, employee:vaccination, sensitive_employee:address, sensitive_employee:creditcards, sensitive_employee:protected_info - [Get Employees Directory](https://documentation.bamboohr.com/reference/get-employees-directory.md): Returns the company's published employee directory: a fieldset definition plus an array of employee records whose keys match the field ids. **When to use this endpoint.** Use it for basic, non-sensitive information about coworkers who appear in the company's published directory, especially coworkers the caller does not manage. For the authenticated caller's own record, use **Get Employee** (`get-employee`) with the id `0` instead. It answers questions such as who a coworker is, their job title, department, division, or location, how to reach them at work, and who they report to. When the company shares its full directory, every record includes `supervisor`, which makes this the most direct way to answer org chart and reporting structure questions such as who reports to a given manager. Do not assume that field is present: always read the `fields` array in the response to see what a given company actually exposes, because a company that shares only its org chart returns a reduced fieldset that omits `supervisor` (see Coverage and limits below). **Access.** Directory access is governed by the company's Company Directory and Company Org Chart sharing settings (Settings > Company Directory in the BambooHR web app), together with whether those features are shared with the caller's access level. It is not governed by per-employee record permissions, so when the directory is shared with the caller the employee data is not narrowed to the people whose records they can otherwise read, and an employee with no managerial or administrative access can normally read the full directory. The `canUploadPhoto` value remains caller-specific. **Fields returned.** The fieldset is fixed by company directory configuration and callers cannot request additional fields. The `fields` array in each response lists exactly which fields that company exposes, so treat it as authoritative rather than assuming a fixed set. With full directory sharing it covers names, job title, department, division, location, manager (`supervisor`), work email, work and mobile phone, pronouns, social profile links, and photo information. It never includes compensation, national identifiers such as SSN, birth date, home address, home contact details, or employment status and history, in any configuration. **Coverage and limits.** This endpoint returns the whole directory in one response and accepts no name, department, or field filters, so narrow the results on the client side. Companies choose which employees appear in the directory, and anyone excluded is absent with no indicator that they exist. Inactive and former employees are also excluded, so an administrator researching someone who has left the company will not find them here even though the record still exists; use `get-employee` or `list-employees` for those. Absence from this response therefore means the employee is not in the published directory, not that no such employee exists, so do not conclude from this endpoint alone that someone does not work at the company. For the same reason it is not an authoritative roster; prefer `list-employees` or `get-data-from-dataset-v2` when completeness matters. **Related endpoints.** To read fields this endpoint does not expose, or to select arbitrary fields for a single employee, use **Get Employee** (`get-employee`), passing the id `0` for the authenticated caller's own record. For a coworker name, department, or location lookup, retrieve this directory and narrow the `employees` array on the client side rather than filtering elsewhere. Use **List Employees** (`list-employees`) for roster, pagination, sorting, or batch-by-id workflows where the caller can read the relevant fields, and **Get Data from Dataset (v2)** (`get-data-from-dataset-v2`) for tabular reporting, custom field selection, or analytical queries across many employees. Those endpoints apply stricter, endpoint-specific permissions and may return `403`, null or omitted field values, or filtered-out rows; this endpoint is the appropriate choice for general coworker and org chart lookups. **Response format.** Follows the `Accept` header: `application/json` returns a JSON object with `fields` and `employees` arrays; `application/xml` (the default when `Accept` is missing or any non-JSON value) returns a `` document with `
` and `` children. Employee `id` values are internal employee IDs returned as strings in both formats. The response also varies with per-company configuration, where Company Directory sharing takes precedence: when it is enabled the full fieldset is returned whether or not Company Org Chart sharing is also on. When the caller has neither usable Company Directory nor Company Org Chart access the endpoint returns 403 with an empty body and the header `x-bamboohr-error-message: Directory disabled for this account`. That can mean the features are disabled company-wide or that they are not shared with the caller's access level, and the response does not distinguish those cases; when both company toggles are off, every caller including administrators receives it. When only org-chart sharing is available (Company Directory off, Company Org Chart on) the response still lists every directory employee but uses a reduced fieldset, observed as `displayName`, `firstName`, `lastName`, `preferredName`, `jobTitle`, `pronouns`, and the photo fields, which means `supervisor`, `department`, `division`, `location`, work email, and phone numbers are all absent and reporting-structure or work-contact questions cannot be answered from that configuration; when the resulting directory has no employees the endpoint returns 404 rather than an empty list. OAuth Scopes: employee_directory - [Update Employee](https://documentation.bamboohr.com/reference/update-employee.md): Update an employee's fields by submitting a JSON object or XML document containing field name/value pairs. The request body schema lists commonly used fields, but any valid writable employee field name may be used as a key. To discover available field names, call **List Fields** (`list-fields`). This endpoint does not upload, replace, or remove the employee profile photo, and does not accept any binary or file uploads in general. Photo-related keys (e.g. `photo`, `photoUrl`) included in the body are silently ignored: the request still returns 200, but no photo change is made. To change a profile photo, use the Upload Employee Photo endpoint (`upload-employee-photo`). AI connectors cannot use that endpoint reliably and should redirect the user to the BambooHR web UI. Trax Payroll note: If the employee is currently on a pay schedule syncing with Trax Payroll, or is being added to one, the request must include the required payroll-related employee fields: employeeNumber (unless the company has automatic employee numbers enabled), firstName, lastName, dateOfBirth, ssn or ein, gender, maritalStatus, hireDate, address1, city, state, zipcode, country, employmentHistoryStatus, exempt, payType, payRate, payPer, overtimeRate, and location. OAuth Scopes: employee, employee.write, employee:assets.write, employee:compensation.write, employee:contact.write, employee:custom_fields.write, employee:custom_fields_encrypted.write, employee:demographic.write, employee:dependent.write, employee:dependent:ssn.write, employee:education.write, employee:emergency_contacts.write, employee:identification.write, employee:job, employee:job.write, employee:management.write, employee:name.write, employee:payroll.write, employee:photo.write, employee:vaccination.write, sensitive_employee:address.write, sensitive_employee:creditcards.write, sensitive_employee:protected_info.write - [List Employees](https://documentation.bamboohr.com/reference/list-employees.md): Lists all employees in the authenticated caller's company as a cursor-paginated list. Use this to list employees, fetch the employee roster, or batch-lookup multiple employees by ID. **Response shape.** The response is a JSON object with `data` (an array of employee records), `meta.total` (count of all employees matching the filter, not just the current page), `meta.page` (cursor pagination state), and `_links` (`self`, plus `next` / `prev` when more pages exist). Each employee record always includes the default identity and job fields, plus any additional fields requested via `fields`. `employeeId` is returned as a string and is the internal employee ID — see the `employeeId` and `employeeNumber` field documentation in the response schema for the distinction between the internal ID and the editable Employee # value. IDs for `filter[ids]` come from prior responses of this endpoint. **Employee photos.** Each record includes a `photoUrl` field with a time-limited signed URL. This is the recommended way for AI connectors to display or link to an employee photo, since fetching raw photo bytes through `get-employee-photo` produces base64 payloads too large for an AI model to consume reliably. **Permissions.** Field values the caller cannot read are returned as `null`, and the names of those suppressed fields are listed on the record in `_restrictedFields`. On an unfiltered request an employee remains in `data` even when the caller can read none of the requested fields: `employeeId` still carries its real value, every unreadable field is `null` and named in `_restrictedFields`, values that are not permission-gated such as `photoUrl` may still be populated, and `meta.total` counts the row. Separately, if the caller cannot read a field used in `filter` or `sort`, the affected employee is dropped from the result set entirely to avoid leaking presence, so a name search can return `meta.total: 0` even though matching employees exist. Neither an empty result nor a fully nulled row means no such employee exists. **Counts and aggregates are only valid when the caller can read every field being grouped on.** A caller with full access can safely count and group these rows. A restricted caller cannot: unreadable values come back `null` and filtered queries drop employees entirely, so grouping what such a caller receives understates the real figures and produces a confident but wrong total. Before reporting any count, headcount, department or location breakdown, or turnover figure, compare `meta.total` against the number of rows carrying readable values for the field in question. If those differ, the aggregate is incomplete: either state plainly how many employees were actually readable, or use **Get Data from Dataset (v2)** (`get-data-from-dataset-v2`) or the custom report endpoints instead, which require broader access and fail loudly rather than returning a partial answer. **Related endpoints.** For a single employee with the full set of fields, use `get-employee`. For complex filtering, arbitrary sorting, or tabular reports across many fields, use Get Data from Dataset (v2) (`get-data-from-dataset-v2`). To look up information published in a coworker's company directory entry, such as job title, department, location, work contact details, or who they report to, use Get Employees Directory (`get-employees-directory`), which is governed by directory sharing settings rather than by per-employee record permissions and is available when directory or org-chart access is shared with the caller's access level. OAuth Scopes: employee, employee:job, employee:name, employee_directory, sensitive_employee:protected_info - [Create Employee](https://documentation.bamboohr.com/reference/create-employee.md): Create a new employee. At minimum, provide a first name and last name in a JSON object or XML document. The request body schema lists commonly used fields, but any valid writable employee field name may be included as a key. To discover available field names, call **List Fields** (`list-fields`). This endpoint does not upload, set, or remove the employee profile photo. Photo-related keys (e.g. `photo`, `photoUrl`) included in the body are silently ignored: the request still creates the employee and returns 201, but no photo is attached. After creation, use the Upload Employee Photo endpoint (`upload-employee-photo`) to attach a profile photo. AI connectors cannot use that endpoint reliably and should redirect the user to the BambooHR web UI. Trax Payroll note: Employees added to a pay schedule synced with Trax Payroll must include the required payroll-related employee fields: employeeNumber (unless the company has automatic employee numbers enabled), firstName, lastName, dateOfBirth, ssn or ein, gender, maritalStatus, hireDate, address1, city, state, zipcode, country, employmentHistoryStatus, exempt, payType, payRate, payPer, overtimeRate, and location. OAuth Scopes: employee, employee.write, employee:assets.write, employee:compensation.write, employee:contact.write, employee:custom_fields.write, employee:custom_fields_encrypted.write, employee:demographic.write, employee:dependent.write, employee:dependent:ssn.write, employee:education.write, employee:emergency_contacts.write, employee:identification.write, employee:job, employee:job.write, employee:management.write, employee:name.write, employee:payroll.write, employee:photo.write, employee:vaccination.write, sensitive_employee:address.write, sensitive_employee:creditcards.write, sensitive_employee:protected_info.write - [Delete employee](https://documentation.bamboohr.com/reference/delete-employee.md): Permanently deletes an employee record and all associated data. OAuth Scopes: employee.write - [Delete Goal](https://documentation.bamboohr.com/reference/delete-goal.md): Permanently deletes a goal for an employee. The goal must belong to the specified employee. Returns 204 with no response body on success. For natural-language requests that identify a goal by title or partial title, first call `list-goals` with `filter=status-all` and resolve exactly one matching goal. Do not delete if there are multiple matches or no match; ask for clarification or report that the goal was not found. OAuth Scopes: goal.write - [Delete Goal Comment](https://documentation.bamboohr.com/reference/delete-goal-comment.md): Deletes a goal comment. The comment must belong to the specified goal, and the goal must belong to the specified employee. Returns 204 with no response body on success. If the user does not provide a comment ID, first call `list-goal-comments` and select a single deletable comment (`canDelete` is true) matching the user's description. If multiple comments match or none are deletable, do not delete; ask for clarification. OAuth Scopes: goal.write - [Get Goal Aggregate](https://documentation.bamboohr.com/reference/get-goal-aggregate.md): Returns a single goal with its comments, alignment options, and a list of all persons who are either shared on the goal or have commented on it. Useful for rendering a full goal detail view in a single request. OAuth Scopes: goal - [Get Goals Aggregate (v1)](https://documentation.bamboohr.com/reference/get-goals-aggregate-v1.md): Deprecated. Use "Get Goals Aggregate (v1.1)" instead. Provides a list of all goals, type counts, goal comment counts, and employees shared with goals for the given employee. This version of the endpoint will not return any goals with milestones. Milestone functionality for this endpoint begins in version 1.2. OAuth Scopes: goal - [Get Goal Filters (v1)](https://documentation.bamboohr.com/reference/get-goals-filters-v1.md): Deprecated. Use "Get Goal Filters (v1.1)" instead. Get the number of goals per status for an employee. Returns a count of goals in each status (In Progress, Completed) for the specified employee. Goals with milestones are excluded from counts in this version. OAuth Scopes: goal - [List Goals](https://documentation.bamboohr.com/reference/list-goals.md): Returns goals for an employee. Use this endpoint to locate goals by title before updating, commenting on, closing, reopening, or deleting them. Use `filter=status-inProgress` when the user asks for current/active goals, `filter=status-completed` for completed goals, `filter=status-closed` for closed goals, and `filter=status-all` when the user says "all goals", "including closed", or you are resolving a goal by title for a write operation where the status is unknown. If no filter is provided, closed goals are excluded. Results are capped at 50 goals; if a title lookup is ambiguous or absent, do not update or delete a different goal. OAuth Scopes: goal - [Create Goal](https://documentation.bamboohr.com/reference/create-goal.md): Create a new goal for an employee. To create a simple goal without milestones, omit the `milestones` field; the goal's progress can then be changed with `update-goal-progress`. To create a milestone-based goal, provide `milestones` as a non-empty array of `{ "title": string }` objects; the goal's percent complete is then derived from milestone completion and should be changed via `update-goal-milestone-progress`. Sending `milestones: null` is treated as omitted (creates a simple goal). OAuth Scopes: goal.write - [Update Goal (v1)](https://documentation.bamboohr.com/reference/update-goal-v1.md): Deprecated. Use "Update Goal (v1.1)" instead. Update a goal. This version will not update a goal to contain milestones, that functionality is added in version 1.1. OAuth Scopes: goal.write - [Update Goal Progress](https://documentation.bamboohr.com/reference/update-goal-progress.md): Update the progress percentage of a simple, non-milestone goal. Do not use this endpoint for goals that contain milestones; BambooHR derives percent complete for milestone-based goals from milestone completion and will reject manual percent updates with a 400 response (`UPDATE_GOAL_WITH_MILESTONE_PROGRESS_ERROR`). For milestone-based goals, use `update-goal-milestone-progress` to mark individual milestones complete or incomplete. OAuth Scopes: goal.write - [Update Milestone Progress](https://documentation.bamboohr.com/reference/update-goal-milestone-progress.md): Update the progress of a milestone in a goal. Validate the result using returned domain fields such as the milestone's `completedDateTime`, plus the goal's `status` and `percentComplete`; do not rely solely on `lastChangedDateTime` as the confirmation timestamp, because it may not match the HTTP response time or may reflect BambooHR's internal timezone/update semantics. OAuth Scopes: goal.write - [Update Goal Sharing](https://documentation.bamboohr.com/reference/update-goal-sharing.md): Replaces the full list of employees this goal is shared with. The provided `sharedWithEmployeeIds` array must include the goal owner's internal employee ID. Returns the updated goal object. OAuth Scopes: goal.write - [Get Goal Creation Permission](https://documentation.bamboohr.com/reference/get-goal-creation-permission.md): Determine if the authenticated caller has permission to create a goal for this employee. OAuth Scopes: goal - [List Goal Sharing Options](https://documentation.bamboohr.com/reference/list-goal-share-options.md): Provides a list of employees with whom the specified employee\'s goals may be shared. OAuth Scopes: goal - [List Goal Comments](https://documentation.bamboohr.com/reference/list-goal-comments.md): Returns comments for a goal, including each comment's ID, author, text, creation time, and edit/delete permissions. Use this endpoint before updating or deleting a comment when the user identifies a comment by text or says "my comment" rather than providing a comment ID. OAuth Scopes: goal - [Create Goal Comment](https://documentation.bamboohr.com/reference/create-goal-comment.md): Creates a new comment on a goal. The goal must belong to the specified employee. Returns the newly created comment object including its assigned ID. OAuth Scopes: goal.write - [Update Goal Comment](https://documentation.bamboohr.com/reference/update-goal-comment.md): Updates the text of an existing goal comment. The comment must belong to the specified goal, and the goal must belong to the specified employee. Returns the updated comment object. If the user does not provide a comment ID, first call `list-goal-comments` and select a single editable comment (`canEdit` is true) matching the user's description. If multiple comments match or none are editable, do not update; ask for clarification. OAuth Scopes: goal.write - [Get Alignable Goal Options](https://documentation.bamboohr.com/reference/get-alignable-goal-options.md): Returns goals that can be used as alignment targets. When a `goalId` query parameter is provided, the currently aligned goal is included in the results even if it would otherwise be excluded. When `goalId` is omitted, returns alignment options for the authenticated caller. This endpoint is permission-sensitive: the caller may be able to view a goal through `list-goals` or `get-goal-aggregate` but still receive 403 here if they lack permission to view alignment options for the selected goal. Treat 403 as "alignment options are permission-restricted," not as proof that the goal ID is invalid. OAuth Scopes: goal - [Close Goal](https://documentation.bamboohr.com/reference/close-goal.md): Closes a goal, moving it to the closed status. An optional comment may be included in the request body to record a note at closing time. Returns the updated goal object. Validate the result using the returned `status`, `percentComplete`, and `completionDate` fields; do not rely solely on `lastChangedDateTime` as the confirmation timestamp, because it may not match the HTTP response time or may reflect BambooHR's internal timezone/update semantics. Note: Cascading goals with visible children cannot be closed. OAuth Scopes: goal.write - [Reopen Goal](https://documentation.bamboohr.com/reference/reopen-goal.md): Reopens a closed goal, returning it to the in-progress status. Returns the updated goal object. Validate the result using the returned `status` and `percentComplete` fields; do not rely solely on `lastChangedDateTime` as the confirmation timestamp, because it may not match the HTTP response time or may reflect BambooHR's internal timezone/update semantics. OAuth Scopes: goal.write - [Get Goal Filters (v1.1)](https://documentation.bamboohr.com/reference/get-goals-filters-v1_1.md): Deprecated. Use "Get Goal Filters (v1.2)" instead. Get the number of goals per status for an employee. Note: Compared to "Get Goal Filters (v1)", this version includes actions. OAuth Scopes: goal - [Get Goals Aggregate (v1.1)](https://documentation.bamboohr.com/reference/get-goals-aggregate-v1_1.md): Deprecated. Use "Get Goals Aggregate (v1.2)" instead. Provides a list of all goals, type counts, filter actions, goal comment counts, and employees shared with goals for the given employee. Note: Compared to "Get Goals Aggregate (v1)", this version returns goals in the closed filter and provides filter actions for each filter. This version of the endpoint will not return any goals with milestones. Milestone functionality for this endpoint begins in version 1.2. OAuth Scopes: goal - [Update Goal (v1.1)](https://documentation.bamboohr.com/reference/update-goal-v1_1.md): Update a goal's top-level fields and optionally add or delete milestones. Milestone handling is not a full replace or upsert: objects passed in `milestones` are always added as new milestones, even if their titles match existing milestones. To keep existing milestones unchanged while editing title, description, due date, sharing, or alignment, omit the `milestones` field. To remove milestones, pass their IDs in `deletedMilestoneIds`. There is no field for editing an existing milestone title in place. Note: Compared to "Update Goal (v1)", this version adds milestone updates. OAuth Scopes: goal.write - [Get Goal Filters (v1.2)](https://documentation.bamboohr.com/reference/get-goals-filters-v1_2.md): Get the number of goals per status for an employee, including goals with milestones. Note: Compared to "Get Goal Filters (v1.1)", this version returns goals with milestones. OAuth Scopes: goal - [Get Goals Aggregate (v1.2)](https://documentation.bamboohr.com/reference/get-goals-aggregate-v1_2.md): Provides a goals dashboard for an employee: goals matching the selected filter, status filter counts/actions, comment counts, and people shared with or commenting on those goals. This v1.2 endpoint includes milestone-based goals in the returned goal list. Use the optional `filter` query parameter to control which statuses are included; use `status-all` when the user asks for a complete dashboard across active, completed, and closed goals. Note: Compared to "Get Goals Aggregate (v1.1)", this version returns goals that contain milestones. OAuth Scopes: goal - [List Catalog Holidays](https://documentation.bamboohr.com/reference/list-catalog-holidays.md): Lists entries in the global holiday catalog. The catalog is read-only system reference data; use the returned uuid values to seed company holidays. OAuth Scopes: holidays - [Get Catalog Holiday](https://documentation.bamboohr.com/reference/get-catalog-holiday.md): Gets a global holiday catalog entry by UUID. OAuth Scopes: holidays - [List Company Holidays](https://documentation.bamboohr.com/reference/list-company-holidays.md): Returns a paginated list of active company holidays. Soft-deleted holidays are never returned. Supports OData filtering via `filter`, sorting via `orderBy`, field projection via `select`, and page-based pagination. OAuth Scopes: holidays - [Create Company Holiday](https://documentation.bamboohr.com/reference/create-company-holiday.md): Creates a company holiday. The body may be fully-specified or carry a globalHolidayUuid that seeds name, dates, and countries from the global catalog entry; partner-supplied values override the catalog defaults. OAuth Scopes: holidays.write - [Get Company Holiday](https://documentation.bamboohr.com/reference/get-company-holiday.md): Gets a company holiday by ID. OAuth Scopes: holidays - [Delete Company Holiday](https://documentation.bamboohr.com/reference/delete-company-holiday.md): Soft-deletes a company holiday and removes its audience, pay, and country sub-rows. Idempotent: deleting a missing or already-deleted holiday also returns 204. OAuth Scopes: holidays.write - [Update Company Holiday](https://documentation.bamboohr.com/reference/update-company-holiday.md): Updates a company holiday with a JSON Merge Patch (RFC 7396) document. Only the fields present in the patch change; countryCodes, audience, and holidayPay replace their stored blocks wholesale when supplied. Send null for endDate to revert to a single-day holiday and null for holidayPay to clear the pay treatment. globalHolidayUuid is read-only and rejected if present. OAuth Scopes: holidays.write - [Bulk Create Company Holidays](https://documentation.bamboohr.com/reference/bulk-insert-company-holidays.md): Creates multiple company holidays in one synchronous call. Each record follows the single-create semantics: it may be fully-specified or carry a globalHolidayUuid that seeds name, dates, and countries from the global catalog entry (mix-and-match within the same request). Records are processed in request order. OAuth Scopes: holidays.write - [Hours](https://documentation.bamboohr.com/reference/hours.md) - [Get Time Tracking Record](https://documentation.bamboohr.com/reference/get-time-tracking-record.md): Retrieves a single time tracking hour record by its ID. Returns the full record details including hours, date, employee, project, task, and shift differential information. The `project` and `shiftDifferential` fields are null when not applicable. For historical compatibility, missing records may surface as an empty/null payload rather than a strict not-found response. OAuth Scopes: time_tracking - [Create Hour Record](https://documentation.bamboohr.com/reference/create-time-tracking-hour-record.md): Adds a single hour record. Use this endpoint when creating one record at a time. For bulk imports, use create-or-update-time-tracking-hour-records. OAuth Scopes: time_tracking.write - [Create or Update Hour Records](https://documentation.bamboohr.com/reference/create-or-update-time-tracking-hour-records.md): Bulk add/edit hour records. The endpoint can return HTTP 201 even when individual items fail validation; inspect each item's `success` flag and per-item `response.message` for partial failures. OAuth Scopes: time_tracking.write - [Update Hour Record](https://documentation.bamboohr.com/reference/update-time-tracking-record.md): Edits an existing hour record by `timeTrackingId`. OAuth Scopes: time_tracking.write - [Delete Hour Record](https://documentation.bamboohr.com/reference/delete-time-tracking-hour-record.md): Deletes an hour record by `timeTrackingId` (`id` path parameter). This removes all stored revisions associated with that logical time tracking record. Not-found and invalid-id cases are currently returned as a 400 invalid-argument response for backward compatibility. OAuth Scopes: time_tracking.write - [List job locations](https://documentation.bamboohr.com/reference/get-locations.md): Retrieves a paginated list of job locations. Returns active locations by default. Supports pagination via page and pageSize query parameters. OAuth Scopes: field - [Create a job location](https://documentation.bamboohr.com/reference/create-location.md): Creates a new job location. Requires a label and address. If remoteLocation is true, address fields are optional. OAuth Scopes: field.write - [Get a job location](https://documentation.bamboohr.com/reference/get-location.md): Retrieves a single job location by its ID. Returns the full location resource including address details. OAuth Scopes: field - [Update a job location](https://documentation.bamboohr.com/reference/update-location.md): Updates an existing job location. OAuth Scopes: field.write - [Delete a job location](https://documentation.bamboohr.com/reference/delete-location.md): Deletes a job location by its ID. Returns 204 No Content on success. OAuth Scopes: field.write - [Login](https://documentation.bamboohr.com/reference/login.md) - [Login](https://documentation.bamboohr.com/reference/user-login.md): Exchanges username, password, and application key for a persistent API key scoped to that user and application. No pre-existing authentication is required; credentials are passed in the request body. On success, returns a persistent API key, the authenticated user ID, the linked employee ID (null when no employee record is associated), and the base API URL to use for subsequent requests. This endpoint is deprecated. New integrations should prefer OAuth or OpenID Connect instead. `applicationKey` must correspond to a registered non-mobile application; iOS and Android app keys are explicitly rejected with a 403 (no body). The optional `deviceId` associates the generated key with a specific device. Response format is determined by the `Accept` request header. Send `Accept: application/json` to receive JSON; omit the header or send any other value to receive XML. Alternatively, set `?format=json` in the query string to force JSON regardless of the `Accept` header. Note: If the company has SSO enabled and password login is disabled, this endpoint returns HTTP 200 with a plain-text error message rather than a structured error response. - [Time Tracking](https://documentation.bamboohr.com/reference/time-tracking.md) - [List Timesheet Entries](https://documentation.bamboohr.com/reference/list-timesheet-entries.md): Returns timesheet entries for all employees, or a filtered subset, within the specified date range. Results include both clock and hour entry types. Dates must fall within the last 365 days and are interpreted in the company timezone. OAuth Scopes: time_tracking - [Create or Update Timesheet Clock Entries](https://documentation.bamboohr.com/reference/create-or-update-timesheet-clock-entries.md): Creates or updates timesheet clock entries in bulk. Entries with an existing ID are updated; entries without an ID are created. OAuth Scopes: time_tracking.write - [Create or Update Timesheet Hour Entries](https://documentation.bamboohr.com/reference/create-or-update-timesheet-hour-entries.md): Creates or updates timesheet hour entries in bulk. Entries with an existing ID are updated; entries without an ID are created. OAuth Scopes: time_tracking.write - [Create Timesheet Clock-In Entry](https://documentation.bamboohr.com/reference/create-timesheet-clock-in-entry.md): Clocks in an employee at the current server time. To record a historical clock-in, provide a `date`, `start` (HH:MM, 24-hour format), and `timezone`. You can optionally associate the entry with `projectId`, `taskId` (requires `projectId`), `breakId`, and a `note`. OAuth Scopes: time_tracking.write - [Create Timesheet Clock-Out Entry](https://documentation.bamboohr.com/reference/create-timesheet-clock-out-entry.md): Clocks out a currently clocked-in employee at the current server time. To record a historical clock-out, provide a `date`, `end` (HH:MM, 24-hour format), and `timezone`. OAuth Scopes: time_tracking.write - [Delete Timesheet Clock Entries](https://documentation.bamboohr.com/reference/delete-timesheet-clock-entries-via-post.md): Deletes one or more timesheet clock entries by their IDs. Delete operations are idempotent; deleting already-removed entries does not require client retries. OAuth Scopes: time_tracking.write - [Delete Timesheet Hour Entries](https://documentation.bamboohr.com/reference/delete-timesheet-hour-entries-via-post.md): Deletes one or more timesheet hour entries by their IDs. Delete operations are idempotent; deleting already-removed entries does not require client retries. OAuth Scopes: time_tracking.write - [Create Time Tracking Project](https://documentation.bamboohr.com/reference/create-time-tracking-project.md): Creates a time tracking project. If a deleted project with the same name exists, that project is restored and updated with the supplied values instead of a new project being created; the response returns the restored project's existing ID. `hasTasks` in the response is set automatically based on whether `tasks` were supplied and cannot be set directly on create. Created tasks are not embedded; retrieve them with **List Time Tracking Project Tasks** (`list-project-tasks`). OAuth Scopes: time_tracking:project.write - [Meal & Rest Breaks](https://documentation.bamboohr.com/reference/meal-rest-breaks.md) - [List Break Policies](https://documentation.bamboohr.com/reference/list-break-policies.md): Returns a paginated list of all break policies. Supports OData v4 filtering. Use includeCounts to include employee and break counts per policy. OAuth Scopes: time_tracking:breaks - [Get Break Policy](https://documentation.bamboohr.com/reference/get-break-policy.md): Retrieves a single break policy by its UUID. When includeCounts is enabled, the response includes the number of associated employees and breaks. OAuth Scopes: time_tracking:breaks - [Create Break Policy](https://documentation.bamboohr.com/reference/create-break-policy.md): Create a break policy. Breaks and assignments can be optionally included and created at the same time. OAuth Scopes: time_tracking:breaks.write - [Update Break Policy](https://documentation.bamboohr.com/reference/update-break-policy.md): Partially updates a break policy identified by its UUID. Only fields provided in the request body are updated. Returns the updated break policy on success. OAuth Scopes: time_tracking:breaks.write - [Replace Breaks for Break Policy](https://documentation.bamboohr.com/reference/replace-breaks-for-break-policy.md): Replace all breaks for a break policy. Breaks with an ID will be updated, breaks without an ID will be created. Existing breaks not in the request will be soft-deleted. OAuth Scopes: time_tracking:breaks.write - [Sync Break Policy](https://documentation.bamboohr.com/reference/sync-break-policy.md): Performs a full replacement of a break policy and its related data (breaks and employee assignments). Unlike the partial update endpoint, this replaces the entire policy state with the provided payload, removing any breaks or assignments not included in the request. OAuth Scopes: time_tracking:breaks.write - [Delete Break Policy](https://documentation.bamboohr.com/reference/delete-break-policy.md): Deletes a break policy by its UUID. Associated breaks and employee assignments are also removed. OAuth Scopes: time_tracking:breaks.write - [List Breaks for Break Policy](https://documentation.bamboohr.com/reference/list-break-policy-breaks.md): Returns a paginated list of breaks belonging to the specified break policy. Supports OData v4 filtering. OAuth Scopes: time_tracking:breaks - [Get Break](https://documentation.bamboohr.com/reference/get-break.md): Retrieves a single time tracking break by its UUID. Returns the full break details including name, duration, paid status, and availability configuration. OAuth Scopes: time_tracking:breaks - [Create Break](https://documentation.bamboohr.com/reference/create-break.md): Creates a new break and associates it with the specified break policy. OAuth Scopes: time_tracking:breaks.write - [Update Break](https://documentation.bamboohr.com/reference/update-break.md): Partially updates a time tracking break identified by its UUID. Only fields provided in the request body are updated. Returns the updated break on success. OAuth Scopes: time_tracking:breaks.write - [Delete Break](https://documentation.bamboohr.com/reference/delete-break.md): Deletes a time tracking break by its UUID. The break is soft-deleted and removed from any break policies it was associated with. OAuth Scopes: time_tracking:breaks.write - [List Break Policy Employees](https://documentation.bamboohr.com/reference/list-break-policy-employees.md): Retrieves employees assigned to a specific break policy. If a policy has no assignments, returns HTTP 200 with an empty `data` array. OAuth Scopes: time_tracking:breaks - [List Employee Break Policies](https://documentation.bamboohr.com/reference/list-employee-break-policies.md): Retrieves break policies assigned to a specific employee. Requires permission to view the target employee. OAuth Scopes: time_tracking:breaks - [Set Employees for Break Policy](https://documentation.bamboohr.com/reference/set-break-policy-employees.md): Sets the employee assignments for a break policy. This replaces all existing assignments with the provided list. OAuth Scopes: time_tracking:breaks.write - [Assign Employees to Break Policy](https://documentation.bamboohr.com/reference/assign-employees-to-break-policy.md): Assigns employees to a break policy. Adds the specified employees to the policy without removing existing assignments. OAuth Scopes: time_tracking:breaks.write - [Unassign Employees from Break Policy](https://documentation.bamboohr.com/reference/unassign-employees-from-break-policy.md): Unassigns the specified employees from a break policy. Removes employee assignments from the policy without affecting the policy itself or other assigned employees. Employees can only be unassigned from policies that are not assigned to all employees. OAuth Scopes: time_tracking:breaks.write - [List Employee Break Availabilities](https://documentation.bamboohr.com/reference/list-employee-break-availabilities.md): Retrieves break availability information for an employee. Requires permission to view the target employee in addition to time-tracking-break access. OAuth Scopes: time_tracking:breaks - [List Break Assessments](https://documentation.bamboohr.com/reference/list-break-assessments.md): Returns a paginated list of break assessments. A break assessment records whether an employee complied with their assigned break policy for a given day, along with any violations. Use the `filter` parameter to scope results by employee, date, result, or other fields. Use `offset` and `limit` for pagination; `limit` defaults to 100 and may not exceed 500. OAuth Scopes: time_tracking:breaks - [Get Break Policy Suggestions](https://documentation.bamboohr.com/reference/get-break-policy-suggestions.md): Uses an AI agent to analyze existing break policies and company context, then returns structured meal and rest break policy recommendations ready for form pre-fill. OAuth Scopes: time_tracking:breaks - [List Time Tracking Projects](https://documentation.bamboohr.com/reference/list-projects.md): Returns a paginated list of time tracking projects. Supports OData-style `filter` and `sort` query parameters. Pagination is page-based via `page` and `pageSize` (defaults: page 1, pageSize 100, max 500). OAuth Scopes: time_tracking:project - [Get Time Tracking Project](https://documentation.bamboohr.com/reference/get-project.md): Retrieves a single time tracking project by its ID, including the list of employees assigned to it. OAuth Scopes: time_tracking:project - [Delete Time Tracking Project](https://documentation.bamboohr.com/reference/delete-project.md): Deletes a time tracking project by its ID. OAuth Scopes: time_tracking:project.write - [Update Time Tracking Project](https://documentation.bamboohr.com/reference/update-project.md): Partially updates a time tracking project identified by its ID. Only fields provided in the request body are updated; omitted fields are left unchanged. OAuth Scopes: time_tracking:project.write - [List Time Tracking Project Tasks](https://documentation.bamboohr.com/reference/list-project-tasks.md): Returns a paginated list of tasks for the specified time tracking project. Tasks are filtered by `statuses[]`, which defaults to `active`. OAuth Scopes: time_tracking:project - [Create Time Tracking Project Task](https://documentation.bamboohr.com/reference/create-project-task.md): Creates a new task on the specified time tracking project. OAuth Scopes: time_tracking:project.write - [Get Time Tracking Task](https://documentation.bamboohr.com/reference/get-task.md): Retrieves a single time tracking task by its ID. OAuth Scopes: time_tracking:project - [Delete Time Tracking Task](https://documentation.bamboohr.com/reference/delete-task.md): Deletes a time tracking task by its ID. OAuth Scopes: time_tracking:project.write - [Update Time Tracking Task](https://documentation.bamboohr.com/reference/update-task.md): Partially updates a time tracking task identified by its ID. Only fields provided in the request body are updated; at least one field must be provided. OAuth Scopes: time_tracking:project.write - [List Time Tracking Shift Differentials](https://documentation.bamboohr.com/reference/list-shift-differentials.md): Returns a paginated list of time tracking shift differentials. Supports OData-style `filter` and `sort` query parameters. Pagination is page-based via `page` and `pageSize` (defaults: page 1, pageSize 20, max 100). Archived rows are excluded by default; include them with `filter=archived eq true`. Soft-deleted rows are never returned. OAuth Scopes: time_tracking:shift_differentials - [Create Time Tracking Shift Differential](https://documentation.bamboohr.com/reference/create-shift-differential.md): Creates a new time tracking shift differential. OAuth Scopes: time_tracking:shift_differentials.write - [Get Time Tracking Shift Differential](https://documentation.bamboohr.com/reference/get-shift-differential.md): Retrieves a single time tracking shift differential by its ID. Archived shift differentials are returned normally; soft-deleted shift differentials return 404. OAuth Scopes: time_tracking:shift_differentials - [Delete Time Tracking Shift Differential](https://documentation.bamboohr.com/reference/delete-shift-differential.md): Deletes a time tracking shift differential by its ID. OAuth Scopes: time_tracking:shift_differentials.write - [Update Time Tracking Shift Differential](https://documentation.bamboohr.com/reference/update-shift-differential.md): Partially updates a time tracking shift differential identified by its ID. OAuth Scopes: time_tracking:shift_differentials.write - [List Clock Entries](https://documentation.bamboohr.com/reference/list-clock-entries.md): Returns a paginated list of time tracking clock entries. Supports OData-style `filter` and `sort` query parameters. Pagination is page-based via `page` and `pageSize` (defaults: page 1, pageSize 50, min 10, max 200). Filterable fields: `timesheetId`, `employeeId`, `start`, `end`. Sortable fields: `start`, `end`, `updatedAt`. Default sort is `start desc`. Geolocation is omitted (null) for entries whose configuration has it disabled. OAuth Scopes: time_tracking:timesheets - [Create Clock Entry](https://documentation.bamboohr.com/reference/create-clock-entry.md): Manually creates a time tracking clock entry (corrections, retroactive entry). Distinct from the real-time clock-in process resource. The parent daily entry and timesheet are resolved (and created if needed) from `start` + `timezone`; the entry is rejected with 409 when the resolved timesheet's type does not accept clock entries. Geolocation is persisted only when the employee's configuration has it enabled. OAuth Scopes: time_tracking:timesheets.write - [Get Clock Entry](https://documentation.bamboohr.com/reference/get-clock-entry.md): Retrieves a single clock entry by its ID. `start`/`end` are ISO 8601 with the offset of the entry's `timezone`; `end` and `clockOutLocation` are null while the entry is open. Geolocation is omitted (null) when the configuration has it disabled. OAuth Scopes: time_tracking:timesheets - [Delete Clock Entry](https://documentation.bamboohr.com/reference/delete-clock-entry.md): Deletes a time tracking clock entry by its ID. OAuth Scopes: time_tracking:timesheets.write - [Update Clock Entry](https://documentation.bamboohr.com/reference/update-clock-entry.md): Partially updates a time tracking clock entry identified by its ID. Only the fields present in the body are changed. When `start` or `timezone` change, the entry's `date` and `timesheetId` are recomputed server-side and the entry is moved to the matching timesheet. Pass `null` for `clockInLocation` / `clockOutLocation` to clear the stored geolocation. OAuth Scopes: time_tracking:timesheets.write - [Clock In](https://documentation.bamboohr.com/reference/clock-in.md): Clocks an employee in at the current server time, creating an open clock entry (`end: null`). Proxy clock-in for a different employee requires `time_tracking:timesheets.write` scope plus permission to manage the target employee's time. OAuth Scopes: time_tracking:timesheets.write - [Clock Out](https://documentation.bamboohr.com/reference/clock-out.md): Clocks an employee out at the current server time, closing the employee's open clock entry (`end` set, `endSource: USER`). Proxy clock-out for a different employee requires `time_tracking:timesheets.write` scope plus permission to manage the target employee's time. OAuth Scopes: time_tracking:timesheets.write - [List Hour Entries](https://documentation.bamboohr.com/reference/list-hour-entries.md): Returns a paginated list of time tracking hour entries. Supports OData-style `filter` and `sort` query parameters. Pagination is page-based via `page` and `pageSize` (defaults: page 1, pageSize 50, min 10, max 200). Filterable fields: `timesheetId`, `employeeId`, `date`. Sortable fields: `date`, `updatedAt`. Default sort is `date desc`. OAuth Scopes: time_tracking:timesheets - [Create Hour Entry](https://documentation.bamboohr.com/reference/create-hour-entry.md): Creates a new time tracking hour entry. OAuth Scopes: time_tracking:timesheets.write - [Get Hour Entry](https://documentation.bamboohr.com/reference/get-hour-entry.md): Retrieves a single hour entry by its ID. OAuth Scopes: time_tracking:timesheets - [Delete Hour Entry](https://documentation.bamboohr.com/reference/delete-hour-entry.md): Deletes a time tracking hour entry by its ID. OAuth Scopes: time_tracking:timesheets.write - [Update Hour Entry](https://documentation.bamboohr.com/reference/update-hour-entry.md): Partially updates a time tracking hour entry identified by its ID. Only the fields present in the body are changed; the rest retain their prior values. Moving the entry to a date in a different pay period updates the returned timesheetId. OAuth Scopes: time_tracking:timesheets.write - [Approve Timesheet](https://documentation.bamboohr.com/reference/approve-timesheet.md): Approves a timesheet (process resource). Only a timesheet whose derived `status` is `PENDING_APPROVAL` can be approved; approving an already-approved or not-yet-open timesheet returns 409. Returns the updated timesheet with `status` `APPROVED`. OAuth Scopes: time_tracking:timesheets.write - [List Timesheets](https://documentation.bamboohr.com/reference/list-timesheets.md): Returns a paginated list of timesheets. Supports OData-style `filter` (fields: `employeeId`, `status`, `startDate`, `endDate`) and `sort` (fields: `startDate`, `endDate`, `approvedAt`, `updatedAt`; default `startDate desc`). Page-based pagination via `page` (default 1) and `pageSize` (default 50, max 200). Future-period timesheets are always excluded. OAuth Scopes: time_tracking:timesheets - [Get Timesheet](https://documentation.bamboohr.com/reference/get-timesheet.md): Retrieves a single timesheet by its ID. The `status` is derived at read time (`OPEN`, `PENDING_APPROVAL`, or `APPROVED`) and `type` is returned in `UPPER_SNAKE_CASE` (`SINGLE`, `CLOCK`, `MULTIPLE`, or `HOUR`). Timesheets for pay periods that have not started yet return 404. OAuth Scopes: time_tracking:timesheets - [Get Timesheet Summary](https://documentation.bamboohr.com/reference/get-timesheet-summary.md): Returns the daily breakdown of hours for a timesheet, including regular, overtime, and double-time hours per day. Every date in the pay period is represented; days with no logged hours return 0.0 in each bucket. OAuth Scopes: time_tracking:timesheets - [Create Time Tracking Project (Legacy)](https://documentation.bamboohr.com/reference/create-time-tracking-project-legacy.md): Deprecated. Use **Create Time Tracking Project** instead (`create-time-tracking-project`). Creates a time tracking project using the legacy contract and returns the project with its tasks. If a deleted project with the same name exists, that project is restored and updated with the supplied values instead of a new project being created; the response returns the restored project's existing ID. OAuth Scopes: time_tracking.write - [List Configurations](https://documentation.bamboohr.com/reference/list-time-tracking-configurations.md): Returns a paginated list of time tracking configurations. Both GLOBAL and GROUP configurations are returned; soft-deleted configurations are never returned. Supports an OData-style `filter`, an `orderBy` sort expression, and `select` sparse fieldsets. Pagination is page-based via `page` and `pageSize` (defaults: page 1, pageSize 20, max 100). OAuth Scopes: time_tracking:configurations - [Create Configuration](https://documentation.bamboohr.com/reference/create-time-tracking-configuration.md): Creates a new GROUP time tracking configuration together with its approval workflow. The type is forced to GROUP server-side; the GLOBAL configuration is auto-managed and cannot be created via this endpoint. Accepts an optional Idempotency-Key header for safe retries. OAuth Scopes: time_tracking:configurations.write - [Get Configuration](https://documentation.bamboohr.com/reference/get-time-tracking-configuration.md): Retrieves a single time tracking configuration by its ID. Soft-deleted configurations return 404. OAuth Scopes: time_tracking:configurations - [Delete Configuration](https://documentation.bamboohr.com/reference/delete-time-tracking-configuration.md): Soft-deletes an empty GROUP time tracking configuration. A configuration that still has enrolled employees cannot be deleted, because un-enrolling employees is governed by the employee enrollment permissions rather than the configuration permissions; move or un-enroll its employees first. Open timesheets stay on the previously-applicable rules until the next pay period boundary. The GLOBAL configuration is auto-managed and cannot be deleted. Deletion is idempotent: an ID that does not exist, or a configuration that was already deleted, also returns 204. OAuth Scopes: time_tracking:configurations.write - [Update Configuration](https://documentation.bamboohr.com/reference/update-time-tracking-configuration.md): Updates a time tracking configuration using JSON Merge Patch (RFC 7396) semantics: only the properties present in the body are applied, omitted properties are unchanged, and an explicit null clears a nullable property. Both GLOBAL and GROUP configurations can be updated. Content-Type: application/merge-patch+json is preferred because it names those semantics, but application/json is also accepted. OAuth Scopes: time_tracking:configurations.write - [List Enrolled Employees](https://documentation.bamboohr.com/reference/list-time-tracking-employees.md): Returns a paginated list of employee time tracking enrollments. Both enabled and disabled enrollments are returned; narrow with the `enabled` filter. Supports an OData-style `filter`, an `orderBy` sort expression, and `select` sparse fieldsets. Pagination is page-based via `page` and `pageSize` (defaults: page 1, pageSize 20, minimum 10, maximum 100). OAuth Scopes: time_tracking:employees - [Get Employee Enrollment](https://documentation.bamboohr.com/reference/get-time-tracking-employee-enrollment.md): Gets an employee's time tracking enrollment data. OAuth Scopes: time_tracking:employees - [Update Employee Enrollment](https://documentation.bamboohr.com/reference/update-time-tracking-employee-enrollment.md): Enables, disables, or reassigns a single employee's enrollment using JSON Merge Patch (RFC 7396) semantics: only the properties present in the body are applied and omitted properties are unchanged. Content-Type must be `application/merge-patch+json`. When the employee has no enrollment record yet and `enabled` is set to true, one is created. `timezone` and `clockInId` are read-only on this API. Reassigning an employee whose time tracking is currently off requires setting `enabled` to true in the same body, and `configurationId` and `enabledOn` cannot be combined with `enabled: false`. OAuth Scopes: time_tracking:employees.write - [Bulk Upsert Employee Enrollments](https://documentation.bamboohr.com/reference/bulk-upsert-time-tracking-employee-enrollments.md): Bulk enables, disables, or reassigns employee enrollments. The body is a top-level JSON array of between 1 and 1000 upsert records; each record requires `employeeId` and applies the same merge-patch semantics as the single-employee PATCH. Request-level validation (payload shape, record cap, missing `employeeId`) runs synchronously; the records themselves are applied asynchronously, so the response is 202 with a `requestId` for log correlation rather than the resulting enrollments. Confirm the final state by reading the enrollments back through `GET /api/v1/time-tracking/employees`. Per-record processing errors, such as an unknown `employeeId` or `configurationId`, do not surface in the response. Send `atomic=true` to commit the whole batch as one unit instead, in which case any per-record failure aborts the batch and returns 422 with nothing applied. OAuth Scopes: time_tracking:employees.write - [List Time Tracking Kiosks](https://documentation.bamboohr.com/reference/list-time-tracking-kiosks.md): Returns a paginated list of time tracking kiosks. Deleted kiosks are never returned. Supports an OData-style `filter`, an `orderBy` sort expression, and `select` sparse fieldsets. Results are sorted by name ascending when `orderBy` is omitted; name ordering is case-insensitive. Pagination is page-based via `page` and `pageSize` (defaults: page 1, pageSize 20, max 100). OAuth Scopes: time_tracking:kiosks - [Get Time Tracking Kiosk](https://documentation.bamboohr.com/reference/get-time-tracking-kiosk.md): Retrieves a single time tracking kiosk by its ID. Deleted kiosks return 404. OAuth Scopes: time_tracking:kiosks - [Delete Time Tracking Kiosk](https://documentation.bamboohr.com/reference/delete-time-tracking-kiosk.md): Soft-deletes a time tracking kiosk. Deletion is idempotent (REST API Standard 3.3): a 204 is returned whether or not the kiosk currently exists, so deleting a missing or already-deleted kiosk also returns 204. Once deleted, a kiosk is absent from List Kiosks and returns 404 on Get Kiosk. OAuth Scopes: time_tracking:kiosks.write - [Update Time Tracking Kiosk](https://documentation.bamboohr.com/reference/update-time-tracking-kiosk.md): Updates a time tracking kiosk using JSON Merge Patch (RFC 7396) semantics. Only the kiosk `name` is mutable. Content-Type: application/merge-patch+json is preferred because it names those semantics, but application/json is also accepted. OAuth Scopes: time_tracking:kiosks.write - [List Time Tracking Time Clocks](https://documentation.bamboohr.com/reference/list-time-tracking-time-clocks.md): Returns a paginated list of the company's time tracking time clocks. Supports an OData-style `filter`, an `orderBy` sort expression, and `select` sparse fieldsets. Results are sorted by name ascending when `orderBy` is omitted; name ordering is case-insensitive. Filtering and sorting are applied in memory over the cached GT Connect list (partner ordering is not relied on). A company with no GT Clocks connected returns an empty list, not a 404. Device health flags are reported as null while device status is temporarily unavailable. Pagination is page-based via `page` and `pageSize` (defaults: page 1, pageSize 20, minimum 10, maximum 100). OAuth Scopes: time_tracking:time_clocks - [Get Time Tracking Time Clock](https://documentation.bamboohr.com/reference/get-time-tracking-time-clock.md): Retrieves a single time tracking time clock by its ID. Device health flags are reported as null while device status is temporarily unavailable. OAuth Scopes: time_tracking:time_clocks - [Update Time Tracking Time Clock](https://documentation.bamboohr.com/reference/update-time-tracking-time-clock.md): Updates a time tracking time clock using JSON Merge Patch (RFC 7396) semantics: only the properties present in the body are applied. Only `name` and `timezone` are mutable, and at least one of them must be provided. Both changes are written through to the GT Clocks partner; writes are never served from cache, so a write returns 503 with a Retry-After header when the partner is unreachable. A successful write invalidates the cached device list so the next read reflects the change. Content-Type: application/merge-patch+json is preferred because it names those semantics, but application/json is also accepted. OAuth Scopes: time_tracking:time_clocks.write - [List Time Tracking Imports](https://documentation.bamboohr.com/reference/list-time-tracking-imports.md): Returns a paginated list of time tracking imports, newest first. Soft-deleted imports are never returned. OAuth Scopes: time_tracking:imports - [Create Time Tracking Import](https://documentation.bamboohr.com/reference/create-time-tracking-import.md): Creates a time tracking import from an uploaded CSV. The file is parsed, every row is validated and auto-corrected, and the import is returned in `DRAFT` so the rows can be reviewed before it is executed. OAuth Scopes: time_tracking:imports.write - [Get Time Tracking Import](https://documentation.bamboohr.com/reference/get-time-tracking-import.md): Retrieves a single time tracking import by its ID, including its resolved column mapping and row counts. Soft-deleted imports are not returned. OAuth Scopes: time_tracking:imports - [Delete Time Tracking Import](https://documentation.bamboohr.com/reference/delete-time-tracking-import.md): Deletes a time tracking import. The import is soft-deleted and stops being returned by any of the read endpoints, along with its rows. Deletion is terminal - a deleted import cannot be restored or executed - and idempotent, so an import that is already gone, or never existed, still reports success. Deleting a `COMPLETE` import does not undo it: the time tracking records its rows created stay in place and are deleted through the timesheet endpoints. An import that is being executed cannot be deleted until that execute finishes. OAuth Scopes: time_tracking:imports.write - [List Time Tracking Import Rows](https://documentation.bamboohr.com/reference/list-time-tracking-import-rows.md): Returns a paginated list of the rows of a time tracking import, in the order they appear in the uploaded file. Rows of a soft-deleted import are not returned. OAuth Scopes: time_tracking:imports - [Get Time Tracking Import Row](https://documentation.bamboohr.com/reference/get-time-tracking-import-row.md): Retrieves a single row of a time tracking import, including anything on it that failed validation and anything the import corrected. Rows of a soft-deleted import are not returned. OAuth Scopes: time_tracking:imports - [Update Time Tracking Import Row](https://documentation.bamboohr.com/reference/update-time-tracking-import-row.md): Corrects one row of a time tracking import using JSON Merge Patch (RFC 7396) semantics: only the properties present in the body are applied and omitted properties are unchanged. The row is auto-corrected and re-validated afterwards, so the response carries its refreshed `errors` and `corrections`. While the import is `DRAFT` any data field may be corrected; once it is `COMPLETE` only `hoursWorked` may be sent, and the new value is carried through to the time tracking record the row created. `Content-Type: application/merge-patch+json` is preferred because it names those semantics, but `application/json` is also accepted. OAuth Scopes: time_tracking:imports.write - [Execute Time Tracking Import](https://documentation.bamboohr.com/reference/execute-time-tracking-import.md): Executes a `DRAFT` time tracking import: every row is committed as a time tracking record and the import moves to `COMPLETE`. The work runs synchronously in one transaction, so either every row is committed or none is and the import is left in `DRAFT`; retrying after a 5xx is therefore safe. Every row must be free of validation errors first - correct them through the row endpoints, or the request is rejected and names the rows still failing. OAuth Scopes: time_tracking:imports.write - [List new hire packets](https://documentation.bamboohr.com/reference/f44b802c30cdea2b9076b3f82f99c74d.md): Returns a paginated list of new hire packet instances for the company. Each item is a flat summary (no sections, tasks, questions, or GTKY recipients). OAuth Scopes: onboarding - [Get new hire packet by id](https://documentation.bamboohr.com/reference/696f0a229cdde60b733568e3c4d043d9.md): Returns a single new hire packet instance with a derived status. Sub-resources (sections, tasks, questions, GTKY) are not included. OAuth Scopes: onboarding - [Create new hire packet](https://documentation.bamboohr.com/reference/ec1ba8e76f33960b018d0d7518fe97b5.md): Creates a new hire packet instance (draft) for an employee. Company configuration is applied for default inclusion flags. OAuth Scopes: onboarding.write - [Update new hire packet](https://documentation.bamboohr.com/reference/1ab0279d46023eb951a434f24df885f1.md): Updates an existing new hire packet instance. Sent, viewed, and completed timestamps are not changed through this endpoint. OAuth Scopes: onboarding.write - [Delete new hire packet](https://documentation.bamboohr.com/reference/caa7fc488bcfaef14125398f2ebb987d.md): Deletes a new hire packet instance by primary key. OAuth Scopes: onboarding.write - [Send new hire packet](https://documentation.bamboohr.com/reference/f49b0f1f2fb1ef2c408ba12916ee9baa.md): Sends the new hire packet for that packet's employee (email or onboarding experience workflow, depending on company configuration). The packet must be in draft state. OAuth Scopes: onboarding.write - [Cancel new hire packet](https://documentation.bamboohr.com/reference/19c7e26a1347ae7eb22919e9b0595c19.md): Cancels the new hire packet. Completed packets cannot be cancelled. OAuth Scopes: onboarding.write - [List employee onboarding experiences](https://documentation.bamboohr.com/reference/0158de7cde2a4c4cf577f0b25070d809.md): Returns onboarding experiences for the employee when the onboarding experience phase-1 and workflow framework company toggles are enabled, and at least one OnboardingExperienceWorkflow execution is running for them. Each item is projected from the employee’s new hire packet instance row for the same public id contract (no embedded NHP payload). OAuth Scopes: onboarding - [Create employee onboarding experience](https://documentation.bamboohr.com/reference/288aa996aba16d7a495c62321ea999a9.md): Creates (starts) an onboarding experience workflow for the employee’s existing new hire packet instance. Requires the onboarding experience phase-1 and workflow framework company toggles. Optional sentDateTime may be supplied for workflow idempotency (ISO 8601 or legacy datetime string accepted when non-empty). OAuth Scopes: onboarding.write - [Get employee onboarding experience by id](https://documentation.bamboohr.com/reference/847dd061d1d1859e7ce8cb3adfc9faf2.md): Returns a single onboarding experience when the onboarding experience phase-1 and workflow framework company toggles are enabled, the employee has at least one running OnboardingExperienceWorkflow (execution status RUNNING), the path id matches their current new hire packet instance id, and the row belongs to the employee. NHP fields are referenced by id only. OAuth Scopes: onboarding - [Get welcome new hires widget](https://documentation.bamboohr.com/reference/044949386f2d655c6a627ef53f9434b7.md): Returns the upcoming-new-hires data that powers the BambooHR home "Welcome New Hires" widget. Items are ordered by most recent hire date first. The list reflects the authenticated user's new-hire-packet and company-directory access — when either is missing the response is an empty list (not 403). Sensitive contact fields (work email, home email) are never returned. OAuth Scopes: onboarding - [Update GTKY answer visibility for a new hire packet](https://documentation.bamboohr.com/reference/update-new-hire-packet-gtky-answer-visibility.md): Shows or hides get-to-know-you (GTKY) question answers for the packet. Omit questionIds to toggle all answers (same as the legacy BFF POST /onboarding/questions/visibility/{newHirePacketId} with a visible query flag). Send questionIds to toggle only specific personal questions linked to this new hire packet. Requires the same edit access as other NHP writes. When the employee has a hire date set, updates are rejected once the company-local calendar date is on or after that date (same rule as GET /onboarding/questions/{newHirePacketId}, which redirects to expired in that case). Draft employees without a hire date are not blocked. OAuth Scopes: onboarding.write - [List Job Titles with Employees](https://documentation.bamboohr.com/reference/list-job-titles-with-employees.md): Returns every active, non-archived company job title (not only titles used in the pay grades and bands configuration) together with the employees who currently hold each title. The response is a JSON array of job title objects; each carries the job title `id`, its `title` name, and an `employees` array. Each employee entry exposes the internal employee ID (`id` here; the same identifier is `employeeId` on List Employees and `eeid` on the employee dataset) alongside the employee display `name`. This internal employee ID is not the editable Employee # (`employeeNumber`); using `employeeNumber` in its place may resolve to a different employee. An employee is omitted from a title's `employees` array when the authenticated caller lacks permission to view a required employee field (name, job title, or id), so an empty `employees` array does not necessarily mean no one holds that title; it can also mean the caller cannot see the employees who do. The array is empty when no job titles exist. This is a read-only view. Use this to see which employees occupy each job title; for the draft assignment of job titles to compensation levels (which returns no employee data), use Get Job Titles and Level Assignments (`get-job-title-level-assignments`) instead. OAuth Scopes: pay_grades_and_bands - [Get Compensation Level Group Status Counts](https://documentation.bamboohr.com/reference/get-compensation-level-group-status-counts.md): Returns the number of compensation level groups in each lifecycle status. The response is a JSON object of integer counts keyed by status: `draft`, `historic`, and `published`. When a published baseline exists, the `draft` count includes only draft groups that have at least one visited setup step (groups the user has actually started editing), not every draft group; when no published groups exist, it counts all draft groups. Use this for a tally of how many groups sit in each status; for the overall setup configuration status (whether each setup step is complete, with its blocking errors and warnings), use Get Levels and Bands Status (`get-levels-and-bands-status`) instead. OAuth Scopes: pay_grades_and_bands - [Get Levels and Bands Status](https://documentation.bamboohr.com/reference/get-levels-and-bands-status.md): Returns the configuration status of the Pay Grades & Bands (levels and bands) setup, broken down by setup step. The response is an object with four step keys, `levels`, `payBands`, `jobTitles`, and `review`, each reporting an `isComplete` flag plus `errors` (blocking issues) and `warnings` (non-blocking issues) arrays; the arrays are empty when a step has no outstanding issues. A setup step that has not yet been visited reports `isComplete: false` with empty `errors` and `warnings`, so empty arrays do not necessarily mean the step has no outstanding issues; the step simply has not been evaluated yet. For the `levels`, `payBands`, and `review` steps, each error or warning identifies the offending compensation level group and level; a `levelId` of `0` is a sentinel meaning the issue applies to the group as a whole rather than to a specific level. For `jobTitles`, each warning is a job title that is not yet assigned to a level. Use this to check whether the setup is complete before publishing. For the number of compensation level groups in each status (draft, published, historic), use Get Compensation Level Group Status Counts (`get-compensation-level-group-status-counts`) instead. OAuth Scopes: pay_grades_and_bands - [List Compensation Level Groups and Levels](https://documentation.bamboohr.com/reference/list-compensation-level-groups-and-levels.md): Returns the working draft configuration of compensation level groups and levels, including the per-group and per-level validation `errors` and `warnings` used by the setup wizard. When no draft configuration exists, the endpoint returns the currently published configuration instead. The response is a JSON object with a `groups` array; each group carries its `levels`, and each level flattens its pay band into `min`, `mid`, `max`, and `percentageRange` value objects (each wrapping a numeric `value` plus its own `errors` and `warnings`), along with `currencyCode`, `compensationType`, and the `jobTitles` assigned to that level. The pay band value objects are returned on this view, but their `errors` and `warnings` are not populated here; pay band values are validated only at review/publish. This is the editable draft/editor view: it reflects in-progress edits and surfaces levels-step validation state. For the same draft structure with pay-band-value validation populated use Get Pay Bands (`get-pay-bands`), and for the consolidated pre-publish validation across every step use Get Levels and Bands Review (`get-levels-and-bands-review`). For the currently published pay grades and bands without validation state, use Get Published Levels and Bands (`get-published-levels-and-bands`) instead. OAuth Scopes: pay_grades_and_bands - [Update Compensation Level Groups and Levels](https://documentation.bamboohr.com/reference/update-compensation-level-groups-and-levels.md): Creates or updates compensation level groups and their levels in the company draft configuration. If no draft exists yet, one is created from the currently published configuration before changes are applied, and published group and level identifiers are mapped to their new draft counterparts. This is a partial upsert. Groups and levels omitted from the request are left unchanged, so it does not overwrite the full set. A group is deleted when its `groupName` is blank or null and it has no levels. A level is deleted when its `levelName` is blank or null and a `levelId` is supplied. Only group and level names and structure are persisted here. The per-level `compensationType` in the request is not applied by this endpoint; a newly created level derives its compensation type from the group's existing compensation type (or `Salary` when the group has none), and existing levels keep their compensation type unchanged. Pay band values (`min`, `mid`, `max`, `percentageRange`, `currencyCode`) and job-title assignments may be present in the payload but are not saved by this endpoint; set pay band values with Update Pay Bands (`update-pay-bands`) and set job-title assignments with Replace Job Title Level Assignments (`replace-job-title-level-assignments`). Changes stay in draft until promoted. Publish them with Publish Draft Compensation Level Groups (`publish-draft-compensation-level-groups`). Read the current draft back with List Compensation Level Groups and Levels (`list-compensation-level-groups-and-levels`). On success the response is a JSON object `{"status":"success"}`. OAuth Scopes: pay_grades_and_bands.write - [Get Pay Bands](https://documentation.bamboohr.com/reference/get-pay-bands.md): Returns the working draft pay band configuration for every compensation level, including the pay-band-step validation `errors` and `warnings` used by the setup wizard. When no draft configuration exists, the endpoint returns the currently published configuration instead. The response is a JSON object with a `groups` array; each group carries its `levels`, and each level flattens its pay band into `min`, `mid`, `max`, and `percentageRange` value objects (each wrapping a numeric `value` plus its own `errors` and `warnings`), along with `currencyCode`, `compensationType`, and the `jobTitles` assigned to that level. A level is a percentage-based band when `percentageRange.value` is set, and a min-mid-max band when `percentageRange.value` is null. This view surfaces validation for the pay-band setup step; for the same structure with levels-step validation use List Compensation Level Groups and Levels (`list-compensation-level-groups-and-levels`), and for the published configuration without validation state use Get Published Levels and Bands (`get-published-levels-and-bands`). OAuth Scopes: pay_grades_and_bands - [Update Pay Bands](https://documentation.bamboohr.com/reference/update-pay-bands.md): Updates the pay band values (`min`, `mid`, `max`, `percentageRange`) for compensation levels in the company's draft pay grades and bands. This is the only endpoint that persists pay band values; Update Compensation Level Groups and Levels (`update-compensation-level-groups-and-levels`) defines the group and level structure but does not save band values. Job-title assignments are set separately with Replace Job Title Level Assignments (`replace-job-title-level-assignments`). Supply the level IDs returned by Get Pay Bands (`get-pay-bands`). If no draft exists yet, one is created from the published structure and the supplied published level IDs are remapped onto the newly created draft levels, so later reads return draft-specific level IDs. When `payBandType` is `percentRange`, `min` and `max` are derived from `mid` and `percentageRange` and any supplied `min`/`max` are ignored; when `minMidMax`, the supplied `min`/`mid`/`max` are stored and `percentageRange` is cleared. Every target level must belong to a draft group, otherwise the request fails with 400. Values are written to the draft only; publish them with Publish Draft Compensation Level Groups (`publish-draft-compensation-level-groups`). Returns an object with a single `status` field set to `success`. OAuth Scopes: pay_grades_and_bands.write - [Get Job Titles and Level Assignments](https://documentation.bamboohr.com/reference/get-job-title-level-assignments.md): Returns the working draft configuration showing which job titles are assigned to each compensation level, as used by the pay grades and bands setup wizard. When no draft configuration exists, the endpoint returns the currently published configuration instead. The response is a JSON object with a `groups` array; each group carries its `levels`, and each level lists the `jobTitles` assigned to it alongside its pay band flattened into `min`, `mid`, `max`, and `percentageRange` value objects (each wrapping a numeric `value` plus its own `errors` and `warnings`), `currencyCode`, and `compensationType`. The per-group and per-level `errors` and `warnings` arrays are always empty on this view; job-title assignment issues are reported by Get Levels and Bands Status (`get-levels-and-bands-status`) instead. Each job title carries a job title identifier and its name; no employee data is included. To see which employees currently hold each job title, use List Job Titles with Employees (`list-job-titles-with-employees`) instead. This is a read-only view. For the same group/level tree focused on level configuration use List Compensation Level Groups and Levels (`list-compensation-level-groups-and-levels`), for pay band values use Get Pay Bands (`get-pay-bands`), and for the published configuration without validation state use Get Published Levels and Bands (`get-published-levels-and-bands`) instead. OAuth Scopes: pay_grades_and_bands - [Replace Job Title Level Assignments](https://documentation.bamboohr.com/reference/replace-job-title-level-assignments.md): Replaces the complete set of draft job title-to-compensation-level assignments with the associations in the request. This is a full replacement: all existing draft job title assignments are deleted and replaced with those supplied, so any assignment omitted from the request is removed from the draft. Each entry pairs a job title with the compensation level it should map to. This endpoint writes only job-title assignments; define group and level structure with Update Compensation Level Groups and Levels (`update-compensation-level-groups-and-levels`) and set pay band values with Update Pay Bands (`update-pay-bands`). If no draft exists yet, one is created from the published structure and the supplied published level IDs are remapped onto the newly created draft levels, so later reads return draft-specific level IDs. Every target level must belong to a draft group, otherwise the request fails with 400. Discover job title and level IDs with Get Job Titles and Level Assignments (`get-job-title-level-assignments`). Assignments are written to the draft only; publish them with Publish Draft Compensation Level Groups (`publish-draft-compensation-level-groups`). Returns an object with a single `status` field set to `success`. OAuth Scopes: pay_grades_and_bands.write - [Get Levels and Bands Review](https://documentation.bamboohr.com/reference/get-levels-and-bands-review.md): Returns the pre-publish review of compensation level groups and levels with validation `errors` and `warnings` consolidated across every setup-wizard step: level naming, group-level checks, and pay band values. This reflects the working draft configuration; when no draft exists it falls back to the currently published configuration. Requesting this review marks all setup steps as visited for the draft, which changes subsequent Get Levels and Bands Status (`get-levels-and-bands-status`) results. The response is a JSON object with a `groups` array; each group carries its `levels` plus its own `errors` and `warnings`, and each level flattens its pay band into `min`, `mid`, `max`, and `percentageRange` value objects (each wrapping a numeric `value` with its own `errors` and `warnings`), along with `currencyCode`, `compensationType`, and the `jobTitles` assigned to that level. Use this for the complete validation picture that determines whether the configuration can be published. For the editable draft view that validates level and group issues but not pay band values, use List Compensation Level Groups and Levels (`list-compensation-level-groups-and-levels`) instead. For the currently published pay grades and bands without any validation state, use Get Published Levels and Bands (`get-published-levels-and-bands`) instead. OAuth Scopes: pay_grades_and_bands - [Get Published Levels and Bands](https://documentation.bamboohr.com/reference/get-published-levels-and-bands.md): Returns the currently published pay grades and bands as a JSON object with a `groups` array. Each group carries its published compensation levels, and each level flattens its pay band into `min`, `mid`, `max`, `currencyCode`, `percentageRange`, and `compensationType`, plus the job titles assigned to that level. Note the asymmetry: `min`, `mid`, and `max` are plain numbers, while `percentageRange` is an object (`LevelsAndBands-PayBandValue`) carrying its own validation state whose `value` is null for min-mid-max bands. Only published groups are returned; the `groups` array is empty when nothing has been published (this is a status filter, not a permission filter). Unlike the configuration-wizard endpoints, this published view omits the per-group and per-level validation `errors` and `warnings`. For the editable draft configuration with validation state, use List Compensation Level Groups and Levels (`list-compensation-level-groups-and-levels`) instead. OAuth Scopes: pay_grades_and_bands - [Publish Draft Compensation Level Groups](https://documentation.bamboohr.com/reference/publish-draft-compensation-level-groups.md): Publishes the company draft compensation configuration, promoting every draft compensation level group, along with its levels, pay bands, and job-title assignments, to the live published set. Any previously published groups are marked historic in the same operation. This is a bodyless POST that takes no request body and always publishes the entire current draft. Build the draft first with Update Compensation Level Groups and Levels (`update-compensation-level-groups-and-levels`), Update Pay Bands (`update-pay-bands`), and Replace Job Title Level Assignments (`replace-job-title-level-assignments`), then publish. Publishing is rejected with a 400 when the draft has unresolved validation errors or warnings. When no draft exists the call is a no-op and still returns success. On success the response is the JSON object `{"status":"success"}`. Read the published result back with Get Published Levels and Bands (`get-published-levels-and-bands`). OAuth Scopes: pay_grades_and_bands.write - [Upload Levels and Bands CSV](https://documentation.bamboohr.com/reference/upload-levels-and-bands-csv.md): Parses an uploaded levels and bands CSV and returns a preview of the parsed rows along with a suggested column mapping. This validates and previews only; it does not persist anything or create a draft. The response is a JSON object with `uploadData`, an array of row arrays holding the raw cell strings for each data row, and `columnMap`, which pairs each CSV column header with the field it maps to (`expectedColumnKey`), or null when the header is not recognized. Recognized field keys are `groupName`, `levelName`, `min`, `mid`, `max`, `compensationType`, `currency`, and `jobTitles`. Use this to confirm a spreadsheet before writing; to persist the data, build the draft with Update Compensation Level Groups and Levels (`update-compensation-level-groups-and-levels`), Update Pay Bands (`update-pay-bands`), and Replace Job Title Level Assignments (`replace-job-title-level-assignments`), then publish it with Publish Draft Compensation Level Groups (`publish-draft-compensation-level-groups`). OAuth Scopes: pay_grades_and_bands.write - [Delete Compensation Level Groups or Level](https://documentation.bamboohr.com/reference/delete-compensation-level-groups-or-level.md): Deletes compensation level configuration, with the behavior chosen by the `{segment}` path value. When `{segment}` is a group status (`draft`, `published`, or `historic`), every compensation level group in that status is deleted and the response is the object `{"status":"success"}`; deleting `draft` discards all in-progress edits and is the way to reset the working draft. When `{segment}` is a numeric compensation level ID, only that single level is deleted and the response is the updated groups-and-levels hierarchy, the same object shape returned by List Compensation Level Groups and Levels (`list-compensation-level-groups-and-levels`). Deleting a numeric level ID that does not exist is a no-op that returns 200 with the unchanged hierarchy. The accepted `{segment}` values are the group lifecycle statuses `draft`, `published`, and `historic`, or a numeric level ID. Discover level IDs with List Compensation Level Groups and Levels (`list-compensation-level-groups-and-levels`). Edit level and group structure with Update Compensation Level Groups and Levels (`update-compensation-level-groups-and-levels`), and promote draft changes to published with Publish Draft Compensation Level Groups (`publish-draft-compensation-level-groups`). This operation mutates the stored configuration directly and cannot be undone. OAuth Scopes: pay_grades_and_bands.write - [Photos](https://documentation.bamboohr.com/reference/photos.md) - [Get Employee Photo](https://documentation.bamboohr.com/reference/get-employee-photo.md): Returns an employee photo at the requested size. Available sizes are: `original` (full resolution), `large` (340×340), `medium` (170×170), `small` (150×150), `xs` (50×50), and `tiny` (20×20). The response shape is selected via standard HTTP content negotiation. By default the body is the stored image bytes and the `Content-Type` response header matches the body (`image/jpeg`, `image/png`, `image/bmp`, `image/gif`, or `image/tiff`). When the caller sends `Accept: application/json`, the body is a JSON object `{ mimeType, fileBase64 }` with the same image bytes base64-encoded. The JSON variant is not recommended for AI connector use, since the base64 payload is too large for an AI model to consume reliably as text input. For AI connectors that need to display or reference a photo, use the `photoUrl` field returned by `list-employees` instead. It is a time-limited signed URL that avoids transferring image bytes through the AI model's context. A 404 response covers three distinct cases: (1) the employee exists but has no photo on file (a normal, non-error state), (2) the employee ID does not exist, or (3) the size value is not one of the recognized options. The `x-bamboohr-error-message` response header distinguishes them: `Employee photo not found`, `Employee not found`, or `Size: "" is not a valid size option. Valid sizes are: xs, small, tiny, original, medium and large.`. Treat "Employee photo not found" as a normal "no photo on file" result rather than as a bad employee ID, permission failure, or other error to debug. OAuth Scopes: employee:photo - [Upload Employee Photo](https://documentation.bamboohr.com/reference/upload-employee-photo.md): Uploads a new photo for an employee. Accepts a `multipart/form-data` POST with a `file` field carrying raw binary image bytes (typical browser and SDK usage). An `application/json` POST with a `fileBase64` property is also accepted, but it is not recommended for AI connector use. The base64 payload is too large for an AI model to produce reliably in a single tool call. Supported formats: JPEG, PNG, BMP, GIF. Other formats (HEIC, SVG, AVIF, WebP) are rejected with 415. TIFF is accepted by the format gate but some variants may fail downstream. The image must be square within 1 pixel and at least 150×150 pixels. This endpoint does not perform cropping, so if your source image is not square, you must crop it before uploading. Photo upload through this endpoint is not a viable AI connector workflow. For interactive cropping or any AI-initiated photo change, redirect the user to the BambooHR web UI. Maximum file size is 20MB (applies to the decoded bytes for the JSON variant). The photo replaces the employee's current photo for all size variants. Employees may upload their own photo if the company has self-photo uploads enabled. OAuth Scopes: employee:photo.write - [Get Company Report](https://documentation.bamboohr.com/reference/get-company-report.md): **Deprecated. Use Custom Reports > Get Report by ID instead.** Returns the data from an existing saved custom report. Non-admins can find these reports in My Reports. Admins can find them in Custom Reports under the My Reports and Company Reports tabs. The report ID can be found by hovering over the report name in BambooHR and noting the ID in the URL. Standard Reports are not available via this endpoint, and report IDs are company-specific. The caller must have permission to view or access the report. The `format` query parameter is case-insensitive (`json`, `JSON`, `Json` are all accepted). If `format` is omitted, the output format is inferred from the `Accept` header, but only these exact values are supported: `application/json`, `text/xml`, `text/csv`, `application/pdf`, `application/vnd.ms-excel`. Any other `Accept` value (including `application/xml` and `*/*`) returns 404. OAuth Scopes: report - [Request Custom Report](https://documentation.bamboohr.com/reference/request-custom-report.md): **Deprecated. Use Datasets > Get Data from Dataset instead.** Generates an ad-hoc employee report based on a caller-specified list of fields and optional filters. Returns report data in the requested format (JSON, XML, CSV, XLS, or PDF). The report includes all employees regardless of status (both Active and Inactive), unlike the BambooHR UI which filters to Active employees by default. The request body may be submitted as JSON or XML. To submit JSON, set `Content-Type: application/json` exactly — any variation such as `application/json; charset=UTF-8` is not recognised as JSON and the body will be parsed as XML instead, which typically results in `400 Malformed XML`. To submit XML, set `Content-Type` to any other value; the body must be a `` document as described in the XML request body schema. The `format` query parameter is case-insensitive (`json`, `JSON`, `Json` are all accepted). If `format` is omitted, the output format is inferred from the `Accept` header, but only these exact values are supported: `application/json`, `text/xml`, `text/csv`, `application/pdf`, `application/vnd.ms-excel`. Any other `Accept` value (including `application/xml` and `*/*`) will return 404. Field IDs in the request that are unknown or that the caller does not have permission to view are silently omitted from the report — the endpoint still returns 200. The `filters` object supports `lastChanged` (ISO 8601 date-time to filter employees by last-modified date, with optional `includeNull` control) and `employeeIds` (restrict results to specific internal employee IDs). The maximum number of fields per request is 400. OAuth Scopes: report - [List Schedules](https://documentation.bamboohr.com/reference/scheduling-list-schedules.md): Retrieves a paginated list of all schedules for the company. Supports optional OData-style filtering and sorting. OAuth Scopes: scheduling:schedules, time_tracking - [Create Schedule](https://documentation.bamboohr.com/reference/scheduling-create-schedule.md): Creates a new schedule for the company. Rejects duplicate schedule data for the same location and configuration. OAuth Scopes: scheduling:schedules.write, time_tracking.write - [Get Schedule](https://documentation.bamboohr.com/reference/scheduling-get-schedule.md): Retrieves a specific schedule by its UUID. Schedules organize shifts for employees. OAuth Scopes: scheduling:schedules, time_tracking - [Delete Schedule](https://documentation.bamboohr.com/reference/scheduling-delete-schedule.md): Deletes a schedule by its UUID. Unworked shifts will be deleted as a result. OAuth Scopes: scheduling:schedules.write, time_tracking.write - [Update Schedule](https://documentation.bamboohr.com/reference/scheduling-update-schedule.md): Partially updates an existing schedule by its UUID. Fields not provided retain their existing values. OAuth Scopes: scheduling:schedules.write, time_tracking.write - [List Timezones](https://documentation.bamboohr.com/reference/scheduling-list-timezones.md): Returns a paginated list of timezones available for use when creating or editing schedules. Supports OData-style filtering on the `name` field. OAuth Scopes: scheduling:schedules, time_tracking - [Get Shift](https://documentation.bamboohr.com/reference/scheduling-get-shift.md): Retrieves a single shift by its UUID. Returns the full shift object including recurrence settings, assigned employee IDs, and status. Returns 404 if the shift does not exist or has been deleted. OAuth Scopes: scheduling:shifts, time_tracking - [Delete Shift](https://documentation.bamboohr.com/reference/scheduling-delete-shift.md): Deletes a shift by its UUID or composite recurrence ID. Use `recurrenceEditOption` to control the scope to delete one or many consecutive recurring shifts OAuth Scopes: scheduling:shifts.write, time_tracking.write - [Update Shift](https://documentation.bamboohr.com/reference/scheduling-update-shift.md): Updates a shift by its UUID. Fields not provided will retain their existing values. For published shifts, changes are not applied directly — they are stored as pending (`unpublishedChanges`) and take effect when the shift is published. `recurrenceEditOption` is required when the shift already has recurrence settings; ALL and FUTURE edits propagate to published sibling occurrences the same way, staging changes rather than applying them immediately. Sibling shifts may be permanently removed if they no longer conform to changed recurrence fields. OAuth Scopes: scheduling:shifts.write, time_tracking.write - [List Shifts](https://documentation.bamboohr.com/reference/scheduling-list-shifts.md): Lists shifts matching the given filters. Either provide `ids` (ignores all other filters) or provide `start`, `end`, and at least one of `employeeIds` or `scheduleIds`. The time window must be no longer than 1 month. Defaults to returning planned and published shifts. OAuth Scopes: scheduling:shifts, time_tracking - [Create Shift](https://documentation.bamboohr.com/reference/scheduling-create-shift.md): Creates a new shift in the specified schedule. OAuth Scopes: scheduling:shifts.write, time_tracking.write - [Publish Shifts](https://documentation.bamboohr.com/reference/scheduling-publish-shifts.md): Publishes one or more planned shifts, making them visible to employees. Shifts with scheduling conflicts are skipped and reported as failures. Returns 200 if all shifts succeed, 207 if some shifts failed due to conflicts, or 409 if all shifts failed due to conflicts. OAuth Scopes: scheduling:shifts.write, time_tracking.write - [Get Schedule PDF](https://documentation.bamboohr.com/reference/scheduling-get-schedule-pdf.md): Generates and streams a PDF of the schedule view for the given schedule and date range. OAuth Scopes: scheduling:schedules - [List Shift Assessments](https://documentation.bamboohr.com/reference/scheduling-list-shift-assessments.md): Lists shift assessments matching the given filters. A filter is required and must include at least one of: employeeId, shiftId, or a date filter (eq/gt/ge/lt/le on date). Results are scoped to the assessments the authenticated user may view. OAuth Scopes: scheduling:shifts - [Time Off](https://documentation.bamboohr.com/reference/time-off.md) - [List Time Off Policies](https://documentation.bamboohr.com/reference/list-time-off-policies.md): Returns all non-deleted time off policies for the company, sorted alphabetically by name. Only includes policies whose time off type has not been deleted. OAuth Scopes: time_off - [List Time Off Types](https://documentation.bamboohr.com/reference/list-time-off-types.md): Lists the company's active time off types — PTO options, vacation, sick leave, and other time off categories — along with the company's default hours-per-day schedule. Pass `mode=request` to filter to only types the authenticated employee has permission to request. Time off type names are company-configured labels; common terms like "PTO" may not appear verbatim and may be expressed as "Vacation" or another company-specific name. The returned list is also permission-filtered: an admin caller may see types (e.g., "Sick") that a non-admin caller does not, so the set available for a given user depends on the caller's role. If a user's term does not exactly match a returned type name, present the available types as options rather than choosing one heuristically. OAuth Scopes: time_off - [Get Time Off Balance](https://documentation.bamboohr.com/reference/get-time-off-balance.md): Returns time off balances for an employee across all assigned categories as of a given date. Each category's balance is calculated by summing all historical balance events (accruals, manual adjustments, used time off, and carry-over events) plus any future accruals and adjustments up to the specified date. To get current balances, pass today's date; to project future balances, pass a future date. Response defaults to XML unless Accept: application/json is provided. **This endpoint does not accept the `0` self sentinel.** Unlike Get Employee (`get-employee`), passing `0` as `employeeId` returns `404` with an empty body and the header `x-bamboohr-error-message: Employee not found`. To read the authenticated caller's own balances, first resolve their internal employee ID with `get-employee` using the id `0`, then call this endpoint with that ID. **Permissions.** Access is gated on the same Time Off tab view permission the web application uses. That permission is configured per access level and is **not** implied by the reporting structure: being an employee's manager does not by itself grant it, and a manager may receive `403` for their own direct reports. A caller without permission for the target employee receives an explicit `403` rather than an empty success, so the two cases are distinguishable: a `403` means access was denied, while an empty array with `200` means the employee has no assigned policies among the time off types this caller can view. Do not read a `403` as the employee having no time off, and do not read an empty array as a permission problem. Because the categories returned are limited to the time off types the caller can view for that employee, two callers can legitimately receive different subsets for the same person. Treat the returned set as what this caller may see, not as the employee's complete policy list. `list-employee-time-off-policies-v1_1` is the companion endpoint for the underlying assignments and is gated on the same permission. A category returning `0.00` is not an error and does not necessarily mean the time cannot be requested. Discretionary policies (for example Bereavement or FMLA) are granted as needed rather than accrued, so they normally report a zero balance while still being available to request. Use `policyType` to distinguish `accruing` from `discretionary` before characterizing a zero. OAuth Scopes: time_off - [Adjust Time Off Balance](https://documentation.bamboohr.com/reference/adjust-time-off-balance.md): Creates a balance adjustment for an employee's time off type. The adjustment is recorded as an override history item. Cannot adjust balances for discretionary (unlimited) time off types. OAuth Scopes: time_off.write - [Create Time Off History Item](https://documentation.bamboohr.com/reference/create-time-off-history.md): Creates a time off history item for an employee. For `used` type entries, a `timeOffRequestId` referencing an approved request is required. For `override` (balance adjustment) entries via the /history path, provide the `amount` and `timeOffTypeId` directly. The `eventType` defaults based on the URI path when omitted. OAuth Scopes: time_off.write - [List Time Off Requests](https://documentation.bamboohr.com/reference/list-time-off-requests.md): Returns time off requests within the specified date range. Both `start` and `end` query parameters are required (YYYY-MM-DD). The search is inclusive: requests whose date range overlaps the query window are returned. Results can be filtered by status, employee, time off type, or limited to requests the caller can approve. **Do not pass `employeeId=0` expecting the caller's own requests.** Unlike Get Employee (`get-employee`), the `0` self sentinel is not supported here and returns an empty array with HTTP `200` rather than an error, which is easily misread as the caller having no requests. Use `action=myRequests` for the authenticated caller's own requests, or resolve their internal employee ID with `get-employee` using the id `0` and pass that value. **An empty result does not mean the employee has no requests.** A caller who lacks permission to view another employee's time off receives an empty array with HTTP `200`, indistinguishable from an employee with no requests in the window. Before concluding that someone has no time off requests, confirm that the window is wide enough and that the caller can actually view that employee. This endpoint and Get Time Off Balance (`get-time-off-balance`) are gated independently, so neither one's outcome predicts the other's. A caller can receive `403` from the balance endpoint for an employee while still receiving that same employee's requests here, which has been observed for a manager viewing a direct report. Do not infer access to one endpoint from access to the other, and do not treat a result from one as evidence about the other. OAuth Scopes: time_off - [Create Time Off Request](https://documentation.bamboohr.com/reference/create-time-off-request.md): Creates a time off request for an employee. The request can be submitted with a status of `approved`, `denied`, or `requested`. Submitting `approved` or `denied` is only honored when the caller is an owner/admin or has view/edit access to the time off type field for the target employee; other callers receive 403. When honored, these statuses record the request directly and suppress approval notifications. Supplying a `previousRequest` ID performs a destructive supersede: the prior request's status is set to `superceded`, all approvals on its workflow are removed and the workflow is marked deleted, and any home-page notifications tied to that workflow are deleted. Accepts both JSON and XML request bodies. OAuth Scopes: time_off.write - [Update Time Off Request Status](https://documentation.bamboohr.com/reference/update-time-off-request-status.md): Updates the status of an existing time off request. Valid statuses are `approved`, `denied` (or `declined`), and `canceled`. Owner/admins can approve out of turn by completing all workflow steps at once; other approvers complete only their current step. Deprecated: use the approvals, denials, or cancellations process resources under /api/v1/time-off/requests/{id} instead. OAuth Scopes: time_off.write - [List Who’s Out](https://documentation.bamboohr.com/reference/list-whos-out.md): Returns a date-sorted list of employees who are out and company holidays for the specified period. Defaults to today through 14 days out when dates are omitted. Results include both `timeOff` entries (employee requests) and `holiday` entries, each identified by `type`. An empty array may mean no one is out, or that no holidays have been configured in the BambooHR company calendar — holidays must be set up there before they appear here. The `filter: off` parameter applies only to employee time-off entries; holidays are independently filtered per-employee based on holiday visibility settings, and that filter is not disabled by `filter: off`. OAuth Scopes: time_off - [List Employee Time Off Policies (v1)](https://documentation.bamboohr.com/reference/list-employee-time-off-policies-v1.md): Deprecated. Use **List Employee Time Off Policies (v1.1)** instead (`list-employee-time-off-policies-v1_1`). Returns the time off policies currently assigned to the specified employee, including policy ID, time off type, and accrual start date. OAuth Scopes: time_off - [Assign Time Off Policies (v1)](https://documentation.bamboohr.com/reference/assign-time-off-policies-v1.md): Deprecated. Use **Assign Time Off Policies (v1.1)** instead (`assign-time-off-policies-v1_1`). Assigns time off policies to an employee with accruals starting on the specified date. A null start date removes the existing assignment. On success, returns the current list of assigned policies. OAuth Scopes: time_off.write - [List Employee Time Off Policies (v1.1)](https://documentation.bamboohr.com/reference/list-employee-time-off-policies-v1_1.md): Returns the time off policies currently assigned to a specific employee, as a list of `{timeOffPolicyId, timeOffTypeId, accrualStartDate}` records. Use this to find which policy governs each time off type for this employee and when their accruals began. This is the per-employee assignment view; use `list-time-off-policies` for the company-wide policy catalog. Includes all policy types (accruing, manual, and unlimited); the v1 form of this endpoint excluded manual and unlimited types — v1.1 includes them. OAuth Scopes: time_off - [Assign Time Off Policies (v1.1)](https://documentation.bamboohr.com/reference/assign-time-off-policies-v1_1.md): Assigns time off policies to an employee with accruals starting on the specified date. On success, returns the current list of assigned policies including manual and unlimited policy types. OAuth Scopes: time_off.write - [List Who's Out](https://documentation.bamboohr.com/reference/list-whos-out-v1.md): Lists approved time off occurrences overlapping the requested date range, scoped to employees the caller can see. Results the caller lacks permission to view are silently excluded. Dates are interpreted in the company timezone. Results are sorted by start date ascending, then id ascending. OAuth Scopes: time_off - [List Time Off Request Comments](https://documentation.bamboohr.com/reference/list-time-off-request-comments.md): Lists the comments on a time off request. OAuth Scopes: time_off:requests - [Create Time Off Request Comment](https://documentation.bamboohr.com/reference/create-time-off-request-comment.md): Adds a comment to a time off request. OAuth Scopes: time_off:requests.write - [List Time Off Requests](https://documentation.bamboohr.com/reference/list-time-off-requests-v1.md): Lists time off requests, with support for filtering, sorting, and pagination. OAuth Scopes: time_off:requests - [Create Time Off Request](https://documentation.bamboohr.com/reference/create-time-off-request-v1.md): Creates a time off request on behalf of an employee. The request is created with status REQUESTED and enters the approval workflow. OAuth Scopes: time_off:requests.write - [Get Time Off Request](https://documentation.bamboohr.com/reference/get-time-off-request.md): Retrieves a single time off request by its ID. OAuth Scopes: time_off:requests - [Update Time Off Request](https://documentation.bamboohr.com/reference/update-time-off-request.md): Updates an existing time off request using JSON Merge Patch semantics: only the fields present in the body are changed, and `employeeNote` may be set to null to clear it. Accepts both `application/merge-patch+json` and `application/json`. Editing a request whose status is REQUESTED replaces the stored request and restarts its approval workflow, so the `id` in the response differs from the id in the path. That `id` is authoritative and should replace any id the client is holding; the id that was replaced returns 410 from then on. `requestedAt` is carried over from the replaced request, and editing a request whose status is APPROVED updates it in place, so `id` and `requestedAt` are both unchanged in that case. Changing `startDate` or `endDate` requires sending `dailyAmounts` in the same request, so the per-day breakdown always covers the stored range. Omitting it returns 422; the server does not redistribute amounts on the caller's behalf. OAuth Scopes: time_off:requests.write - [Approve Time Off Request](https://documentation.bamboohr.com/reference/create-time-off-request-approval.md): Approves a time off request. Completes the caller's step in the approval chain, or every remaining step when `bypass` is true. Returns the updated time off request, which remains in REQUESTED status when further approvals are still outstanding. OAuth Scopes: time_off:requests.write - [Deny Time Off Request](https://documentation.bamboohr.com/reference/create-time-off-request-denial.md): Denies a time off request. A single denial is final: it completes the caller's step and discards any remaining steps in the approval chain, so the returned time off request is always in DENIED status. OAuth Scopes: time_off:requests.write - [Cancel Time Off Request](https://documentation.bamboohr.com/reference/create-time-off-request-cancellation.md): Cancels a time off request. Available to the employee who requested the time off and to anyone with authority to manage it. A request can be canceled while it is REQUESTED, and after approval only while it has not started yet. Takes no request body. OAuth Scopes: time_off:requests.write - [Add Employees to Total Rewards](https://documentation.bamboohr.com/reference/add-total-rewards-employees.md): Add employees to Total Rewards. Each employee will have a Total Rewards profile created and will be notified if they are active users. OAuth Scopes: total_rewards.write - [Remove Employees from Total Rewards](https://documentation.bamboohr.com/reference/remove-total-rewards-employees.md): Remove employees from Total Rewards. Their Total Rewards profiles will be deleted. OAuth Scopes: total_rewards.write - [Set Total Rewards Onboarding Step Status](https://documentation.bamboohr.com/reference/set-total-rewards-onboarding-step.md): Set a Total Rewards onboarding step to completed or incomplete. Valid step names are defined by the Total Rewards onboarding configuration. OAuth Scopes: total_rewards.write - [Set Total Rewards Custom Disclaimer](https://documentation.bamboohr.com/reference/set-total-rewards-custom-disclaimer.md): Set the company-wide Total Rewards custom disclaimer text shown on employee statements. OAuth Scopes: total_rewards.write - [Remove Total Rewards Custom Disclaimer](https://documentation.bamboohr.com/reference/remove-total-rewards-custom-disclaimer.md): Remove the company-wide Total Rewards custom disclaimer. After removal, the default disclaimer will be shown on employee statements. OAuth Scopes: total_rewards.write - [Get Total Rewards Statement](https://documentation.bamboohr.com/reference/get-total-rewards-statement.md): Returns the full Total Rewards statement for the given employee, including compensation, benefits, bonuses, equity, reimbursements, and time-off data. OAuth Scopes: total_rewards - [Check Total Rewards Profile Availability](https://documentation.bamboohr.com/reference/check-total-rewards-profile.md): Check if the given employee has an active Total Rewards profile and the current user has permission to view it. Returns 204 when the employee has a profile and the user is authorized; 404 if the profile does not exist or the user lacks access. OAuth Scopes: total_rewards - [Get Printable Total Rewards Statement](https://documentation.bamboohr.com/reference/get-total-rewards-printable-statement.md): Generate and return a PDF printable version of the employee's Total Rewards statement. OAuth Scopes: total_rewards - [Training](https://documentation.bamboohr.com/reference/training.md) - [List Training Types](https://documentation.bamboohr.com/reference/list-training-types.md): Returns all training types for the company as an object keyed by training type ID. Each entry includes the training name, renewable status, renewal frequency, required status, due-date window for new hires, category, link URL, description, and self-completion permission. The authenticated caller must have access to training settings. OAuth Scopes: training - [Create Training Type](https://documentation.bamboohr.com/reference/create-training-type.md): Creates a new training type. Only 'name' is required; all other fields are optional. When 'renewable' is true, 'frequency' (months between renewals) must also be provided. The 'dueFromHireDate' field is only valid when 'required' is true. The authenticated caller must have access to training settings. OAuth Scopes: training.write - [Update Training Type](https://documentation.bamboohr.com/reference/update-training-type.md): Updates an existing training type. Only provided fields are updated. To remove a category, pass an empty string or null for the category field. Returns 405 when the training type cannot be modified. The authenticated caller must have access to training settings. OAuth Scopes: training.write - [Delete Training Type](https://documentation.bamboohr.com/reference/delete-training-type.md): Delete an existing training type. The authenticated caller must have access to training settings. Deleting a training type will only be successful if all employee trainings for this type have been removed prior to this request. OAuth Scopes: training.write - [List Training Categories](https://documentation.bamboohr.com/reference/list-training-categories.md): Returns all training categories for the company as an object keyed by category ID. Each entry contains the category ID and name. The authenticated caller must have access to training settings. OAuth Scopes: training - [Create Training Category](https://documentation.bamboohr.com/reference/create-training-category.md): Creates a new training category. The 'name' field is required. Returns the created TrainingCategory on success. The authenticated caller must have access to training settings. OAuth Scopes: training.write - [Update Training Category](https://documentation.bamboohr.com/reference/update-training-category.md): Updates the name of an existing training category. Returns 409 if a category with the same name already exists. The authenticated caller must have access to training settings. OAuth Scopes: training.write - [Delete Training Category](https://documentation.bamboohr.com/reference/delete-training-category.md): Delete an existing training category. The authenticated caller must have access to training settings. OAuth Scopes: training.write - [List Employee Training Records](https://documentation.bamboohr.com/reference/list-employee-trainings.md): Returns all training records for the specified employee as an object keyed by training record ID. Use the optional 'type' query parameter to filter by training type ID. Fields such as instructor, credits, hours, and cost are only included when enabled in the company's training settings. The authenticated caller must have permission to view the employee. OAuth Scopes: training - [Create Employee Training Record](https://documentation.bamboohr.com/reference/create-employee-training-record.md): Creates a new training record for the specified employee. The 'completed' date (yyyy-mm-dd) and 'type' (training type ID) are required. Optional fields include instructor, hours, credits, notes, and cost. The authenticated caller must have permission to add trainings for the employee. OAuth Scopes: training.write - [Update Employee Training Record](https://documentation.bamboohr.com/reference/update-employee-training-record.md): Updates an existing employee training record. The 'completed' date (yyyy-mm-dd) is required; all other fields are optional. Returns the updated TrainingRecord with HTTP 201. Returns 405 when the record cannot be updated. The authenticated caller must have permission to edit trainings for the employee. OAuth Scopes: training.write - [Delete Employee Training Record](https://documentation.bamboohr.com/reference/delete-employee-training-record.md): Delete an existing employee training record. The authenticated caller must have permission to view and edit the employee and training type. OAuth Scopes: training.write - [Webhooks](https://documentation.bamboohr.com/reference/webhooks.md) - [Get Webhook Post Fields](https://documentation.bamboohr.com/reference/get-post-fields.md): Returns an object containing the employee fields that can be included in the webhook post body for field-based webhooks. Also includes the related table and page records referenced by those fields. Use the field IDs or aliases from this response in the `postFields` map when creating or updating a field-based webhook. OAuth Scopes: webhooks - [List Webhooks](https://documentation.bamboohr.com/reference/list-webhooks.md): Returns all webhooks owned by the authenticated user. Each entry is a summary with the webhook's ID, name, URL, creation datetime, and last-fired datetime. Returns an empty array when no webhooks exist. Use "Get Webhook" to retrieve the full configuration of a specific webhook, including monitored fields and post fields when applicable, and events. OAuth Scopes: webhooks - [Get Webhook](https://documentation.bamboohr.com/reference/get-webhook.md): Returns the full configuration of a single webhook owned by the authenticated user, including its name, URL, format, monitored fields and post fields when applicable, events, creation datetime, and last-sent datetime. Returns 403 if the webhook exists but belongs to a different user, and 404 if the webhook does not exist. OAuth Scopes: webhooks - [Create Webhook](https://documentation.bamboohr.com/reference/create-webhook.md): Creates a new webhook for the authenticated user. The webhook will fire when the specified events occur or when any of the monitored fields change. The `monitorFields` array is required when `events` includes `employee.updated` or `employee_with_fields.updated`. If `events` is omitted, it defaults to `['employee_with_fields.updated', 'employee_with_fields.deleted', 'employee_with_fields.created']`, which means `monitorFields` is required by default. The `format` field is required. The response includes a `privateKey` that should be used to verify the authenticity of incoming webhook payloads via HMAC-SHA256. This key is only returned at creation time and cannot be retrieved again. For more details refer to the [webhooks documentation](https://documentation.bamboohr.com/docs/webhooks), including guides for [event-based](https://documentation.bamboohr.com/docs/event-based-webhooks) and [field-based](https://documentation.bamboohr.com/docs/field-based-webhooks) webhooks. For details on the payloads sent by each event, see the event reference: - [employee.created](https://documentation.bamboohr.com/reference/employee-created-webhook) - [employee.updated](https://documentation.bamboohr.com/reference/employee-updated-webhook) - [employee.deleted](https://documentation.bamboohr.com/reference/employee-deleted-webhook) OAuth Scopes: webhooks, webhooks.write - [Update Webhook](https://documentation.bamboohr.com/reference/update-webhook.md): Performs a full replacement update of a webhook — all request body fields overwrite existing values, so omitted optional fields revert to defaults. The `monitorFields` array must be non-empty when the webhook's events include `employee.updated` or `employee_with_fields.updated` (the default event set includes `employee_with_fields.updated`). The private key is not regenerated on update. Use List Webhooks to discover webhook IDs. OAuth Scopes: webhooks, webhooks.write - [Delete Webhook](https://documentation.bamboohr.com/reference/delete-webhook.md): Permanently removes a webhook owned by the authenticated user. A webhook can only be deleted by the same credentials that created it; attempting to delete another user's webhook returns 403. Use List Webhooks to find webhook IDs. OAuth Scopes: webhooks, webhooks.write - [Employee Created](https://documentation.bamboohr.com/reference/employee-created-webhook.md): Triggered when a new employee is created. ### Behavior & Constraints - **Creation Sequence**: When an employee is created, both `employee.created` and `employee.updated` events fire sequentially due to the create-then-initialize pattern. - **Data Availability**: The `data` object contains the `companyId` and `employeeId` of the newly created employee. - **Permission Checking**: This event does **not** enforce permission checking. The webhook will fire for all subscribers regardless of the API token's field-level permissions. ### Deprecation Notice **Note:** This event is the modern replacement for the legacy `employee_with_fields.created` event. While the legacy event is deprecated, it will remain available for the foreseeable future to support existing integrations. We encourage using this new event for all new development. **Important:** You cannot subscribe to both this new event and the legacy `employee_with_fields` events on the same webhook. Webhooks created without specifying any events will default to the legacy behavior, effectively subscribing to the `employee_with_fields` events automatically. - [Employee Updated](https://documentation.bamboohr.com/reference/employee-updated-webhook.md): Triggered when an employee record is updated and at least one of the monitored fields has changed. ### Behavior & Constraints - **Monitoring**: At least one `monitorField` is required when subscribing to this event via `POST /api/v1/webhooks`. - **Permissions**: For API-created webhooks, this event will not fire if the webhook creator lacks access to all monitored fields being changed. ### Detailed Description - **Creation Sequence**: When an employee is created, both `employee.created` and `employee.updated` events fire sequentially due to the create-then-initialize pattern. - **Field Consolidation**: When multiple fields change simultaneously, they may be consolidated into a single event. Currently, custom field updates and standard field updates are grouped separately and may fire as two events. - **Effective Dates**: For history-tracked fields (e.g., `jobTitle`, `payRate`), events fire only when changes take effect, not when future-dated changes are created. - **Changed Fields**: The `changedFields` array contains the API aliases for fields that changed and are monitored by this webhook. Aliases match those returned by `GET /api/v1/webhooks/monitor_fields`. ### Deprecation Notice **Note:** This event is the modern replacement for the legacy `employee_with_fields.updated` event. While the legacy event is deprecated, it will remain available for the foreseeable future to support existing integrations. We encourage using this new event for all new development. **Important:** You cannot subscribe to both this new event and the legacy `employee_with_fields` events on the same webhook. Webhooks created without specifying any events will default to the legacy behavior, effectively subscribing to the `employee_with_fields` events automatically. - [Employee Deleted](https://documentation.bamboohr.com/reference/employee-deleted-webhook.md): Triggered when an employee is deleted. ### Behavior & Constraints - **Permission Checking**: This event does **not** enforce permission checking. The webhook will fire for all subscribers regardless of the API token's field-level permissions. ### Deprecation Notice **Note:** This event is the modern replacement for the legacy `employee_with_fields.deleted` event. While the legacy event is deprecated, it will remain available for the foreseeable future to support existing integrations. We encourage using this new event for all new development. **Important:** You cannot subscribe to both this new event and the legacy `employee_with_fields` events on the same webhook. Webhooks created without specifying any events will default to the legacy behavior, effectively subscribing to the `employee_with_fields` events automatically. - [Company Integrations Updated](https://documentation.bamboohr.com/reference/company-integrations-updated-webhook.md): Triggered when company integrations are updated. ### Behavior & Constraints - **Permission Checking**: This event does **not** enforce permission checking. The webhook will fire for all subscribers regardless of the API token's permissions. - **Event Scope**: This event fires when any integration settings are modified for the company, including enabling, disabling, or updating integration configurations. - [Company Updated](https://documentation.bamboohr.com/reference/company-updated-webhook.md): Triggered when company information or company status changes. ### Behavior & Constraints - This event is emitted for general company updates. - When the underlying change is a company status change, the emitted event depends on the new status: - If the new status is `DELETED` or `CANCELLED`, the system emits `company.deleted` instead. - Otherwise the system emits `company.updated`. - [Company Deleted](https://documentation.bamboohr.com/reference/company-deleted-webhook.md): Triggered when a company status change results in the company being considered deleted/closed. ### Behavior & Constraints - This event is emitted when the new company status is `DELETED` or `CANCELLED`. - For other company updates and status changes, the system emits `company.updated`. - [List Webhook Logs](https://documentation.bamboohr.com/reference/list-webhook-logs.md): Returns an array of recent delivery log entries for a webhook. Use List Webhooks to find webhook IDs. Logs cover the last 14 days and are limited to 200 entries. The `lastAttempted` and `lastSuccess` fields are usually UTC datetimes in `YYYY-MM-DD HH:MM:SS` format, but may instead contain status strings such as `Webhook Not Found`. Returns an empty array if no deliveries have occurred in the lookback window. **Rate limiting:** This endpoint is rate-limited. When the rate limit is exceeded the server still returns HTTP 200, but the body is `{"error":{"code":429,"message":"Over rate limit, please try again in 60 seconds"}}` instead of the log array. Callers should check for this shape before processing the response as a log list. OAuth Scopes: webhooks - [List Monitor Fields](https://documentation.bamboohr.com/reference/list-monitor-fields.md): Returns the list of employee fields that can be monitored by a webhook. Monitor fields are only applicable to webhooks that use update events (`employee.updated` or `employee_with_fields.updated`). Use the field IDs or aliases from this response in the `monitorFields` array when creating or updating a webhook via Create Webhook or Update Webhook. OAuth Scopes: webhooks - [Update Company Industry Codes](https://documentation.bamboohr.com/reference/put-company-industry-codes.md): Updates the industry codes associated with a company. OAuth Scopes: company:details.write - [List Calendar Events](https://documentation.bamboohr.com/reference/list-calendar-events.md): Lists calendar events (time off, holidays, birthdays, and anniversaries) overlapping the requested date range. Events are sorted by start ascending, then type ascending (ANNIVERSARY, BIRTHDAY, HOLIDAY, TIME_OFF), then id ascending. TIME_OFF events represent approved requests only. Events the caller cannot view are silently omitted. OAuth Scopes: calendar:events - [Get Custom Table](https://documentation.bamboohr.com/reference/get-custom-table.md): Returns one custom table definition with its fields. IDs are strings and each has a numeric `legacyId` companion for legacy integrations. Use this for a known custom table ID. For browsing active custom tables, use List Custom Tables (`list-custom-tables`) instead. OAuth Scopes: employee:custom_fields - [List Custom Tables](https://documentation.bamboohr.com/reference/list-custom-tables.md): Returns a paginated list of active custom tables with their fields. IDs are strings and each has a numeric `legacyId` companion for legacy integrations. Use this for browsing active custom tables. For a known custom table ID, use Get Custom Table (`get-custom-table`) instead. OAuth Scopes: employee:custom_fields - [Create Custom Table](https://documentation.bamboohr.com/reference/create-public-custom-table.md): Creates a new custom table together with its columns in a single request. Requires the acting user to be an owner-admin. The `tab` value is the target tab's page ID; use Custom Fields > List Custom Fields (`list-custom-fields`) to find the `pageId` of an existing field on the desired tab. Use this to create a table backed by multiple columns. For adding a column to a table that already exists, use Create Custom Table Field (`create-public-custom-table-field`) instead. For a single standalone field not backed by a table, use Custom Fields > Create Custom Field (`create-public-custom-field`) instead. OAuth Scopes: employee:custom_fields.write - [Reorder Custom Table Fields](https://documentation.bamboohr.com/reference/reorder-public-custom-table-fields.md): Reorder a custom table's columns. Requires the acting user to be an owner-admin. The `columns` array must include the ID of every field currently in the table; a partial list or an ID that does not belong to this table is rejected with a `422`. Any `id` in the request body is ignored; the table reordered is always the one identified by the path. Returns the full updated custom table, including all fields in their new order. Use this for a lightweight pure-reorder without resending field definitions; to add, remove, or edit fields while also reordering, use Update Custom Table (`update-public-custom-table`) instead. OAuth Scopes: employee:custom_fields.write - [Update Custom Table](https://documentation.bamboohr.com/reference/update-public-custom-table.md): Updates an existing custom table's metadata and, optionally, replaces its full set of columns. Requires the acting user to be an owner-admin. The `tab` value is the target tab's page ID; use Custom Fields > List Custom Fields (`list-custom-fields`) to find the `pageId` of an existing field on the desired tab — changing `tab` moves the table to that page. Any `id` in the request body is ignored; the table edited is always the one identified by the path. Omitted optional fields reset rather than persist: leaving out `allowEdits` resets it to `true`, and leaving out `sortOrderDirection` resets it to `desc`. Omitting `columns` leaves existing columns unchanged; including `columns` replaces the entire column set, deleting any existing column whose `id` is not present in the array — include a column's `id` to update it in place, or omit `id` to add a new column. To add a single column without resending the rest, use Create Custom Table Field (`create-public-custom-table-field`) instead; to delete a single column without resending the rest, use Delete Custom Table Field (`delete-public-custom-table-field`) instead; to reorder columns without resending field definitions, use Reorder Custom Table Fields (`reorder-public-custom-table-fields`) instead. A request that changes nothing returns the table unchanged rather than an error. OAuth Scopes: employee:custom_fields.write - [Create Custom Table Field](https://documentation.bamboohr.com/reference/create-public-custom-table-field.md): Add a new column to an existing custom table; the new column is appended after the table's current columns. Requires the acting user to be an owner-admin. To create a table together with its initial columns, use Create Custom Table (`create-public-custom-table`) instead. To edit an existing column or replace the table's full column set, use Update Custom Table (`update-public-custom-table`) instead. For a single standalone field not backed by a table, use Custom Fields > Create Custom Field (`create-public-custom-field`) instead. OAuth Scopes: employee:custom_fields.write - [Delete Custom Table Field](https://documentation.bamboohr.com/reference/delete-public-custom-table-field.md): Deletes a single column from a custom table, including all data stored in it, and removes the field from any custom reports that reference it. This cannot be undone. Requires the acting user to be an owner-admin. Use this to remove one column; a 404 is returned when the table does not exist, when the field does not exist, or when the field exists but belongs to a different table, so repeating a delete returns 404 rather than succeeding. To replace the table's entire column set in a single request, use Update Custom Table (`update-public-custom-table`) instead. For a standalone field not backed by a table, use Custom Fields > Archive Custom Field (`archive-public-custom-field`) instead, which soft-archives the field rather than permanently deleting it. OAuth Scopes: employee:custom_fields.write - [API Support](https://documentation.bamboohr.com/reference/api-support.md) ## Pages - [Using OpenID Connect to Authenticate and Retrieve an API Key](https://documentation.bamboohr.com/page/authenticate-integration.md) - [OpenID Connect Login API](https://documentation.bamboohr.com/page/openid-connect-login-api.md) - [Single Sign-On (SSO) with OpenID Connect](https://documentation.bamboohr.com/page/single-sign-on-sso-with-openid-connect.md)