Skip to content

REST API Cost Centres

Ed Mozley edited this page Oct 4, 2026 · 1 revision

🏷️ REST API: Cost centres

The usage guide for cost centres in the REST API β€” the list itself, and the sync an accounting system calls. Mirrors the interactive documentation at System β†’ API β†’ Documentation. User guide: Cost centres.

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.

What's distinctive about cost centres:

🏒 Company-scoped Every cost centre 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 "0010" stays "0010". Unique per company, ignoring case. Send codes as JSON strings, never numbers.
πŸ”„ One call keeps you in step POST /cost-centres/sync takes the whole list, matched on code β€” added, updated, nothing duplicated. All or nothing.

πŸš€ Quick start

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

# Active cost centres, by code
curl -s -H "$K" "$B/cost-centres?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/cost-centres/sync" -d '{
  "dry_run": true,
  "deactivate_missing": true,
  "cost_centres": [
    {"code": "0010", "name": "IT"},
    {"code": "0011", "name": "IT - Infrastructure", "parent_code": "0010"},
    {"code": "N1414", "name": "Facilities", "is_active": true}
  ]}'

Endpoints

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

List filters

company_id, code (exact), q (code or name), active=true|false, parent_id (0 = top level), sort (code default, name, updated_at, id; prefix - for descending), page / per_page.

A cost centre

{
  "id": 7, "code": "0011", "name": "IT - Infrastructure", "description": null,
  "parent": { "id": 6, "code": "0010", "name": "IT" },
  "is_active": true,
  "company": { "id": 1, "name": "Default" },
  "child_count": 0,
  "created_at": "2026-10-03T09:12:00Z", "updated_at": "2026-10-03T09:12:00Z"
}

Writes take code, name, description, parent_id (same company; never itself or anything below it), is_active, and on create company_id.

The sync

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

  • Matched on code, ignoring case. A new code needs a name. Only the keys you send are changed.
  • parent_code may name another row in the same call, or an existing cost centre. A blank one means top level.
  • deactivate_missing: true makes inactive every cost centre of that company not in the list β€” for when the list is complete. Nothing is ever deleted.
  • All or nothing. If any row has a problem, nothing is written and you get 422 invalid_rows with every problem in error.details.errors (line = 1-based position in cost_centres).
  • 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, action and the fields that changed (line is null for one made inactive because it was missing).


See also: Cost centres Β· Cost centres β€” Developer Guide Β· REST API

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally