-
Notifications
You must be signed in to change notification settings - Fork 15
REST API CMDB
The complete usage guide for the CMDB module of the REST API β classes, typed properties, configuration items, relationships, impact analysis and ticket links. 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 the CMDB:
| 𧬠Schema-driven | Every class defines typed properties (text, number, date, boolean, dropdown, object_ref). Read the class first (GET /cmdb/classes/{id}), then write objects with a friendly property_key β value map β the API validates types, required flags, dropdown options and object_ref target classes. |
| π³ Hierarchy + graph | Objects nest via parent_id (cycle-guarded) and connect via directed relationships with verb/inverse-verb pairs ("depends on" / "is depended on by"). |
| π₯ Deletes take the tree | Deleting an object removes its whole descendant tree, properties, relationships and ticket links (the module's design). Check GET .../impact first β the response tells you deleted_descendants. |
| π‘οΈ Ticket links are company-scoped | The internal CMDB screen reads linked tickets unscoped (a known multi-tenancy gap); the API deliberately does not reproduce that β GET /cmdb/objects/{id}/tickets honours the key's company scope, and link/unlink gate the ticket. |
| ποΈ Classes are read-only in v1 | Class design (properties, options, icons) stays an admin activity in the UI; the API reads definitions so integrations can build valid writes. |
Discover the shape, then create a CI with validated properties:
B="https://your-server/api/v1"; K="Authorization: Bearer fitsm_β¦"
# 1. What does a "server" need?
curl -s -H "$K" "$B/cmdb/classes" | jq '.data[] | {id, class_key, name}'
curl -s -H "$K" "$B/cmdb/classes/12" | jq '.data.properties[] | {property_key, type, is_required}'
# 2. Create it (required properties enforced; dropdowns validated against the option list)
curl -s -X POST "$B/cmdb/objects" -H "$K" -H "Content-Type: application/json" -d '{
"name": "SQL01", "class_key": "server",
"properties": { "hostname": "sql01.corp.local", "os": "Windows Server 2022" }
}'
# 3. Wire it into the graph
curl -s -X POST "$B/cmdb/objects/44/relationships" -H "$K" -H "Content-Type: application/json" \
-d '{"to_object_id": 12, "verb": "depends on"}'All CI classes with class_key, icon, active flag and object counts.
The class plus its full property definitions β everything needed to build a valid write:
{ "data": { "id": 12, "class_key": "server", "name": "Server",
"properties": [
{ "id": 40, "property_key": "hostname", "label": "Hostname", "type": "text",
"is_required": true, "target_class": null, "options": [] },
{ "id": 41, "property_key": "os", "label": "OS", "type": "dropdown",
"is_required": false, "target_class": null,
"options": [ { "value": "Windows Server 2022", "colour": null }, β¦ ] } ] } }| Parameter | Description |
|---|---|
class_id / class_key
|
Filter by class |
q |
Search by name |
parent_id |
Children of an object Β· top_level=true for roots |
is_planned |
true / false β planned vs live CIs |
sort |
name (default), id, created_at, updated_at β prefix - for descending |
page / per_page
|
Pagination β default 1 / 25, max 100 |
name + class_id/class_key required. properties is a map keyed by property_key. Validation mirrors the UI exactly β plus one improvement:
- required properties enforced on create (
422naming the missing label) -
numbermust be numeric Β·datemust parse (ISO 8601) Β·booleancoerces sensibly -
object_refmust exist, can't self-reference, and must match the property's target class - dropdown values must be one of the property's options (the UI stores anything β the API doesn't)
The class is immutable after creation, like the UI. Returns 201.
Fully hydrated: every class property with its typed value (object_ref values come with an embedded {id, name, class_name} card), parent, children, relationships.outgoing/incoming with natural-reading verbs, and the cached ai_summary.
Update name, parent_id (existence + cycle-walk guard β you can't parent an object to its own descendant), is_planned, and any subset of properties β only the keys you send are touched (required checks apply only to sent properties, matching the UI's inline edit). Empty/null clears a property.
Warning
Takes the whole tree. The object, all its descendants, their property values, relationships and ticket links are permanently removed (object_ref properties elsewhere that pointed at them are cleared). The response reports deleted_descendants β run GET .../impact first if you're not sure.
The blast radius before you touch something:
{ "data": { "descendants": [ { "id": 45, "name": "NODE1", "class_name": "Server", "depth": 1 } ],
"referenced_by_property": [ { "id": 7, "name": "Payroll", "class_name": "Application", "property": "Runs on" } ],
"incoming_relationships": [ { "id": 45, "name": "NODE1", "class_name": "Server", "relationship": "is depended on by" } ] } }Creates a directed edge from this object: {"to_object_id": 12, "verb": "depends on"} (or relationship_type_id). No self-links (422); the same from/to/type triple twice β 409. The other side automatically reads with the inverse verb.
Removes the edge β it must involve this object (either direction).
The tickets linked to this CI β scoped to the key's companies (deliberately tighter than the internal endpoint).
Body: {"ticket_id": 141}. The ticket must be within the key's company scope (404 otherwise); already linked β 409.
Removes the link.
| Endpoint | Permission | Returns |
|---|---|---|
π’ GET /cmdb-relationship-types
|
π reference.read |
Verb + inverse-verb pairs (seeded: depends on, connects to, managed by) |
A network-discovery job upserting CIs and wiring dependencies (cmdb_classes: read + cmdb_objects: read/create/update + cmdb_relationships: create):
B="https://your-server/api/v1"; K="Authorization: Bearer fitsm_β¦"
# Upsert-by-name within the server class
ID=$(curl -s -H "$K" "$B/cmdb/objects?class_key=server&q=sql01" | jq -r '.data[0].id // empty')
if [ -n "$ID" ]; then
curl -s -X PATCH "$B/cmdb/objects/$ID" -H "$K" -H "Content-Type: application/json" \
-d '{"properties": {"os": "Windows Server 2022"}}'
else
ID=$(curl -s -X POST "$B/cmdb/objects" -H "$K" -H "Content-Type: application/json" \
-d '{"name":"SQL01","class_key":"server","properties":{"hostname":"sql01.corp.local"}}' | jq -r '.data.id')
fi
# The app depends on the freshly-synced server
curl -s -X POST "$B/cmdb/objects/$APP_ID/relationships" -H "$K" -H "Content-Type: application/json" \
-d "{\"to_object_id\": $ID, \"verb\": \"depends on\"}"And change-risk enrichment β what breaks if we reboot this?
curl -s -H "$K" "$B/cmdb/objects/$ID/impact" \
| jq -r '.data.incoming_relationships[] | "\(.class_name): \(.name) (\(.relationship))"'Under the hood: REST API β How It Works Β· Other modules: Tickets Β· Assets Β· Problems Β· Changes Β· Knowledge Β· Tasks Β· Keys & permissions: System β API (System module) Β· Module docs: CMDB.
FreeITSM β an open-source IT Service Management platform Β· github.com/edmozley/freeitsm Β· MIT licence
- Installation
- β° Scheduled tasks (cron jobs)
- Architecture
- AI Providers
- Internationalisation (i18n)
- Timezones & Time Handling
- Theming & Dark Mode
- β¨οΈ Command palette (βK)
- π Searching inside tickets
- π Attached documents
- MobileβFriendly
-
Security
- Layer 1 β which modules you can enter
- β³ π§© Module Access Control
- β³ π οΈ Module Access β Developer Guide
- Layer 2 β what you can administer
- β³ π Roles & Permissions
- β³ π οΈ Roles β Developer Guide
- β³ π€ Why capabilities are constants
- Layer 3 β the System module
- β³ π Admin Access Control
- Hardening
- β³ π Security review response 2026-08
- β³ π‘οΈ Security hardening 2026-08
- β³ π οΈ Security hardening 2026-08 β Developer Guide
- β³ π‘οΈ Round three β plain English
- β³ π οΈ Round three β Developer Guide
- Single Sign-On (SSO)
- ποΈ LDAP & Active Directory
- Browser Extension
- API Reference
-
π REST API β how it works
- β³ π« REST API: Tickets
- β³ π» REST API: Assets
- β³ π΄ REST API: Problems
- β³ π REST API: Changes
- β³ π REST API: Knowledge
- β³ β REST API: Tasks
- β³ ποΈ REST API: CMDB
- β³ π REST API: Contracts
- β³ ποΈ REST API: Calendar
- β³ πΏ REST API: Software
- β³ π¦ REST API: Service Status
- β³ βοΈ REST API: Morning Checks
- β³ π REST API: Forms
- β³ βοΈ REST API: Workflow
- β³ πΊοΈ REST API: Network Mapper
- β³ π§ Using the API docs page
- β³ π OpenAPI specification
- β³ β OpenAPI: kept correct
- β³ π οΈ Maintaining the catalogue
- Watchtower
-
Tickets
- β³ Mailbox Authentication
- β³ π€ Email send log
- β³ Basic IMAP mailboxes
- β³ Email rendering & images
- β³ SLA Management
- β³ WhatsApp channel
- β³ π¬ Web chat channel
- β³ π£ Slack channel
- β³ π Linking tickets
- β³ ποΈ Canned responses
- β³ βοΈ Limiting replies to particular senders
- β³ βοΈ Email signatures
- β³ π The public web address
- β³ π’ Ticket numbering
- β³ π Raising a ticket for someone else
- β³ π Merging tickets
- β³ β Splitting tickets
- β³ β Selecting several tickets
- β³ π οΈ Snoozing tickets β Developer Guide
- β³ π₯ Collision detection
- β³ β±οΈ Time tracking
- Problem Management
- Tasks
- Assets
- Knowledge
- Change Management
- Calendar
- Morning Checks
- Reporting
- Software
- Forms
- Contracts
- Service Status
- π Notifications
- π¨ War Room
- Self-Service Portal
- LMS
- Process Mapper
- CMDB
- Network Mapper
- Workflows
- Issue trackers (Jira, Azure DevOps)
- System
-
Overview
- β³ π Progress tracker
- β³ Concepts & vocabulary
- β³ Email routing & mailboxes
- β³ Settings: global vs per-company
- β³ Users & self-service
- β³ Staff cross-company access
- β³ Worked examples
- β³ Pitfalls & gotchas
- β³ Scope: what it's for
- β³ π οΈ Developer Guide (make a module multi-company)
- β³ ποΈ Case study: CMDB (a linked graph)
- β³ π§ͺ Test harness (prove it's isolated)