Skip to content

Concepts

Approvals

On this page

A company can require approval before some changes take effect: job changes, terminations and pay changes, each set separately in Settings → Approval rules. When approval is required, the write doesn't apply: it creates a request, and the change happens when the last approver approves.

Your integration must handle both outcomes of the same call.

Settings#

org.approvals.settings.get says what applies (owners, admins and HR):

ModeWho approves
offNobody: the change applies at once (the default)
hrAn owner, admin or HR member
managerThe person's manager today; with no manager, their team lead (or the lead of a team above); HR when none of them can
manager_then_hrBoth, in that order

Pay changes offer off and hr only. Settings change only in the app, never through a key or MCP, so an assistant can't switch approval off.

A write that becomes a request#

org.people.change_job and org.people.terminate return an approval field:

  • null: no approval was needed; the change applied.
  • status: "pending": a request was created and the change waits. waiting_for is the step (manager or hr), approvers who can decide it, then the step after it.
  • status: "approved" with automatic: true: approval was required, but no one else could give it (note: proposed_by_approver when you are the only approver, no_other_approver otherwise), so it was approved at once and the change applied.
JSON
{
  "data": {
    "id": "p1",
    "title": "Engineer",
    "approval": {
      "id": "apr1",
      "status": "pending",
      "waiting_for": "manager",
      "approvers": ["Rui Costa"],
      "automatic": false,
      "note": null,
      "fallback": false,
      "then": "hr"
    }
  }
}

While a request waits, the person's job is unchanged. A person can have one open job change request at a time. A dry run shows the same approval field, so you know in advance whether a change would become a request.

Following a request#

  • org.approvals.list: open (default), closed or all requests you may see; person_id narrows to one person.
  • org.approvals.get: one request, with its steps and who can decide.
  • The approval.decided webhook tells you when a job change or termination is approved (its person event, such as person.job_changed, is sent too) or rejected. Nothing is sent while a request waits.

Who decides#

A manager step is decided by the person's manager. When the person has no manager, or their manager has left, the team lead of their unit (or of the nearest unit above with a lead) decides it instead; the step's team_lead says which unit and why (reason: no_manager or manager_left). HR decides the step when no manager or lead can, and the step says why: team_lead_blocked when the proposer set or removed that unit's lead, or moved or archived the unit, in the last 30 days; untrusted when the manager or lead had no Bizisy login before the request (no_login) or the proposer invited them in the last 30 days (invited_by_proposer). Who decides is fixed when the request is made.

Approving and rejecting happen in the web app, by a person: org.approvals.approve and org.approvals.reject refuse API keys and connected apps. A proposer never approves their own app request, and nobody decides about themselves.

The proposer, or an owner, admin or HR member, can withdraw a waiting request with org.approvals.cancel, which works through an API key for job and termination requests.

A request whose effective date has passed is applied backdated when approved; 30 days after that date it expires.

See Handle approvals for a worked example.

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

Developer docs