> ## 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.

# Charts of accounts

Manage accounting accounts for an organization through the Findity Admin API — used for expense categorization, bookkeeping, and payroll.

This guide shows you how to list, create, update, and delete accounts in an organization's chart of accounts, and how those accounts map to expense categories and voucher rows on export.

## Overview

Accounts are the rows in an organization's chart of accounts. Each account has a `number` (the code your customer's financial system uses, e.g. `5010`) and a `name` (the human-readable label, e.g. `Travel expenses`). The chart-of-accounts lifecycle is:

1. **Provision the accounts** — POST one per ledger code your customer uses.
2. **Map accounts to expense categories** — done in the Findity admin UI or via the categories endpoints. The mapping decides which account number ends up on the debit, credit, or VAT row of a voucher.
3. **Keep them in sync** — list, update, or delete accounts as the customer's chart of accounts evolves.

This guide covers steps 1 and 3 — provisioning and sync. Category mapping is summarized at the end with links to the related guides.

## Prerequisites

1. Complete [Authentication](/docs/accessing) and obtain an admin-scoped bearer token.
2. Provision the organization first — see [Admin API — Getting started](/docs/getting-started-with-admin-api). The chart-of-accounts endpoints require the organization's **internal `id`** (32-character hex), which you can read from the response of `GET /organizations/externalid/{externalId}/`.

## Key concepts

| Concept | Description |
| - | - |
| **Account** | One row in the chart of accounts. Holds a `number`, a `name`, and an internal `id`. |
| **Chart of accounts** | The full set of accounts an organization uses to categorize expenses and post bookkeeping entries. |
| **Expense category mapping** | The link between a Findity expense category (e.g. *Travel*) and an account `number`. Determines which account appears on the debit row of the voucher. |
| **Voucher row** | One line of a generated voucher. Each expense produces at least a debit row, a credit row, and a VAT row when applicable. |
| **Accounting recipient** | An external accounting system connected to Findity. When configured, account mappings on expense categories can be synced from the external system automatically. |

## API endpoints

All endpoints live on the v1 admin API. Examples in this guide use the stage host — switch to the production host (`api.findity.com`) only when you're ready to go live.

```sh cURL theme={"system"}
https://stage-api.findity.com/api/v1/admin
```

| Operation | Method | Endpoint |
| - | - | - |
| List accounts | `GET` | `/organizations/{organizationId}/accounts` |
| Get a single account | `GET` | `/organizations/{organizationId}/accounts/{accountId}` |
| Create an account | `POST` | `/organizations/{organizationId}/accounts` |
| Update an account | `PUT` | `/organizations/{organizationId}/accounts/{accountId}` |
| Delete an account | `DELETE` | `/organizations/{organizationId}/accounts/{accountId}` |

### Required headers

| Header | Value |
| - | - |
| `Content-Type` | `application/json` |
| `Accept` | `application/json` |
| `Authorization` | `Bearer {access_token}` |

## Step 1 — List accounts

Retrieve every account in an organization's chart of accounts. The response is wrapped in a `{meta, data}` envelope.

`GET /organizations/{organizationId}/accounts`

```sh cURL theme={"system"}
curl -X GET \
  "https://stage-api.findity.com/api/v1/admin/organizations/8a5c8bee9e3a4a24019e3ae1732b008e/accounts" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

**Example response** (status `200 OK`)

```json JSON theme={"system"}
{
  "meta": { "total": 3, "count": 3 },
  "data": [
    { "id": "8a5c8bee9e3a4a24019e3ae175000090", "meta": {}, "name": "Expenses", "number": "100" },
    { "id": "8a5c8bee9e3a4a24019e3ae175000091", "meta": {}, "name": "VAT", "number": "999" },
    { "id": "8a5c88f89e4f3dd1019e4f725ab40010", "meta": {}, "name": "Office Supplies", "number": "6300" }
  ]
}
```

`meta.total` is the total number of accounts; `meta.count` is the number of items returned in this response.

## Step 2 — Create an account

Add a new account to the chart of accounts. Returns `201 Created` with the new account's `id`.

`POST /organizations/{organizationId}/accounts`

### Request body fields

| Field | Type | Required | Description |
| - | - | - | - |
| `name` | string | Yes | Display name of the account (e.g. `Travel expenses`). |
| `number` | string | Yes | The account number used in your customer's financial system (e.g. `5010`). |

> [!WARNING]
>
> **Only `name` and `number` are accepted on the request body. The backend explicitly rejects unknown fields with `400 NO_KNOWN_JSON_PROPERTIES`.**

```sh cURL theme={"system"}
curl -X POST \
  "https://stage-api.findity.com/api/v1/admin/organizations/8a5c8bee9e3a4a24019e3ae1732b008e/accounts" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "name": "Travel expenses",
    "number": "5010"
  }'
```

**Example response** (status `201 Created`)

```json JSON theme={"system"}
{
  "id": "8a5c89929e4f9c08019e4fb9b90b007d",
  "meta": null,
  "name": "Travel expenses",
  "number": "5010"
}
```

`meta` is `null` on a freshly created account and may be populated by Findity later with auxiliary attributes (currently `abbreviation` and `capabilities`).

## Step 3 — Get a single account

Retrieve one account by its internal `id`.

`GET /organizations/{organizationId}/accounts/{accountId}`

```sh cURL theme={"system"}
curl -X GET \
  "https://stage-api.findity.com/api/v1/admin/organizations/8a5c8bee9e3a4a24019e3ae1732b008e/accounts/8a5c89929e4f9c08019e4fb9b90b007d" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

**Example response** (status `200 OK`)

```json JSON theme={"system"}
{
  "id": "8a5c89929e4f9c08019e4fb9b90b007d",
  "meta": { "abbreviation": null, "capabilities": null },
  "name": "Travel expenses",
  "number": "5010"
}
```

## Step 4 — Update an account

Modify an existing account. The request body **must include the account's `id`**, and it must match the `accountId` in the URL — otherwise the call returns `400 INVALID_ID`.

`PUT /organizations/{organizationId}/accounts/{accountId}`

### Request body fields

| Field | Type | Required | Description |
| - | - | - | - |
| `id` | string | Yes | The account's internal id. Must match the `{accountId}` in the URL. |
| `name` | string | Yes | The updated display name. |
| `number` | string | Yes | The updated account number. |

```sh cURL theme={"system"}
curl -X PUT \
  "https://stage-api.findity.com/api/v1/admin/organizations/8a5c8bee9e3a4a24019e3ae1732b008e/accounts/8a5c89929e4f9c08019e4fb9b90b007d" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "id":     "8a5c89929e4f9c08019e4fb9b90b007d",
    "name":   "Travel and accommodation expenses",
    "number": "5010"
  }'
```

**Example response** (status `200 OK`)

```json JSON theme={"system"}
{
  "id": "8a5c89929e4f9c08019e4fb9b90b007d",
  "meta": null,
  "name": "Travel and accommodation expenses",
  "number": "5010"
}
```

## Step 5 — Delete an account

Remove an account from the chart of accounts. Returns `204 No Content` with an empty response body on success.

`DELETE /organizations/{organizationId}/accounts/{accountId}`

> [!NOTE]
>
> Deleting an account that is currently mapped to one or more expense categories will break the accounting flow for
> those categories — voucher generation will fail until the categories are remapped. Verify no active categories
> reference the account before deleting.

```sh cURL theme={"system"}
curl -X DELETE \
  "https://stage-api.findity.com/api/v1/admin/organizations/8a5c8bee9e3a4a24019e3ae1732b008e/accounts/8a5c89929e4f9c08019e4fb9b90b007d" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

**Example response** (status `204 No Content`)

The response body is empty.

## Mapping accounts to expense categories

After creating accounts, map them to expense categories so Findity can generate the correct voucher rows on export. The mapping decides which account number appears in the debit, credit, or VAT row of the voucher output.

Administrators can configure these mappings through:

* **Admin web client** — *Settings → Expense management → Expense categories*, select the account for each category.
* **Admin API** — Use the categories endpoints to update account mappings programmatically (see the [Expense API guide](/docs/getting-started-with-expense-api)).

Each expense category can be linked to:

* A **debit account** — the accounting account the expense is recorded against.
* A **salary type** — for payroll integration, if applicable.

> [!NOTE]
>
> **If the organization uses an accounting recipient connected through the API, account mappings on expense categories can be synced from the external system automatically. For manual recipients, administrators manage these mappings through the admin interface.**

## Relationship to vouchers

When expense reports are exported through the [Connect API](/docs/voucher-structure), Findity uses the chart of accounts to generate structured voucher data. Each expense produces voucher rows like:

| Voucher row | Account source | Description |
| - | - | - |
| Debit row | Expense category's mapped account | Records the expense in the general ledger. |
| Credit row | Payment method's mapped account | Records the payment source (e.g. corporate card, employee reimbursement). |
| VAT row | VAT account | Records the tax amount separately when `vatType` is `SEPARATELY`. |

For details on how vouchers are structured and grouped, see [Voucher structure](/docs/voucher-structure).

## Common integration patterns

**Sync from an ERP or accounting system.** Keep the chart of accounts in sync with your ERP on a schedule (e.g. nightly):

1. Export the current account list from your financial system.
2. Call `GET /organizations/{organizationId}/accounts` to retrieve existing accounts in Findity.
3. Diff the two lists and call `POST` for new accounts, `PUT` for changed accounts, and `DELETE` for removed accounts.

**Initial organization setup.** When onboarding a new organization:

1. Create the [organization](/docs/admin-api-organizations). If you use a template org with pre-configured accounts, accounts are inherited and you can skip the next step.
2. Otherwise, call `POST /organizations/{organizationId}/accounts` for each account in the customer's chart of accounts.
3. Map accounts to expense categories through the admin UI or the categories API.
4. Configure salary types if the organization integrates with a payroll system.
5. Set up the accounting recipient to enable voucher export.

**Migrating account numbers.** When an organization changes its accounting system or restructures its chart of accounts:

1. `GET /organizations/{organizationId}/accounts` to list all current accounts.
2. `POST` to create the new accounts.
3. Update expense-category mappings to point to the new account numbers.
4. Deactivate or delete the old accounts once all active expense reports have been exported.
5. Verify the migration by exporting a test voucher and confirming the new account numbers appear in the voucher rows.

## Error handling

Errors return a JSON envelope:

```json JSON theme={"system"}
{ "result": "error", "requestId": "<uuid>", "description": "<human-readable message>", "code": "<machine-readable code>" }
```

The `requestId` value is useful to include when reporting a problem to Findity support.

| Status | `code` | Description |
| - | - | - |
| `400` | `NO_KNOWN_JSON_PROPERTIES` | The request body contains no fields the backend recognizes (e.g. you sent `accountNumber`/`accountName` instead of `number`/`name`). Use the field names documented in this guide. |
| `400` | `INVALID_ID` | On `PUT`, the `id` in the request body doesn't match the `accountId` in the URL. Include `id` in the body and make sure both match. |
| `401` | — | Access token is missing, expired, or invalid. Refresh and retry. |
| `403` | — | The token does not have admin scope for this organization. |
| `404` | — | The organization or account isn't found. Confirm the `organizationId` and `accountId`. |
| `429` | — | Rate limit exceeded. Apply exponential backoff. |
| `500` | — | Server error. Safe to retry with backoff; if it persists, contact support with the `requestId` from the response. |

## Next steps

> **[Admin API — Getting started](/docs/getting-started-with-admin-api)**
>
> The six-step provisioning flow that creates the organization, dimensions, accounts, users, and approvers.

> **[Organizations](/docs/admin-api-organizations)**
>
> Manage organization settings and look up an organization's internal id.

> **[Dimensions](/docs/admin-api-dimensions)**
>
> Configure dimension fields and manage value lists.

> **[Voucher structure](/docs/voucher-structure)**
>
> See how account numbers flow into the debit, credit, and VAT rows of an exported voucher.
