Skip to content
DocumentationAPI ReferenceChangelog
API ReferenceTalon Studio v1.0.2-beta

Coverage

Read a workspace's ATT&CK coverage: totals, the highest-value gaps, adversary coverage and comparisons, an ATT&CK Navigator layer, and the technique catalogue.

Get coverage

GET/api/v1/coveragecoverage:read

Coverage totals for one workspace. Returned as a flat object, with no data envelope.

Query parameters
workspaceIdstring (UUID)
Required with an org-scoped token; a workspace-bound token uses its own workspace.
Response
workspaceIdstring (UUID)
defaultSiemTypestring
The workspace's primary SIEM.
totals.sourcetypesinteger
Sourcetypes in the connected SIEM's telemetry that map to a recognised ATT&CK data source.
totals.detectionsinteger
Talon detections in any status except deprecated.
totals.detectableTechniquesinteger
Techniques your telemetry can support.
totals.coveredTechniquesinteger
Detectable techniques covered by a Talon detection or an enabled imported SIEM rule.
totals.gapsinteger
Always detectableTechniques − coveredTechniques.
totals.importedCoveredTechniquesinteger
Techniques covered by enabled imported SIEM rules, counted whether or not they are detectable — so it can include techniques outside coveredTechniques.
totals.falseCoverageTechniquesinteger
Covered, detectable techniques whose only Talon detections stayed silent on their last replay and that no imported rule covers. Shown alongside coveredTechniques, not subtracted from it.
Coverage is computed at parent-technique level, so a sub-technique detection (T1055.001) covers its parent (T1055). Imported coverage is already folded into coveredTechniques, not added on top.
Tip
This is the same evidence-grounded coverage Atlas shows, so an integration can track it over time.
Request
curl -H "Authorization: Bearer tlk_…" \
  "https://<your-instance>/api/v1/coverage?workspaceId=…"
Response
{
  "workspaceId": "d41f…",
  "defaultSiemType": "splunk",
  "totals": {
    "sourcetypes": 42,
    "detections": 130,
    "detectableTechniques": 210,
    "coveredTechniques": 88,
    "gaps": 122,
    "importedCoveredTechniques": 14,
    "falseCoverageTechniques": 3
  }
}

List coverage gaps

GET/api/v1/coverage/gapscoverage:read

Uncovered ATT&CK techniques ranked by how many threat groups and campaigns use them — the detections most worth writing next. Only uncovered techniques are returned; meta carries the full tallies.

Query parameters
workspaceIdstring (UUID)
Required with an org-scoped token; a workspace-bound token uses its own workspace.
limitinteger · optional
1–100, default 25. A non-number falls back to 25; out-of-range values are clamped.
Response
data[].idstring
Parent technique id, e.g. T1059.
data[].namestring · nullable
data[].groupCountinteger
ATT&CK groups that use the technique.
data[].campaignCountinteger
ATT&CK campaigns that use the technique.
data[].adversaryCountinteger
groupCount + campaignCount — the ranking weight.
data[].coveredboolean
Always false here.
metaobject
limit, uncovered (all uncovered techniques), covered, techniquesRanked (uncovered + covered).
Sorted by adversaryCount descending, then by technique id. Only techniques used by at least one ATT&CK group or campaign are ranked. Here a technique counts as covered only when a Talon detection (any status except deprecated) maps to it — imported SIEM rules are not counted, unlike GET /coverage and GET /adversaries — so a technique covered only by an imported rule still appears as a gap.
Request
curl -H "Authorization: Bearer tlk_…" \
  "https://<your-instance>/api/v1/coverage/gaps?workspaceId=…&limit=10"
Response
{
  "data": [
    {
      "id": "T1105",
      "name": "Ingress Tool Transfer",
      "groupCount": 98,
      "campaignCount": 21,
      "adversaryCount": 119,
      "covered": false
    }
  ],
  "meta": { "limit": 25, "uncovered": 164, "covered": 51, "techniquesRanked": 215 }
}

Export a Navigator layer

GET/api/v1/coverage/navigator-layercoverage:read

The workspace's coverage as an ATT&CK Navigator layer (layer format 4.5), scored by validation evidence rather than rule count. The response body is the layer itself, sent as a download named talon-navigator-layer.json — save it and open it in ATT&CK Navigator.

Query parameters
workspaceIdstring (UUID)
Required with an org-scoped token; a workspace-bound token uses its own workspace.
adversarystring · optional
An ATT&CK group or campaign id (G0016, C0024), name or alias. Restricts the layer to that adversary's techniques and adds a red gap cell for each one nothing covers.
Response
namestring
"<workspace> — detection coverage", or "<workspace> — <adversary> (<id>) coverage".
versionsobject
attack (the synced ATT&CK version), navigator ("5.1.0"), layer ("4.5").
domainstring
"enterprise-attack".
descriptionstring
techniques[]object[]
techniqueID, score, color, comment (e.g. "2 detections, 1 validated"), enabled.
legendItems[]object[]
label and color for each score band.
metadata[]object[]
generated_by, generated_at, workspace, and adversary when one was given.
Scores: 100 validated (a detection fired on replayed or atomic telemetry) · 75 deployed (live on a SIEM, not yet proven) · 50 exists (authored, or covered by an imported SIEM rule) · 25 false coverage (its only detections stayed silent on the last replay) · 0 gap (adversary mode only). An unknown adversary returns 404 with up to five "Did you mean" suggestions. This response has no envelope and carries no X-RateLimit headers.
Request
curl -H "Authorization: Bearer tlk_…" \
  -o talon-navigator-layer.json \
  "https://<your-instance>/api/v1/coverage/navigator-layer?workspaceId=…&adversary=APT29"
Response
{
  "name": "Corp SecOps — APT29 (G0016) coverage",
  "versions": { "attack": "17", "navigator": "5.1.0", "layer": "4.5" },
  "domain": "enterprise-attack",
  "techniques": [
    {
      "techniqueID": "T1059.001",
      "score": 100,
      "color": "#1a7a3c",
      "comment": "2 detections, 1 validated",
      "enabled": true
    },
    {
      "techniqueID": "T1566",
      "score": 0,
      "color": "#d13b3b",
      "comment": "GAP — used by this adversary, no detection covers it",
      "enabled": true
    }
  ]
}

List adversaries

GET/api/v1/adversariescoverage:read

ATT&CK threat groups and campaigns, each with how many of its techniques the workspace covers. Returns summary rows by default; pass name to get one adversary in full.

Query parameters
workspaceIdstring (UUID)
Required with an org-scoped token; a workspace-bound token uses its own workspace.
namestring · optional
A group or campaign id (G0016, C0024), canonical name or alias, case-insensitive. Returns that adversary in full instead of the list.
Response
data.groups[]object[]
Threat groups: pinned watchlist actors first, then those relevant to the workspace's threat profile, then by technique count.
data.campaigns[]object[]
Campaigns, by technique count.
…idstring
G#### or C####.
…namestring
…aliasesstring[]
…techniqueCountinteger
Parent techniques the adversary uses.
…coveredCountinteger
Of those, how many a Talon detection or an enabled imported SIEM rule covers.
…attributedTostring[]
Campaigns only: the groups the campaign is attributed to.
…relevantToProfileboolean
Groups only: matches the threat profile's sector or region.
…pinnedboolean
Groups only: on the threat profile's priority-actor list.
With name, data is a single adversary: the summary fields plus description, techniques[] ({ id, name, covered }, uncovered first) and procedureExamples[] ({ adversaryId, adversaryName, techniqueId, description } — MITRE's examples of how this adversary uses each technique). An unknown name returns 404 with up to five "Did you mean" suggestions.
Request
curl -H "Authorization: Bearer tlk_…" \
  "https://<your-instance>/api/v1/adversaries?workspaceId=…&name=APT29"
Response
{
  "data": {
    "groups": [
      {
        "id": "G0016",
        "name": "APT29",
        "aliases": ["IRON RITUAL", "NobleBaron", "Cozy Bear"],
        "techniqueCount": 87,
        "coveredCount": 60,
        "relevantToProfile": true,
        "pinned": false
      }
    ],
    "campaigns": [
      {
        "id": "C0024",
        "name": "SolarWinds Compromise",
        "aliases": [],
        "techniqueCount": 64,
        "coveredCount": 41,
        "attributedTo": ["APT29"]
      }
    ]
  }
}

Compare adversaries

GET/api/v1/adversaries/comparecoverage:read

Compare the workspace's coverage against two to five adversaries at once. sharedGaps are uncovered techniques every one of them uses — closing one closes a gap against all of them; uniqueGaps are the uncovered techniques only one of them uses.

Query parameters
workspaceIdstring (UUID)
Required with an org-scoped token; a workspace-bound token uses its own workspace.
adversariesstringrequired
2–5 comma-separated ids, names or aliases, e.g. APT29,FIN7.
Response
data.adversaries[]object[]
id, name, techniqueCount, coveredCount, uncoveredCount.
data.sharedGaps[]object[]
id, name, covered (false) — techniques every compared adversary uses and nothing covers.
data.uniqueGaps[]object[]
adversaryId, adversaryName, techniques[] — per adversary, the uncovered techniques none of the others use.
Fewer than two or more than five names returns 400. Names that resolve to the same adversary count once, and fewer than two distinct adversaries returns 400. An unknown name returns 404 with suggestions. Coverage has the same meaning as in GET /adversaries.
Request
curl -H "Authorization: Bearer tlk_…" \
  "https://<your-instance>/api/v1/adversaries/compare?workspaceId=…&adversaries=APT29,FIN7"
Response
{
  "data": {
    "adversaries": [
      { "id": "G0016", "name": "APT29", "techniqueCount": 87, "coveredCount": 60, "uncoveredCount": 27 },
      { "id": "G0046", "name": "FIN7", "techniqueCount": 72, "coveredCount": 49, "uncoveredCount": 23 }
    ],
    "sharedGaps": [
      { "id": "T1566", "name": "Phishing", "covered": false }
    ],
    "uniqueGaps": [
      { "adversaryId": "G0016", "adversaryName": "APT29", "techniques": [] },
      { "adversaryId": "G0046", "adversaryName": "FIN7", "techniques": [] }
    ]
  }
}

Get ATT&CK technique

GET/api/v1/mitre/techniques/{techniqueId}coverage:read

One technique from the instance's synced ATT&CK catalogue: its definition, tactics, data components, who uses it, how to mitigate it, and MITRE's procedure examples. Reference data — it takes no workspaceId and works with any token that holds coverage:read.

Path parameters
techniqueIdstringrequired
A technique or sub-technique id, e.g. T1059.001. Trimmed and upper-cased before lookup.
Response
data.idstring
data.namestring
data.descriptionstring · nullable
data.tacticstring
Primary tactic name, e.g. Execution.
data.tacticsListstring[]
data.dataComponentsobject[]
ATT&CK data components that can observe the technique.
data.threatGroupsstring[]
Names of groups that use it.
data.campaignsstring[]
data.softwarestring[]
Malware and tools that implement it.
data.mitigationsstring[]
data.nistControlsstring[]
data.procedureExamplesobject[]
Up to 20, by adversary name: adversaryId, adversaryName, techniqueId, description.
An unknown id returns 404 with up to five near matches ("Did you mean: T1059 (Command and Scripting Interpreter)?"), or a note that the MITRE catalogue may not be synced yet.
Request
curl -H "Authorization: Bearer tlk_…" \
  "https://<your-instance>/api/v1/mitre/techniques/T1059.001"
Response
{
  "data": {
    "id": "T1059.001",
    "name": "PowerShell",
    "tactic": "Execution",
    "tacticsList": ["Execution"],
    "threatGroups": ["APT29", "FIN7"],
    "mitigations": ["Execution Prevention"],
    "procedureExamples": [
      {
        "adversaryId": "G0016",
        "adversaryName": "APT29",
        "techniqueId": "T1059.001",
        "description": "…"
      }
    ]
  }
}