> ## Documentation Index
> Fetch the complete documentation index at: https://absentify.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# absentify REST API introduction and overview

> Overview of the absentify REST API for managing absence requests, approvals, allowances, users, departments, and webhook integrations programmatically.

### Welcome to the absentify developer documentation

Welcome to the developer documentation for absentify! This guide provides everything you need to start using the absentify API for efficient management of absence requests, approvals, and real-time integrations via webhooks.

<Note>
  Access to the API requires a Plus plan, which includes an API key and supports up to 150 requests per second per IP. For higher throughput, you can upgrade to 1500 requests per second for \$100/€100 per month by contacting support.
</Note>

### Choose your starting point

<CardGroup cols={3}>
  <Card title="Quick start guide" icon="rocket" href="./quick_start">
    Get started quickly with your first API request by following the quick start guide. It covers everything you need to set up and make your first API call with absentify.
  </Card>

  <Card title="Webhook integration" icon="link" href="./webhooks">
    Set up webhook integrations to receive instant notifications for events in absentify. Webhooks enable real-time connections for actions like request creation and status updates.
  </Card>

  <Card title="MCP server" icon="robot">
    Connect AI assistants to our documentation using the Model Context Protocol (MCP). Enable AI applications to search and retrieve relevant information from the absentify documentation.

    **MCP server URL:** `https://absentify.com/docs/mcp`
  </Card>
</CardGroup>

***

### Managing allowances through the API

Allowances are driven by **allowance rules**. A rule defines how much is granted per cycle, when the allowance year starts, and what happens to unused allowance. Every rule belongs to an **allowance type**, the balance that leave types draw from. Employees are connected to a rule through a **rule assignment** with a validity period, and individual corrections are recorded as **adjustments** on top of the rule.

The **Allowance Management** endpoints follow that model:

| Purpose          | Endpoints                                                                                                                                                                         |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Allowance types  | `GET`/`POST /allowance-types`, `GET`/`PATCH`/`DELETE /allowance-types/{id}`, `POST /allowance-types/reorder`, `PUT /allowance-types/{allowance_type_id}/default-rule`             |
| Rules            | `GET`/`POST /allowance-types/{allowance_type_id}/rules`, `PATCH`/`DELETE /rules/{id}`, `GET /rules/{rule_id}/members`                                                             |
| Rule assignments | `GET`/`POST /members/{member_id}/rule-assignments`, `PATCH`/`DELETE /rule-assignments/{id}`, `POST /members/{member_id}/rule-change`, `POST /members/{member_id}/manual-rule`     |
| Adjustments      | `GET`/`POST /members/{member_id}/adjustments`, `DELETE /adjustments/{id}`                                                                                                         |
| Balances         | `GET /members/{member_id}/allowances`, `GET /members/{member_id}/allowance-breakdown`, `POST /allowances/{id}/revert-carryover-override`                                          |
| History          | `GET /rules/{rule_id}/audit-log`, `GET /allowance-types/{allowance_type_id}/audit-log`, `GET /members/{member_id}/rule-audit-log`, `GET /members/{member_id}/allowance-audit-log` |

A few things to know before you integrate:

* All Allowance Management endpoints require an **admin** API key. The exceptions are the read-only `GET /allowance-types`, `GET /allowance-types/{id}`, and `GET /members/{member_id}/allowances`, which a manager key can also call for the members it is allowed to see.
* `GET /allowance-types` returns the ids that every rule, rule assignment, adjustment, and balance endpoint expects as `allowance_type_id`.
* Date-only fields (`rule_start_date`, `rule_end_date`, `accrual_anchor_date`, adjustment `date` and `expiry_date`) must be sent as `YYYY-MM-DD`. Values that are not real calendar dates, such as `2026-02-30`, are rejected.
* On a rule assignment, `rule_start_date` is the first day the rule applies and `rule_end_date` is the **last** day it applies. To cover a member through August 31, 2026, send `2026-08-31`. Send `null` for an open-ended assignment. `GET` returns the same convention, so a value you read can be sent straight back in a `PATCH`.
* On `PATCH /rule-assignments/{id}`, omit `rule_end_date` to leave the current end date unchanged, and send `null` to make the assignment open-ended.
* Amounts follow the allowance type's unit: days for day-based types, **minutes** for hour-based types.
* `proration_basis` controls how a partial year is calculated on yearly rules. `month` counts whole months and prorates the started month by day; `day` is calendar-day exact. It defaults to `month` and is ignored for monthly and bi-weekly cycles.
* `DELETE /rules/{id}` requires `reassign_to` whenever members are still assigned to the rule.
* Rule changes accept an optional `reason` that is stored in the audit trail. Creating, updating, or deleting a rule assignment requires a `reason` of 3–500 characters; leading and trailing whitespace is ignored, and whitespace-only values are rejected.

#### Managing allowance types

* `POST /allowance-types` creates a type without any rule, so nothing accrues on it until you add one through `POST /allowance-types/{allowance_type_id}/rules`. How many allowance types a workspace may have depends on its plan.
* `allowance_unit` is `days` or `hours` and **cannot be changed** after the type exists. On an `hours` type, every amount in the API is expressed in **minutes**.
* `PATCH /allowance-types/{id}` applies only the fields you send. Omit a field to leave its current value untouched, so two integrations changing different fields cannot overwrite each other. Sending `translations` replaces the stored translations; omit the field to keep them.
* In responses, `name` is translated into the language of the API key owner where a translation exists, while `default_name` is always the stored name.
* `DELETE /allowance-types/{id}` is rejected while leave types still draw from the type, while it is any member's default type, while it still has rules, and for the last remaining type of the workspace.
* `POST /allowance-types/reorder` sets the order the types appear in throughout the app and in `GET /allowance-types`. Send every id of the workspace. An id you leave out keeps its old position, which makes the resulting order ambiguous.
* `PUT /allowance-types/{allowance_type_id}/default-rule` points the organisation default at another rule. New members are put on it unless their department has a default rule of its own; members who already exist are not moved. The rule must be an active, shared rule of that allowance type.

#### Moving members between rules

* `POST /members/{member_id}/rule-change` moves a member to another rule. It ends the current assignment on `valid_from` and starts the new rule the same day, in one transaction, so there is neither a gap nor an overlap and the move is recorded as a single audit entry. Prefer it over deleting and recreating an assignment. Pass the assignment you are replacing as `current_assignment_id`, taken from `GET /members/{member_id}/rule-assignments`.
* `POST /members/{member_id}/manual-rule` takes a member off automatic accrual for one allowance type from `valid_from` on. Nothing accrues afterwards, and the balance is whatever you set through adjustments. Pass the member's active assignment as `current_assignment_id` and it is ended in the same transaction; without it, an assignment that overlaps `valid_from` makes the call fail. Send `null` when the member has no assignment.
* On both endpoints, `valid_from` is the first day covered and `valid_until` is the **last** day covered, in `YYYY-MM-DD` format, the same convention as `rule_end_date`. Send `null` for an open-ended assignment. Both require a `reason` of 3–500 characters.
* `GET /rules/{rule_id}/members` lists the members whose assignment to a rule has not ended yet. `limit` caps how many are returned (1–50, default 10) and `total` always counts all of them. There is no offset, so treat the list as a preview rather than full pagination.

#### Reading balances and history

* `GET /members/{member_id}/allowances` returns every fiscal year of every allowance type the member can use, oldest first, and is the read side of the deprecated `PUT` endpoint below. `allowance` is the effective entitlement and equals `rule_allowance` plus `adjustments`: the part the rule granted, plus the part that came from manual adjustments. Allowance types that are switched off for the member are left out.
* `GET /members/{member_id}/allowance-breakdown` explains a single fiscal year the way the ledger does in the app: the rule that was active, what accrued month by month, what was carried over, what expired, and which requests were booked out of it. When `legacy_unmigrated` or `no_allowance_for_year` is `true`, there is nothing to explain and the remaining fields are empty.
* `POST /allowances/{id}/revert-carryover-override` drops a carry-over that was set by hand and recomputes the member's allowances before the response returns. The `id` is the `member_allowance_id` from the breakdown, and the `brought_forward` it returns is the value from **before** the revert. Read the allowances again for the recomputed figure.
* The four audit endpoints answer different questions: `GET /rules/{rule_id}/audit-log` for one rule and its assignments, `GET /allowance-types/{allowance_type_id}/audit-log` for every rule of a type, `GET /members/{member_id}/rule-audit-log` for which rules a member was put on or moved to, and `GET /members/{member_id}/allowance-audit-log` for hand-set balances, carry-over overrides, and deleted adjustments. All return the newest entries first.
* On the rule and allowance-type logs, `take` controls how many entries you get (1–200, default 100); the member allowance history returns at most the 200 newest entries. The `changes` object depends on `event_type`: a rule edit carries `{ field: { from, to } }` pairs, a rule change carries `from_rule_id` and `to_rule_id`.
* A member moving to another rule is filed under the rule they moved **to**, with the previous rule in `changes.from_rule_id`. Rules that were deleted keep their history, and the allowance-type audit log is the only place those entries can still be read.

<Warning>
  **Changed on August 10, 2026:** `rule_end_date` used to be read as the first day the rule no longer applied, so an assignment created with `2026-08-31` stopped covering the member after August 30. It is now the last day the rule applies, and the same request covers August 31. If your integration added a day to compensate, remove that adjustment.
</Warning>

<Warning>
  `PUT /members/{id}/allowance/{allowance_type_id}/{year}` is **deprecated**, and in a workspace that uses the rule-based model its `allowance` field is **ignored**. The request is accepted, but the value has no effect, so writing a value and reading it back returns the amount the rule grants, not what you sent. This is deliberate: it restores the behavior integrations were built against before the rule model, when the calculation engine owned that value.

  To change an entitlement, use `POST /members/{member_id}/adjustments` for a one-off correction or a rule for a recurring entitlement. `brought_forward`, `compensatory_time_off`, `set_as_default`, and `disabled` keep working wherever the request is accepted.

  Two further responses to handle. While a workspace is locked, meaning a migration is running or it was rolled back to the previous model, the endpoint rejects the whole request with a conflict instead of applying part of it. If no rule assigns the member that allowance type for the requested year, or the year lies outside their employment period, it returns **404 Not Found**. That is a permanent condition, so do not retry it.

  The `allowance` field **returned** for a member is unaffected: it is still the effective allowance, the amount granted by the rule plus all adjustments. To read entitlements, use `GET /members/{member_id}/allowances`, which reports the same value per year and splits it into `rule_allowance` and `adjustments`.
</Warning>

***
