REST API Software - edmozley/freeitsm GitHub Wiki
๐ฟ 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.