Skip to content

REST API Software

Ed Mozley edited this page Jul 3, 2026 · 1 revision

💿 REST API: Software

The complete usage guide for the Software module of the REST API — the agent-collected application inventory and the licence register, with computed compliance numbers the UI doesn't have. Mirrors the interactive documentation at System → API → Documentation (with its live "Try it" tester).

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 Software:

🤖 Inventory is read-only The application catalogue and per-machine installs are 100% agent-owned (the inventory agent full-syncs each host) — analysts can't edit them in the UI and neither can the API. Licences are the writable half.
🧮 Compliance is computed for you Every licence carries app_installs (distinct non-system-component machines) next to its seat quantity, and app detail returns installs vs summed Active seats with seats_available — the seats-vs-installs comparison the UI never makes. Over-deployed software is one call away.
Renewal logic server-side The licence screen colours renewals client-side; the API computes renewal_status (ok / due_soon / overdue — due_soon = within each licence's own notice period, default 30 days) and offers matching list filters.
🔑 Legacy keys stay out This module's settings screen manages the old plaintext keys for the inventory agent/extension — that's a separate, older mechanism. The REST API uses its own fitsm_… keys.

🚀 Quick start

The licence-compliance question, answered in one call:

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

curl -s -H "$K" "$B/software/apps/227" | jq '.data.compliance'
# { "installs": 368, "licensed_seats": 100, "unmetered_licences": false, "seats_available": -268 }
#                                                     ↑ over-deployed by 268 machines

💿 Applications (inventory — read-only)

🟢 GET /software/apps   🔑 software_inventory.read

The application catalogue with install counts (distinct machines) and licence counts.

Parameter Description
q Search name and publisher
filter apps (non-components — the UI's default tab), components, or all (default)
sort name (default), publisher, install_count, id — prefix - for descending
page / per_page Pagination — default 1 / 25, max 100
{ "id": 227, "name": "Microsoft Intune Management Extension", "publisher": null,
  "install_count": 368, "system_component": false, "licence_count": 1,
  "first_detected": "2026-05-10T09:12:44Z" }

🟢 GET /software/apps/{id} — app + compliance   🔑 software_inventory.read

The app with its licences and the computed compliance block: installs (distinct non-component machines), licensed_seats (sum of Active licence quantities), seats_available (negative = over-deployed 🔥), and unmetered_licences: true when an Active licence has no seat count (e.g. a site licence) — in which case seats_available is null rather than misleading.

🟢 GET /software/apps/{id}/machines   🔑 software_inventory.read

Every machine it's installed on — hostname, version, install date, last seen — with asset_id so you can join straight to /assets/{id}.


🔑 Licences

🟢 GET /software/licences   🔑 software_licences.read

Parameter Description
app_id Licences for one application
status e.g. Active
q Search app name, licence type and vendor contact
renewal_within_days Renewal date within N days
due_soon true = within each licence's own notice period, not yet overdue
renewal_overdue true = renewal already passed 🔴
sort renewal_date (default), app, cost, created_at, id — prefix - for descending
page / per_page Pagination

The licence shape:

{ "id": 19,
  "app": { "id": 227, "name": "Microsoft Intune Management Extension", "publisher": null },
  "licence_type": "Per-seat subscription", "licence_key": null,
  "quantity": 100, "app_installs": 368,
  "renewal_date": "2026-07-23", "renewal_status": "due_soon", "notice_period_days": 30,
  "portal_url": null, "cost": 2400.0, "currency": "GBP", "purchase_date": null,
  "vendor_contact": null, "notes": null, "status": "Active",
  "created_by": { "id": 1, "name": "Administrator" },
  "created_at": "2026-07-03T17:26:11Z", "updated_at": "2026-07-03T17:26:11Z" }

quantity: 100 vs app_installs: 368 — your compliance report writes itself.

🔵 POST /software/licences   🔑 software_licences.create

Field Required Description
app_id The application (validated — 422 on unknown)
licence_type Free text, e.g. "Per-seat subscription"
quantity Seat count — omit for site/unmetered licences
renewal_date / purchase_date YYYY-MM-DD
notice_period_days Drives due_soon (default 30)
cost / currency Amount + currency (default GBP)
licence_key / portal_url / vendor_contact / notes / status Admin fields (status defaults Active)

created_by is stamped as the analyst the key acts as. Returns 201.

🟢 GET · 🟠 PATCH · 🔴 DELETE /software/licences/{id}   🔑 software_licences.read/update/delete

Everything creatable is patchable (created_by is never touched — UI parity). Delete is a clean leaf-table removal.


🧪 Worked example: monthly true-up report

A read-only key (software_inventory: read + software_licences: read):

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

# Every licensed app where installs exceed Active seats
curl -s -H "$K" "$B/software/licences?status=Active&per_page=100" \
  | jq -r '.data[] | select(.quantity != null and .app_installs > .quantity)
           | "🔥 \(.app.name): \(.app_installs) installs vs \(.quantity) seats (\(.app_installs - .quantity) over)"'

# Renewals needing action (each licence's own notice window)
curl -s -H "$K" "$B/software/licences?due_soon=true&sort=renewal_date" \
  | jq -r '.data[] | "\(.renewal_date)  \(.app.name)  \(.cost // 0) \(.currency)"'

And the procurement direction — recording the true-up you just bought:

curl -s -X PATCH "$B/software/licences/19" -H "$K" -H "Content-Type: application/json" \
  -d '{"quantity": 400, "cost": 9600, "notes": "True-up July 2026 (PO-1042)."}'

Under the hood: REST API — How It Works · Other modules: Tickets · Assets · Problems · Changes · Knowledge · Tasks · CMDB · Contracts · Calendar · Keys & permissions: System → API (System module) · Module docs: Software.

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally