Skip to main content
The API can change things: personal and contact details, job changes, pay changes and leave requests. Every write calls the same code the andteam console calls. So the tenant’s HRIS locks, approval chains, the self-approval guard, notifications and audit apply, because they are already in the path. There is no flag to skip approval.

What a key needs

  • A Write switch on the field group the write changes. Write implies Read. Write exists for Personal contact, Personal details, Job history, Pay and Leave, and for Hires, which has a Write switch only. A key with the Read switch alone answers write-not-allowed. See Field groups.
  • A named requester. Every write key names a console user who holds the permission for each write the key may make, for example requesting a pay change. Approval chains that route to “the requester’s manager” start from this person. Nobody approves their own request, so the requester can never approve what the key files.
  • requestedBy, optionally. A request body may name another requester: an andteam user id or work email, such as the hiring manager in your ATS. That person is checked for the same permission over that employee. If the check fails the request is refused with requester-not-allowed. It is never put back on the key’s requester.
If the requester loses the permission or leaves, the key’s writes answer requester-not-allowed and its reads keep working.

202 or 201

A write never approves itself. With a chain, a *.decided webhook is sent when the chain ends or the request is withdrawn: job_change.decided, pay_change.decided or leave_request.decided. Its data.requestedVia.keyId is the key that filed the request, so you can match a decision to your own call. See Webhooks and Employee events.

Everything the console does

Because a write is the console’s own request:
  • HRIS locks. A field the tenant’s HRIS owns for this person is refused with field-locked, which names every locked field. Nothing is written. Correct the field in the HRIS, which owns the record.
  • Approval chains. The tenant’s chain for the action decides. A step that resolves to nobody is approval-chain-unresolvable.
  • Audit. The employee’s history and the request’s approval history record the key as the actor, with the requester it acted for. Every request also has its own row in the tenant’s API audit.
  • Notifications. The employee is told what changed or what was requested for them, and by which system.
  • Letters. The API never sends a letter. After an approved job or pay change, HR sees a letter to send in andteam.

Check before you send

Every POST that creates something takes ?validate_only=true. It answers 200 with what would happen and writes nothing: the approval steps and who they resolve to, the knock-ons (“3 reports also move”) and, for leave, the balance after the request.

Every write needs two headers

A POST needs an Idempotency-Key. A PATCH needs If-Match. See Retries and versions. A body that is wrong is one 422 validation-failed. Its errors lists every field at once, each with a pointer, a code and a detail, so you fix them in one round.

Change personal details

PATCH /v1/employees/{id} is a JSON Merge Patch (RFC 7396) of preferredName, personalEmail, mobile, homeAddress, dateOfBirth and nationality. Each field needs the Write switch of its group: Personal contact for personalEmail, mobile and homeAddress, Personal details for the rest. Read the employee first and send its ETag as If-Match.
The answer is 200 with the employee and a new ETag. A part of homeAddress sent as null is removed; a part left out is kept. Legal first and last names, work email, Directory and Positions fields and Special categories are not writable.

Request leave

POST /v1/employees/{id}/leave-requests submits leave in the employee’s name through the leave approval chain. The balance and per-request caps are checked as in the portal.
The answer is 202 with awaiting_approval, or 201 with approved when the chain has no steps. A refusal is 422 validation-failed with a code in errors, such as insufficient-balance or over-cap. Sick leave is refused (sick-leave-in-portal): the sick note belongs in the portal. The employee is told which system made the request and can withdraw it in the portal. leave_request.submitted is sent.

File a job change with pay

POST /v1/employees/{id}/job-changes files a promotion, transfer or regrade with an effectiveDate. Send the facts that change, and a pay block when pay rides along. The pay change is filed with the job change in one transaction, so there is never a promotion without its pay change. The pay block needs the Write switch on Pay as well.
Corrections and changes of terms are made in andteam. The API answers 422 with the code not-supported. A change already waiting for the person is pending-change-exists, with the existingId.

File a pay change

POST /v1/employees/{id}/pay-changes takes a kind (increase, promotion or adjustment), an effectiveDate, the whole package as components[], and a reason kept as the change’s note. The package is checked against the tenant’s compensation rules.
A correction or a removal is made in andteam. A person in a protected group is not found unless the key’s Pay approval includes protected groups. See Approvals.

Withdraw a request

POST /v1/job-changes/{id}/withdraw, POST /v1/pay-changes/{id}/withdraw and POST /v1/leave-requests/{id}/withdraw take back a request while it waits. Only the key that filed it may withdraw it. Anything else is not-withdrawable. Each withdraw needs an Idempotency-Key. The matching *.decided event is sent with status: "withdrawn". Read a request back at any time with GET /v1/job-changes/{id}, GET /v1/pay-changes/{id} or GET /v1/leave-requests/{id}.

New hires

An ATS starts a hire with POST /v1/hires. That is a draft offer for HR, not a starter. See New hires from an ATS.