API Reference

Read-only REST API for the Australian Government ISM control data.

This API is provided as-is with no support. If something isn't working, read the docs. Do not email asking for help troubleshooting your code.

Base URL https://api.secctrl.fyi
Format JSON (application/json)
Methods GET only
Auth None — public, read-only
Rate limits 60/min (stats & metadata); 30/min (per-record detail); 10/min (full-dataset lists); 2/min (/api/compare) — all per IP, bypassable with a token
CORS Browser CORS is restricted to secctrl.fyi; scripts and CLI tools can call directly
AI agents SKILL.md — machine-readable reference for LLMs and agents

Using the API

All endpoints are public and require no authentication. Example with curl:

curl "https://api.secctrl.fyi/api/controls?filter=e8"

Example with Python requests:

import requests

r = requests.get("https://api.secctrl.fyi/api/controls")
controls = r.json()["controls"]

All endpoints are rate-limited per IP. The default limits are sufficient for general use. If you need higher throughput, a bypass token removes rate limits entirely — pass it as a request header:

X-Bypass-Token: your-token-here

Tokens are free and optional. See who is eligible and how to apply. Tokens do not expire unless revoked.

Controls

GET /api/controls

Returns a list of ISM controls at their latest version. Supports full-text search, filter presets, and scoping by section or guideline. Withdrawn controls are excluded from all filters except filter=withdrawn.

Query parameters
Parameter Type Description
search optional string Full-text search across control descriptions. Max 200 characters. Bare numbers (e.g. 1173) and ISM ID patterns (ISM-1173, ism-1173) trigger an exact control lookup rather than full-text search.
filter optional string Preset filter. One of: all (default — all non-withdrawn controls), e8 (Essential Eight controls only), ml1 / ml2 / ml3 (Essential Eight controls at a specific maturity level), changed (modified in the latest release), new (added in the latest release), withdrawn (withdrawn controls only).
section optional string Filter by ControlGroup ID (use the id field from /api/sections). Max 60 characters.
guideline optional string Filter by guideline chapter name (use the guideline value from /api/guidelines, e.g. Guidelines for System Hardening). Max 60 characters.
applicability optional string Filter to controls that apply to a specific classification level. One of: NC, OS, P, S, TS. Combinable with filter and search — e.g. filter=e8&applicability=S returns Essential Eight controls that apply to SECRET systems.
Response
Field Type Description
total integer Number of controls returned.
controls array Array of control summary objects.
controls[].id string Canonical control ID, e.g. ism-1173.
controls[].display_id string Display-form ID, e.g. ISM-1173.
controls[].label string Short topic label for the control.
controls[].statement string The control's description.
controls[].applicability string[] Classification levels this control applies to. Values: NC (Not Classified), OS (OFFICIAL:Sensitive), P (PROTECTED), S (SECRET), TS (TOP SECRET).
controls[].e8_levels string[] Essential Eight maturity levels. Values: ML1, ML2, ML3. Empty array if not an E8 control.
controls[].change_type string Status in the latest ISM release. One of: new, modified, unchanged, withdrawn.
controls[].updated string | null Month last updated per the ISM, e.g. Sep-2024.
controls[].catalog_version string ISM catalog version this revision belongs to.
controls[].guideline string | null Guideline chapter name.
controls[].section string | null Parent ControlGroup title.
controls[].section_overview string | null Overview text for the parent section.
Example
curl "https://api.secctrl.fyi/api/controls?search=patch&filter=e8"
{
  "total": 8,
  "controls": [
    {
      "id": "ism-1690",
      "display_id": "ISM-1690",
      "label": "Patch management",
      "statement": "An automated mechanism is used ...",
      "applicability": ["NC","OS","P","S","TS"],
      "e8_levels": ["ML1","ML2","ML3"],
      "change_type": "unchanged",
      "updated": "Jun-2024",
      "catalog_version": "2024.09",
      "guideline": "Guidelines for Patch Management",
      "section": "Patch Management",
      "section_overview": "..."
    }
  ]
}
GET /api/controls/:id

Returns full details for a single control: the complete current revision in latest, and a lightweight history array (no statement text) suitable for stats and sparkline rendering. The :id path parameter accepts ISM-1173, ism-1173, or bare 1173 — all are equivalent. Full revision text across all ISM releases back to November 2010 is available via /api/controls/:id/history.

Path parameters
Parameter Type Description
id string Control ID. Case-insensitive. Accepts ISM-1173, ism-1173, or bare 1173. Max 60 characters.
Response
Field Type Description
id string Canonical control ID.
display_id string Display-form ID.
label string Control topic label.
control_class string | null Control type classification, e.g. Technical, Operational, Both.
section string | null Parent ControlGroup title.
section_overview string | null Overview text for the parent section.
latest object Full latest revision, including statement, catalog_version, commit_date, change_type, applicability, applicability_raw, e8_levels, revision, updated, guideline, source, compliance.
history array Lightweight revision history (newest first) for stats/sparkline use. Contains all fields except statement. For full revision text, use /api/controls/:id/history.
history[].catalog_version string ISM catalog version for this revision.
history[].commit_date string ISO 8601 date of this catalog release.
history[].change_type string Change status: new, modified, unchanged, or withdrawn.
history[].applicability string[] Normalised applicability codes.
history[].e8_levels string[] Essential Eight maturity levels at this revision.
history[].guideline string | null Guideline chapter name at this revision.
annotation object | null AI-generated annotation for this control. null if not yet generated.
annotation.ai_view string | null Plain-English factual summary of the control, generated by Claude.
annotation.ai_view_snarky string | null Sardonic "Professional" summary of the control, generated by Claude.
annotation.links array | null JSON array of relevant external links.
annotation.impls array | null JSON array of implementation notes.
annotation.catalog_version string | null ISM catalog version the annotation was generated against.
annotation.updated_at string | null ISO timestamp of when the annotation was last generated.
Example
curl "https://api.secctrl.fyi/api/controls/ism-1173"

# Also works:
curl "https://api.secctrl.fyi/api/controls/1173"
{
  "id": "ism-1173",
  "display_id": "ISM-1173",
  "label": "Application control",
  "control_class": "Technical",
  "section": "System Hardening",
  "section_overview": "...",
  "latest": {
    "catalog_version": "2024.09",
    "commit_date": "2024-09-15",
    "statement": "Application control is implemented ...",
    "change_type": "modified",
    "applicability": ["NC","OS","P","S","TS"],
    "applicability_raw": null,
    "e8_levels": ["ML1","ML2","ML3"],
    "revision": "9",
    "updated": "Sep-2024",
    "guideline": "Guidelines for System Hardening",
    "source": "oscal",
    "compliance": null
  },
  "history": [
    {
      "catalog_version": "2024.09",
      "commit_date": "2024-09-15",
      "change_type": "modified",
      "applicability": ["NC","OS","P","S","TS"],
      "applicability_raw": null,
      "e8_levels": ["ML1","ML2","ML3"],
      "updated": "Sep-2024",
      "guideline": "Guidelines for System Hardening",
      "source": "oscal",
      "compliance": null
    },
    {
      "catalog_version": "2014.01-pdf",
      "commit_date": "2014-01-01",
      "change_type": "unchanged",
      "applicability": ["NC","P","S","TS"],
      "applicability_raw": ["G","P","C","S","TS"],
      "e8_levels": [],
      "updated": "Jan-2014",
      "guideline": "System Hardening",
      "source": "pdf",
      "compliance": "must"
    }
  ],
  "annotation": {
    "ai_view": "ISM-1173 requires organisations to implement application control ...",
    "ai_view_snarky": "Congratulations, you must now whitelist every app ...",
    "links": [],
    "impls": [],
    "catalog_version": "2024.09",
    "updated_at": "2025-02-23T10:00:00Z"
  }
}
GET /api/controls/:id/history

Returns the complete revision history for a control, including the full statement text at every ISM release back to November 2010. This endpoint is rate-limited separately (10 req/min) to protect this unique dataset.

Path parameters
Parameter Type Description
id string Control ID. Case-insensitive. Accepts ISM-1173, ism-1173, or bare 1173. Max 60 characters.
Response
Field Type Description
id string Canonical control ID.
history array Full revision history, newest first. All fields present including statement.
history[].catalog_version string ISM catalog version for this revision.
history[].commit_date string ISO 8601 date of this catalog release.
history[].statement string Control description text at this revision.
history[].change_type string Change status: new, modified, unchanged, or withdrawn.
history[].applicability string[] Normalised applicability codes. Values: NC, OS, P, S, TS, and C (historical Confidential, pre-2019 PDF-era only).
history[].applicability_raw string[] | null Original PDF-era applicability codes; null for OSCAL-era entries.
history[].e8_levels string[] Essential Eight maturity levels at this revision.
history[].revision string | null ISM revision number from the source document.
history[].updated string | null ISM "updated" field, e.g. Sep-2024.
history[].guideline string | null Guideline chapter name at this revision.
history[].source string Data origin: oscal or pdf.
history[].compliance string | null Compliance level from pre-2019 PDF releases: must, should, or recommended.
Example
curl -H "X-Bypass-Token: your-token" \
     "https://api.secctrl.fyi/api/controls/ism-1173/history"
{
  "id": "ism-1173",
  "history": [
    {
      "catalog_version": "2024.09",
      "commit_date": "2024-09-15",
      "statement": "Application control is implemented ...",
      "change_type": "modified",
      "applicability": ["NC","OS","P","S","TS"],
      "applicability_raw": null,
      "e8_levels": ["ML1","ML2","ML3"],
      "revision": "9",
      "updated": "Sep-2024",
      "guideline": "Guidelines for System Hardening",
      "source": "oscal",
      "compliance": null
    }
  ]
}
GET /api/controls/:id/graph

Returns a Cytoscape.js-formatted neighbourhood graph for a control — the requested control as the centre node, with all other controls in the same ControlGroup section as neighbour nodes. Edges connect the centre to each neighbour and are labelled with the section name.

Path parameters
Parameter Type Description
id string Control ID (case-insensitive, same formats as above). Max 60 characters.
Response
Field Type Description
nodes array Cytoscape node elements. Each element has a data object containing id, display_id, label, statement, and role ("center" or "neighbor").
edges array Cytoscape edge elements. Each element has a data object with id, source, target, and group (the section name).
group object The shared ControlGroup: { id: string, title: string }.
Example
curl "https://api.secctrl.fyi/api/controls/ism-1173/graph"
{
  "nodes": [
    {
      "data": {
        "id": "ism-1173",
        "display_id": "ISM-1173",
        "label": "Application control",
        "statement": "...",
        "role": "center"
      }
    },
    {
      "data": {
        "id": "ism-0859",
        "display_id": "ISM-0859",
        "label": "Application control",
        "statement": "...",
        "change_type": "unchanged",
        "role": "neighbor"
      }
    }
  ],
  "edges": [
    {
      "data": {
        "id": "ism-1173--ism-0859",
        "source": "ism-1173",
        "target": "ism-0859",
        "group": "System Hardening"
      }
    }
  ],
  "group": { "id": "sg-sh", "title": "System Hardening" }
}
GET /api/compare

Returns controls that changed between two ISM catalog versions. Both parameters are required; from must be older than to. Version strings are the version values returned by /api/versions. Rate-limited to 2 req/min per IP.

Query parameters
Parameter Type Description
from required string The earlier catalog version to compare from, e.g. 2024.09. Max 60 characters.
to required string The later catalog version to compare to, e.g. 2025.01. Max 60 characters.
Response
Field Type Description
from string The from version as requested.
to string The to version as requested.
total integer Number of changed controls.
changes array Array of changed control objects.
changes[].id string Canonical control ID.
changes[].display_id string Display-form ID, e.g. ISM-1234.
changes[].change_type string How the control changed: new (added in to), modified (description or applicability changed), withdrawn (removed in to).
changes[].guideline string | null Guideline chapter name.
changes[].new_statement string | null Control description in the to version. null for withdrawn controls.
changes[].old_statement string | null Control description in the from version. null for new controls.
changes[].new_applicability string[] | null Applicability codes in the to version.
changes[].old_applicability string[] | null Applicability codes in the from version.
Example
curl "https://api.secctrl.fyi/api/compare?from=2024.09&to=2025.01"
{
  "from": "2024.09",
  "to": "2025.01",
  "total": 42,
  "changes": [
    {
      "id": "ism-1234",
      "display_id": "ISM-1234",
      "change_type": "modified",
      "guideline": "Guidelines for Network Management",
      "new_statement": "...",
      "old_statement": "...",
      "new_applicability": ["OS","P","S"],
      "old_applicability": ["OS","P"]
    },
    {
      "id": "ism-1999",
      "display_id": "ISM-1999",
      "change_type": "new",
      "guideline": "Guidelines for System Hardening",
      "new_statement": "...",
      "old_statement": null,
      "new_applicability": ["NC","OS","P","S","TS"],
      "old_applicability": null
    }
  ]
}

Principles

GET /api/principles

Returns all ISM principles at their latest version, ordered by ID. No query parameters.

Response
Field Type Description
total integer Total number of principles.
principles array Array of principle objects.
principles[].id string Canonical principle ID.
principles[].display_id string Display-form ID.
principles[].label string Principle title.
principles[].statement string Principle description.
principles[].applicability string[] Applicability codes.
principles[].change_type string Change status in the latest release.
principles[].updated string | null Month last updated per the ISM.
principles[].catalog_version string Latest catalog version.
principles[].guideline string | null Guideline chapter name.
principles[].section string | null Parent section title.
Example
curl "https://api.secctrl.fyi/api/principles"

Sections & Guidelines

GET /api/sections

Returns all ControlGroup sections that contain at least one active control, with control counts. Use the returned id value as the section parameter in /api/controls.

Response

Array of section objects, ordered by title.

Field Type Description
id string ControlGroup node ID — use as the section filter value.
title string Section title.
overview string | null Section overview text.
guideline string | null Associated guideline chapter name.
control_count integer Number of active controls in this section.
Example
curl "https://api.secctrl.fyi/api/sections"
[
  {
    "id": "sg-sm",
    "title": "System Management",
    "overview": "...",
    "guideline": "Guidelines for System Management",
    "control_count": 38
  },
  ...
]
GET /api/guidelines

Returns all distinct guideline chapter names with active control counts. Use the returned guideline string as the guideline parameter in /api/controls.

Response

Array of guideline objects, ordered alphabetically.

Field Type Description
guideline string Guideline chapter name.
control_count integer Number of active controls under this guideline.
Example
curl "https://api.secctrl.fyi/api/guidelines"
[
  {
    "guideline": "Guidelines for Data Transfers",
    "control_count": 14
  },
  {
    "guideline": "Guidelines for Email",
    "control_count": 12
  },
  ...
]

Glossary

GET /api/terms

Returns all ISM glossary terms at their latest version, ordered alphabetically. Supports substring search on term names.

Query parameters
Parameter Type Description
search optional string Case-insensitive substring match on the term name. Max 200 characters.
Response
Field Type Description
total integer Number of terms returned.
terms array Array of term summary objects.
terms[].id string Canonical term ID (use with /api/terms/:id).
terms[].term string Term name.
terms[].meaning string Current definition.
terms[].change_type string Change status in the latest release.
terms[].catalog_version string Latest catalog version.
Example
curl "https://api.secctrl.fyi/api/terms?search=encryption"
{
  "total": 3,
  "terms": [
    {
      "id": "term-end-to-end-encryption",
      "term": "End-to-end encryption",
      "meaning": "Encryption where ...",
      "change_type": "unchanged",
      "catalog_version": "2024.09"
    }
  ]
}
GET /api/terms/:id

Returns the full definition history for a single glossary term. Use the id field from /api/terms as the :id path parameter.

Path parameters
Parameter Type Description
id string Term ID as returned by /api/terms. Max 60 characters.
Response
Field Type Description
id string Canonical term ID.
term string Term name.
history array Complete definition history, newest first.
history[].catalog_version string ISM catalog version for this revision.
history[].commit_date string ISO 8601 date of this catalog release.
history[].meaning string Definition at this revision.
history[].change_type string Change status: new, modified, or unchanged.
Example
curl "https://api.secctrl.fyi/api/terms/term-end-to-end-encryption"
{
  "id": "term-end-to-end-encryption",
  "term": "End-to-end encryption",
  "history": [
    {
      "catalog_version": "2024.09",
      "commit_date": "2024-09-15",
      "meaning": "Encryption where ...",
      "change_type": "unchanged"
    },
    {
      "catalog_version": "2023.06",
      "commit_date": "2023-06-12",
      "meaning": "...",
      "change_type": "modified"
    }
  ]
}

Metadata

GET /api/stats

Returns a lightweight summary of catalog statistics — current control, principle, and term counts, plus the latest catalog version string. Designed for header chips and dashboards; returns ~100 bytes rather than downloading the full control list.

Response
Field Type Description
controls integer Number of active (non-withdrawn) controls at latest revision.
principles integer Number of principles at latest revision.
terms integer Number of glossary terms at latest revision.
version string Latest ISM catalog version string, e.g. 2025.12.9.
Example
curl "https://api.secctrl.fyi/api/stats"
{
  "controls": 1073,
  "principles": 84,
  "terms": 275,
  "version": "2025.12.9"
}
GET /api/versions

Returns all distinct ISM catalog versions in the database, ordered chronologically oldest-first. Covers both pre-OSCAL PDF-era releases (version strings suffixed -pdf) and OSCAL releases.

Response

Array of version objects.

Field Type Description
version string Version string, e.g. 2024.09 (OSCAL) or 2021.06-pdf (PDF-era).
date string ISO 8601 release date.
Example
curl "https://api.secctrl.fyi/api/versions"
[
  { "version": "2010.11-pdf", "date": "2010-11-01" },
  { "version": "2010.12-pdf", "date": "2010-12-01" },
  ...
  { "version": "2024.09", "date": "2024-09-15" }
]
GET /

Health check. Confirms the API is reachable.

Example
curl "https://api.secctrl.fyi/"
{ "status": "ok", "service": "ism-explorer-api" }