-
Notifications
You must be signed in to change notification settings - Fork 15
REST API Knowledge
The complete usage guide for the Knowledge Base module of the REST API β every URL, method, parameter and response shape. 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 Knowledge:
| π Install-wide | The knowledge base has no company concept β a key's company scope does not restrict it (matches the UI). |
| π·οΈ Tags, not categories | The module's only taxonomy is free-text tags β send them as an array of names and they're created on the fly. |
| β»οΈ Recycle bin, not trash-forever |
DELETE archives; articles restore from the bin; permanent deletion only works from the bin and the bin auto-purges on the module's retention setting β all exactly like the UI. |
| π§ Embeddings stay warm | If the module's OpenAI key is configured, creating or updating an article via the API regenerates its search embedding (best-effort, like the UI) β so the AI chat and vector search find API-written articles too. |
| π View counts are opt-in | Reading an article via the API does not bump view_count unless you pass ?count_view=true β a deliberate divergence so sync jobs and chatbots don't inflate the stats the review screens use. |
Warning
Article bodies are TinyMCE-style HTML stored verbatim β the product performs no server-side sanitisation (the UI behaves identically). Only send trusted HTML, and sanitise on render if you display articles outside FreeITSM.
Sync a runbook from your docs pipeline into the KB:
B="https://your-server/api/v1"; K="Authorization: Bearer fitsm_β¦"
curl -X POST "$B/knowledge/articles" -H "$K" -H "Content-Type: application/json" -d '{
"title": "How to reset your VPN token",
"body_html": "<h2>Steps</h2><ol><li>Open the portal</li><li>Click reset</li></ol>",
"tags": ["vpn", "how-to"],
"next_review_date": "2026-12-01"
}'Published immediately, tagged, embedded for AI search, and on the review calendar. π
Published articles (or the recycle bin with archived=true). Each list item carries a 300-character plain-text preview instead of the full body.
| Parameter | Description |
|---|---|
q |
π Keyword search across title and body (the module's own search β no AI required) |
tag |
Only articles carrying this tag (exact name) |
author_id / owner_id
|
Filter by author or owning analyst |
review |
overdue Β· upcoming (next 30 days) Β· none β the review screen's exact windows |
modified_since |
ISO 8601 β the sync-job filter |
archived |
true lists the recycle bin (and runs the same retention auto-purge the UI runs on opening it) |
sort |
modified_at (default, desc), created_at, title, view_count, next_review_date, id β prefix - for descending |
page / per_page
|
Pagination β default 1 / 25, max 100 |
Articles are created published immediately β the product has no draft workflow. Returns 201 with the full article.
| Field | Required | Description |
|---|---|---|
title |
β | Max 255 characters |
body_html |
The article content (HTML) | |
tags |
Array of tag names β created on the fly, e.g. ["vpn", "how-to"]
|
|
owner_id |
Owning analyst (drives the review cycle) | |
next_review_date |
YYYY-MM-DD |
The full article with body_html, tags, version number and a has_embedding flag. Add ?count_view=true to count the read as a view (UI parity β otherwise machine reads leave the stats alone).
{ "data": { "id": 26, "title": "How to reset your VPN token",
"tags": ["how-to", "vpn"],
"author": { "id": 1, "name": "Administrator" }, "owner": null,
"version": 2, "view_count": 41, "next_review_date": "2026-12-01",
"is_archived": false,
"created_at": "2026-07-03T12:18:31Z", "modified_at": "2026-07-03T12:19:07Z",
"body_html": "<h2>Steps</h2><ol>β¦</ol>", "has_embedding": true } }| Field | Notes |
|---|---|
title / body_html
|
New content |
tags |
Replaces the article's tag set |
owner_id / next_review_date
|
Review-cycle fields (null clears) |
save_as_version |
true = snapshot the current content into the version history first, then bump the version number β exactly the UI's "Save as new version" |
The search embedding is refreshed automatically after every create/update (when the OpenAI key is configured). An archived article answers 409 β restore it first.
Soft-archives the article. It stays restorable until the module's retention window (knowledge_recycle_bin_days, default 30; 0 = keep forever) purges it.
Brings an archived article back, exactly as it was.
Warning
Hard-deletes the article, its version history and its tag links (orphaned tags are cleaned up). Only allowed once the article is already in the recycle bin β same guard as the UI. 409 otherwise.
Snapshots are only created when a save says so (save_as_version here, "Save as new version" in the UI) β routine edits update in place.
The saved snapshots β version number, title at the time, who saved it, when β newest first.
One snapshot including its full body_html β everything needed to diff or roll back (roll back by PATCHing the old body onto the article).
Every tag with its published-article count:
{ "data": [ { "id": 3, "name": "how-to", "article_count": 12 },
{ "id": 7, "name": "vpn", "article_count": 4 } ] }A CI job that keeps the KB in step with a docs repo (knowledge: read, create, update + reference: read):
B="https://your-server/api/v1"; K="Authorization: Bearer fitsm_β¦"
# Upsert-by-title: find the article, PATCH it (with a version snapshot) or create it
ID=$(curl -s -H "$K" "$B/knowledge/articles?q=$(python3 -c 'import urllib.parse;print(urllib.parse.quote("How to reset your VPN token"))')" | jq -r '.data[0].id // empty')
if [ -n "$ID" ]; then
curl -s -X PATCH "$B/knowledge/articles/$ID" -H "$K" -H "Content-Type: application/json" \
-d "{\"body_html\": $(jq -Rs . < rendered.html), \"save_as_version\": true}"
else
curl -s -X POST "$B/knowledge/articles" -H "$K" -H "Content-Type: application/json" \
-d "{\"title\": \"How to reset your VPN token\", \"body_html\": $(jq -Rs . < rendered.html), \"tags\": [\"vpn\"]}"
fiAnd the review-cycle report β what's overdue for review, and who owns it?
curl -s -H "$K" "$B/knowledge/articles?review=overdue&sort=next_review_date&per_page=100" \
| jq -r '.data[] | [.title, .next_review_date, (.owner.name // "unowned")] | @tsv'Under the hood: REST API β How It Works Β· Other modules: Tickets Β· Assets Β· Problems Β· Changes Β· Keys & permissions: System β API (System module) Β· Module docs: Knowledge.
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)