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

# Approval structures

Configure expense report approval workflows through the Findity Admin API — based on departments, dimensions, or a combination of both.

Configure approval structures for an organization through the Findity Admin API — controlling how expense reports are routed to the correct approvers based on departments, dimensions, or a combination of both.

## Key Concepts

An **approval structure** defines the rules for who approves expense reports within an organization. Findity supports two approval models that can be used independently or combined:

* **Department-based approval** — Approvers are assigned to departments in the [organization structure](/docs/departments-new). When a user submits an expense report, it is routed to the approver of the user's department.
* **Dimension-based approval** — Approvers are assigned to specific [dimension](/docs/dimensions-new) values (e.g., a cost center or project). When a user selects a dimension value on an expense, the report is routed to the approver of that value.

Each approver assignment has the following properties:

| Property | Description |
| - | - |
| `personId` | The `personID` of the user who acts as the approver |
| `sortOrder` | Position in the approval chain (e.g., `0` for first approver, `1` for second). Determines the sequence for multi-step approval |
| `amountLimit` | Maximum amount the approver is authorized to approve. Set to `null` for no limit |
| `id` | Unique identifier for the approver assignment |

### Approval Steps

Findity supports up to **3 approval steps** per structure. Each step is a level in the approval chain:

| Step | Example | `sortOrder` |
| - | - | - |
| First approver | Department manager | `0` |
| Second approver | Division head | `1` |
| Third approver | CFO | `2` |

When an expense report is submitted, it passes through each step in order. If an approver's `amountLimit` is exceeded, the report moves to the next step automatically.

> [!WARNING]
>
> Approval must be **activated in the admin web client** (Marketplace) before it can be configured via the API. The API
> manages approver assignments but does not enable or disable approval itself.

## API Endpoints

Approval structures are managed through two sets of endpoints depending on the approval model:

### Department-Based Approval

Approvers are configured as part of the organization structure. All endpoints use the Admin API base URL:

```
https://expense.findity.com/api/admin
```

| Operation | Method | Endpoint |
| - | - | - |
| Get organization structure | `GET` | `/organizations/externalid/{externalId}/organizationalunits/` |
| Update organization structure | `PUT` | `/organizations/externalid/{externalId}/organizationalunits/` |

### Dimension-Based Approval

Approvers are assigned to specific dimension values:

| Operation | Method | Endpoint |
| - | - | - |
| Get dimension approvers | `GET` | `/organizations/externalid/{externalId}/customdimensions/{dimensionId}/approvers/` |
| Update dimension approvers | `PUT` | `/organizations/externalid/{externalId}/customdimensions/{dimensionId}/approvers/` |

### Required Headers

Include these headers with every request:

| Header | Value |
| - | - |
| `Content-Type` | `application/json` |
| `X-Findity-ApiVersion` | `3` |
| `Authorization` | `Bearer {access_token}` |

## Step 1 — Choose an Approval Model

Decide which approval model fits your organization:

| Model | Use When | How Approvers Are Determined |
| - | - | - |
| Department-based | Each department has a fixed manager who approves all expenses | User's `organizationalUnitId` → department's `approvers` array |
| Dimension-based | Approval depends on a dynamic value like cost center or project | Dimension value selected on expense → value's assigned approvers |
| Combined | Users belong to departments but work on projects with separate approvers | Findity checks dimension approvers first, then falls back to department approvers (or vice versa, based on priority order) |

> [!NOTE]
>
> When combining department and dimension approval, the **priority order** determines where Findity looks first for an
> approver. Configure this in the admin web client by ordering the approval structure boxes — the box on top is checked
> first. API endpoints for managing priority order programmatically are not yet publicly available but are under
> development.

## Step 2 — Set Up Department-Based Approval

Assign approvers to departments by updating the organization structure. Each department in the tree has an `approvers` array.

```bash bash theme={"system"}
PUT /organizations/externalid/{externalId}/organizationalunits/
```

### Approver Object Properties

| Property | Type | Required | Description |
| - | - | - | - |
| `personId` | string | Yes | The `personID` of the user who acts as approver |
| `sortOrder` | integer | Yes | Position in the approval chain (`0` = first, `1` = second, `2` = third) |
| `amountLimit` | number / null | No | Maximum amount this approver can approve. `null` means no limit |

### Example: Assign Approvers to a Department

This example updates a department with two approval steps — a manager who can approve up to 5000, and a director with no limit:

```json theme={"system"}
{
  "id": "dept-sales-001",
  "name": "Sales",
  "description": "Sales department",
  "approvers": [
    {
      "personId": "8a5c9c38923312df019233426f7d04dd",
      "sortOrder": 0,
      "amountLimit": 5000
    },
    {
      "personId": "9b6d0d49034423ef0203344370e815ee",
      "sortOrder": 1,
      "amountLimit": null
    }
  ],
  "subUnits": []
}
```

When a user in the Sales department submits an expense report:

1. If the total is **5000 or less**, the manager (`sortOrder: 0`) approves it
2. If the total **exceeds 5000**, the report moves to the director (`sortOrder: 1`) after the manager approves

## Step 3 — Set Up Dimension-Based Approval

Assign approvers to specific dimension values. This requires a dimension with `controlType` set to `LIST_SEARCHABLE` and values already populated.

```bash bash theme={"system"}
PUT /organizations/externalid/{externalId}/customdimensions/{dimensionId}/approvers/
```

### Example: Assign Approvers to a Cost Center Value

```json theme={"system"}
[
  {
    "dimensionValueId": "CC-100",
    "approverExternalId": "EMP-MGR-001",
    "sortOrder": 0,
    "amountLimit": null
  },
  {
    "dimensionValueId": "CC-200",
    "approverExternalId": "EMP-MGR-002",
    "sortOrder": 0,
    "amountLimit": 10000
  },
  {
    "dimensionValueId": "CC-200",
    "approverExternalId": "EMP-DIR-001",
    "sortOrder": 1,
    "amountLimit": null
  }
]
```

In this example:

* Expenses tagged with cost center **CC-100** are approved by `EMP-MGR-001` with no amount limit
* Expenses tagged with cost center **CC-200** go through two approval steps: `EMP-MGR-002` up to 10,000, then `EMP-DIR-001` for any amount

## Step 4 — Retrieve the Current Approval Configuration

### Get Department Approvers

Retrieve the full organization structure, which includes the `approvers` array on each department:

```bash bash theme={"system"}
GET /organizations/externalid/{externalId}/organizationalunits/
```

### Get Dimension Approvers

Retrieve approvers assigned to a specific dimension's values:

```bash bash theme={"system"}
GET /organizations/externalid/{externalId}/customdimensions/{dimensionId}/approvers/
```

## Default Approver

If Findity cannot determine the correct approver — for example, a department's approver has been removed, or a user selects a dimension value with no approver assigned — the expense report is routed to the **default approver**.

Configure the default approver in the admin web client under Approval settings. This acts as a safety net to prevent expense reports from getting stuck in the approval queue.

## Temporary Approvers

Temporary approvers handle vacations and time off. When an approver is unavailable, a temporary replacement can be appointed to receive expense reports in their place.

There are three settings for temporary approver configuration:

| Setting | Description |
| - | - |
| **No** | Approvers cannot designate a temporary replacement |
| **Only from approvers with same or higher limit** | Temporary approver must have an equal or higher approval limit |
| **Yes, from all employees** | Approver can choose any user in the organization as a temporary replacement |

Configure this setting in the admin web client under Approval settings.

> [!NOTE]
>
> No extra authorization is required for a user to act as an approver. Any user in the organization can be assigned as
> an approver — they gain the ability to approve and reject reports but receive no additional administrative
> permissions.

## Common Integration Patterns

> **Syncing Department Approvers from HR**
>
> To keep department-based approval in sync with your HR system:
>
> 1. Export the current department-to-manager mappings from your HR system
> 2. Call `GET /organizations/externalid/{externalId}/organizationalunits/` to retrieve the current organization structure
> 3. Update each department's `approvers` array with the correct `personId` values from the HR export
> 4. Call `PUT /organizations/externalid/{externalId}/organizationalunits/` with the updated structure
> 5. Run this sync on a schedule (e.g., nightly) to reflect manager changes automatically

> **Project-Based Approval with Dimensions**
>
> To set up approval routing based on projects:
>
> 1. Create a dimension named "Project" with `controlType` set to `LIST_SEARCHABLE` and `level` set to `EXPENSE` (see [Dimensions](/docs/dimensions-new))
> 2. Populate the dimension with project values (e.g., "Project Alpha", "Project Beta")
> 3. For each project value, assign the project manager as approver using `PUT /organizations/externalid/{externalId}/customdimensions/{dimensionId}/approvers/`
> 4. When users create expenses and select a project, the expense report routes to that project's manager for approval

> **Combined Department + Dimension Approval**
>
> To use both department and dimension approval together:
>
> 1. Set up department-based approval as a baseline — every user's department has a designated approver
> 2. Create a dimension (e.g., "Cost Center" or "Project") and assign approvers to its values
> 3. In the admin web client, order the approval structure boxes to set the priority — place the dimension box above the department box if dimension approvers should be checked first
> 4. When a user submits an expense with a dimension value that has an approver, that approver handles it. If no dimension approver is found, Findity falls back to the department approver
> 5. If neither is found, the expense routes to the default approver

> **Multi-Step Approval with Amount Limits**
>
> To configure escalating approval based on expense amount:
>
> 1. Identify the approval thresholds for your organization (e.g., manager up to 5,000, director up to 25,000, CFO for any amount)
> 2. Assign three approvers to the department or dimension value with ascending `sortOrder` values (`0`, `1`, `2`) and corresponding `amountLimit` values (`5000`, `25000`, `null`)
> 3. When a user submits an expense report, Findity routes it through each step — the first approver with a sufficient `amountLimit` handles the approval
> 4. If the amount exceeds an approver's limit, the report continues to the next step after that approver approves
