Skip to content

Concepts

People, jobs and effective dates

On this page

A person has a profile (names, contact details, custom fields) and a job history: rows that each hold a job from one day to another. Bizisy keeps the whole history, so any read can be asked "as of" a day, past or future.

Job rows#

Each row has valid_from, its first day, and valid_to, the first day it no longer applies (null: open-ended), and the job on those days: title, unit, manager, location, legal entity, employment type, FTE and contract terms. A person's current job is the row that covers today; history lists every row.

JSON
{
  "id": "j1",
  "valid_from": "2024-01-15",
  "valid_to": null,
  "title": "Engineer",
  "unit": { "id": "u2", "name": "Engineering" },
  "manager": { "id": "p2", "name": "Rui Costa", "title": "CTO", "photo_url": null },
  "employment_type": "full_time",
  "fte": 1,
  "reason": "hire",
  "contract_type": "fixed_term",
  "contract_end_date": "2026-01-14"
}

reason says why a row started: hire, change, promotion, transfer, termination, rehire or correction.

Status#

statusMeaning
pre_hireHired with a start date in the future.
activeEmployed today.
terminatedTheir last day has passed.

Effective dates#

Changes to a job take effect on a day, never "now" by accident:

  • org.people.hire: the first row, from start_date (a future date makes them pre_hire).
  • org.people.change_job: the current row ends at effective_date and a new one starts there with the changed fields. It can be in the future: the change is scheduled and shows up when that day comes.
  • org.people.terminate: employment ends after last_day (inclusive), today or in the future.
  • org.people.rehire: a new employment period for someone who left.
  • org.people.correct_job: fixes a row in place (a typo in a title, a wrong date), without a new row.

Bizisy refuses a change that would leave the history wrong: a manager who isn't employed that day, a reporting cycle, two rows starting the same day. The error's hint says what to do instead, often to use correct_job.

Reading "as of" a day#

org.people.list, org.people.get and org.chart.get take as_of (YYYY-MM-DD, default today in the company's time zone). With a future date you see scheduled changes; with a past date, the company as it was.

Shell
curl https://api.bizisy.com/v1/org/chart.get \
  -H "Authorization: Bearer $BIZISY_API_KEY" -H "Content-Type: application/json" \
  -d '{"as_of": "2026-12-01", "by": "unit"}'

The team lead as default manager#

Each unit can have a team lead (the unit's head, set with org.units.set_head). When someone joins a unit and you don't say who their manager is, the lead of that unit becomes their manager (the team lead joining their own unit gets the parent unit's lead). This applies on every path into a team:

CallNo manager given meansTo choose yourself
org.people.hire, org.people.rehirethe lead of unit_idsend manager_id (null for none)
org.people.change_job with a new unit_idthe lead of the new unitsend manager_id (the current one to keep it, null for none)
org.setup.applythe lead of the person's unitsend manager_email (null for none)
org.people.import_csvthe lead of the row's teamfill manager_email, or write none

The result says when it happened: manager_default ({ "unit_id", "unit_name" }, or null) on hire, rehire and change job, and team_lead_managers (a count) on imports. The person.hired, person.job_changed and person.rehired webhooks carry manager_source: "team_lead" and manager_lead_unit_id. Setting a lead changes no one's manager today, and corrections (org.people.correct_job) never default the manager.

Approvals#

When the company requires approval for job changes or terminations, change_job and terminate create a request instead of a row (Approvals).

Something missing or wrong on this page? Write to hello@bizisy.com.

Developer docs