BambooHR Sensor
What it ingests
Org chart and role context from BambooHR — the employee directory, not time-off or compensation:
| BambooHR object | Ontology entity | Signal |
|---|---|---|
| Employee | Person (identity + role properties) | employee |
| Department / division | Organization | employee |
An employee is identity — they resolve to Person via work email and a stable BambooHR employee id, the same contract as a HubSpot contact. Job title, department, and location land as properties on that Person. The employee's department (and division, when present) is an Organization with a MEMBER_OF edge; a department is PART_OF its division. The supervisor, when the directory exposes it, is RELATED_TO by name.
This is BambooHR alone. Workday is a different HRIS with a different API and has its own Workday sensor.
Read-only and poll-based against https://{companyDomain}.bamboohr.com/api/v1. BambooHR webhooks exist but are configured in the BambooHR UI, never via API, so they cannot be provisioned at install time.
Credential
References a bamboohr_api_key credential by id. The secret is a BambooHR API key. BambooHR authenticates with HTTP Basic: the key as the username and the literal x as the password.
The company subdomain is not part of the secret. It is a required config field (see below) interpolated into https://{companyDomain}.bamboohr.com.
curl -sS -X POST https://your-corveil-host/api/credentials \
-H "Authorization: Bearer <admin>" -H "Content-Type: application/json" \
-d '{"type":"bamboohr_api_key","name":"acme-bamboohr","secret":"<api-key>"}'OAuth (BambooHR's developer-portal marketplace app) is out of scope in v1.
Config fields
| Key | Required | Notes |
|---|---|---|
company_domain | yes | The subdomain in your BambooHR URL. If you log in at https://acme.bamboohr.com, this is acme. A full URL is accepted and stripped to the slug. Do not include a path. |
There is no default_entity_type. This source emits Person and Organization, so a single override would silently mistype the rest.
Provider-side setup
- In BambooHR, click your profile photo → API Keys.
- Create a key. Copy it immediately — you will not see it again.
- Store only the key value, not
key:xorBasic …. - Note your company subdomain (
acmeinacme.bamboohr.com). - Confirm Company Directory (or at least Company Org Chart) is shared with the access level that owns the API key. If both are off, the directory endpoint returns 403
Directory disabled for this accountand Test connection fails.
Wire-up
POST /api/sensors
{
"sensor_type": "bamboohr",
"name": "Acme BambooHR",
"config": {
"company_domain": "acme"
},
"credentials": { "api_key": "<bamboohr_api_key credential id>" }
}Verify
Run Test connection. It authenticates the key against GET /api/v1/employees/directory, so a 401/403 fails at save/test rather than on the first poll. A "Directory disabled" error means the Company Directory / Org Chart sharing settings, not a bad key.
Once polling, employees_collected appears in the per-poll summary log.
How incremental sync works
Worth knowing, because it explains a few behaviours you may notice.
- Each poll re-reads the whole directory. BambooHR returns every published employee in one response and does not paginate. Typical HRIS sizes fit in a single request.
- A title or manager change re-ingests. Event ids include a fingerprint of the role-context fields (
bamboohr:employee:<id>:<fingerprint>), sosensor_eventstreats the change as a new event. The Person itself upserts on the stablebamboohr:employee:<id>. - Deletes are invisible. Someone vanishing from the directory is not treated as a deletion.
- The fieldset is company-configured. A tenant that shares only the org chart omits
supervisor,department,division,location, and work email. Names and job titles still land.
Not included
- Workday. A different HRIS; do not configure this source against Workday.
- OAuth / marketplace apps. Only needed for multi-customer marketplace distribution.
- Webhooks. BambooHR supports them, but subscriptions are created in the BambooHR UI, never via API — so they cannot be provisioned at install time. Polling is the supported path.
- Time-off, compensation, custom reports, files. Deferred.