Skip to content

REST API Accounts

Ed Mozley edited this page Nov 12, 2026 · 1 revision

πŸ“’ REST API: Chart of accounts

The usage guide for accounts in the REST API β€” the chart itself, and the sync a finance system calls. Mirrors the interactive documentation at System β†’ API β†’ Documentation. User guide: Chart of accounts. New in 5.1.0.

Note

New to the API? The basics table on REST API: Tickets covers base URL, authentication, the response envelope, error codes, rate limits and PATCH semantics - identical across all modules.

Accounts work exactly like cost centres - company-scoped, codes as text, one sync call to stay in step - with one more field, kind.

🏒 Company-scoped Every account is one company's. Lists are filtered to the key's companies; one outside them is a 404 on every by-id route. Writes land in company_id (checked against the key) or the key's default company.
πŸ”€ Codes are text "2.0.3.0.4" and "0010" stay as sent. Unique per company, ignoring case. Send codes as JSON strings.
🏷️ Kind expense, fixed_asset, payroll or income. Words the import understands ("Capex", "Salaries", "Revenue") are accepted too and stored as the key.
πŸ”„ One call keeps you in step POST /accounts/sync takes the whole chart, matched on code. All or nothing.

πŸš€ Quick start

B="https://your-server/api/v1"; K="Authorization: Bearer fitsm_…"

# Active fixed-asset accounts
curl -s -H "$K" "$B/accounts?kind=fixed_asset&active=true" | jq '.data[] | {code, name}'

# Nightly sync from finance - try it first with dry_run
curl -s -H "$K" -H "Content-Type: application/json" -X POST "$B/accounts/sync" -d '{
  "dry_run": true,
  "accounts": [
    {"code": "2.0.3.0",   "name": "IT running costs",   "kind": "expense"},
    {"code": "2.0.3.0.4", "name": "Software Licences",  "parent_code": "2.0.3.0"},
    {"code": "2.1.0.3.2", "name": "Computer Equipment", "kind": "fixed_asset"},
    {"code": "1.3.0.0.1", "name": "Employee Payroll",   "kind": "payroll"}
  ]}'

Endpoints

Method Path Permission What
GET /accounts accounts.read List / search
POST /accounts accounts.create Add one
GET /accounts/{id} accounts.read One account
PATCH /accounts/{id} accounts.update Change fields
DELETE /accounts/{id} accounts.delete Delete (refused with 409 while it has children - make it inactive instead)
POST /accounts/sync accounts.update and create Bring the whole chart in step

List filters

company_id, code (exact), kind (expense / fixed_asset / payroll / income; anything else is a 400), q (code, name or description), active=true|false, parent_id (0 = top level), sort (code default, name, kind, updated_at, id; prefix - for descending), page / per_page.

An account

{
  "id": 12, "code": "2.0.3.0.4", "name": "Software Licences", "kind": "expense", "description": null,
  "parent": { "id": 11, "code": "2.0.3.0", "name": "IT running costs" },
  "is_active": true,
  "company": { "id": 1, "name": "Default" },
  "child_count": 0,
  "created_at": "2026-11-12T19:02:00Z", "updated_at": "2026-11-12T19:02:00Z"
}

Writes take code, name, kind (required on create), description, parent_id or parent_code (same company; never itself or anything below it), is_active, and on create company_id. kind can be changed but not emptied.

The sync

Body: accounts (array, at most 10,000 β€” split bigger charts by company), each with code and any of name, kind, description, parent_code, is_active; optional company_id, dry_run, deactivate_missing.

  • Matched on code, ignoring case. Only the keys you send are changed.
  • A new code needs a name and a kind - or a parent_code, whose kind it then takes (the nearest ancestor with one, in this call or already there).
  • parent_code may name another row in the same call, or an existing account. A blank one means top level.
  • deactivate_missing: true makes inactive every account of that company not in the list. Nothing is ever deleted.
  • All or nothing. Any problem and nothing is written: 422 invalid_rows with every problem in error.details.errors (line = 1-based position in accounts).
  • dry_run: true returns what would happen and writes nothing.

Response: company_id, applied, dry_run, counts (create, update, unchanged, deactivate) and changes - one entry per row that changed, with its line, code, name, kind, action and the fields that changed.


Related: REST API Β· Chart of accounts Β· REST API: Cost centres

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Responses to feedback

Blue sky thinking

Bugs resolved

Pull requests

Links

Clone this wiki locally