Liberty91

Threat Events: the deduplicated occurrence layer.

Last updated 29 Jul 20267 min read

This is the endpoint most integrations should start from. A Threat Event is a real-world occurrence, whether a specific breach, a specific exploitation campaign, or a specific leak, with every report describing it attached. Reporting repeats itself, so a report-per-item feed hands you six near-identical entries and leaves you to work out they are the same story. Here you read the occurrence once.

Requires the threat-events.read scope.

List Threat Events

GET /api/v1/threat-events/

curl "https://api.liberty91.com/api/v1/threat-events/?verification=corroborated&target_sector=Healthcare" \
  -H "X-API-Key: $LIBERTY91_API_KEY"
{
  "next": "https://api.liberty91.com/api/v1/threat-events/?cursor=cD0yMDI2LTA3LTI5",
  "previous": null,
  "results": [
    {
      "id": "8f1a2b3c-4d5e-6f70-8192-a3b4c5d6e7f8",
      "title": "Ransomware attack on a regional hospital group",
      "summary": "...",
      "event_class": "security-incident",
      "event_type": "intrusions",
      "verification": "corroborated",
      "credibility": 2,
      "credibility_label": "Probably True",
      "occurred_start": "2026-07-18T00:00:00Z",
      "occurred_end": null,
      "first_reported_at": "2026-07-19T08:12:00Z",
      "last_reported_at": "2026-07-24T16:03:00Z",
      "sectors": ["healthcare"],
      "regions": ["de", "western europe"],
      "report_count": 4,
      "source_count": 3,
      "latest_source": "BleepingComputer",
      "merged_into": null,
      "created_at": "2026-07-19T08:20:00Z"
    }
  ]
}

Filters

FilterMeaning
qFree text over title and summary
event_class, event_typeTaxonomy classification, see what happened
verificationauto, corroborated, verified, disputed, rejected, merged
min_credibility1 to 6; returns bands at least this good, so 2 gives you 1 and 2
source_count1, 2, 3+: how many independent sources reported it
target_sectorSector name or code
target_country, source_countryCountry name or ISO code: who was hit, and where the reporting came from
techniqueATT&CK technique id, e.g. T1566 or T1566.001
occurred_after, occurred_beforeWhen it happened (ISO 8601)
last_reported_after, last_reported_beforeWhen it was last written about
relevanttrue: only occurrences matched to your account
organizationOrganization UUID: only occurrences affecting that organization
intel_requirementIntelligence Requirement UUID

An unrecognised filter value is a 400, not an empty list. A mistyped sector returning zero results silently would read as "nothing in that sector", which is the opposite of the truth.

Threat Event detail

GET /api/v1/threat-events/{id}/ adds the evidence.

{
  "id": "8f1a2b3c-...",
  "title": "Ransomware attack on a regional hospital group",
  "credibility": 2,
  "credibility_label": "Probably True",
  "sources": [
    {
      "report_id": "1c2d3e4f-...",
      "title": "Hospital group confirms ransomware incident",
      "url": "https://example.test/report",
      "source_name": "BleepingComputer",
      "module": "Cyber news and reports",
      "published_at": "2026-07-24T16:03:00Z",
      "stance": "corroborates",
      "reliability": "C",
      "reliability_label": "Fairly reliable",
      "event_id": "9a8b7c6d-..."
    }
  ],
  "actors": [{"id": "...", "name": "Qilin", "from_private_source": false}],
  "malware": [],
  "vulnerabilities": [],
  "victims": [{"name": "Regional Hospital Group", "role": "victim"}],
  "techniques": [
    {"technique_id": "T1486", "name": "Data Encrypted for Impact",
     "description": null, "from_private_source": false}
  ],
  "organizations": [
    {
      "organization_id": "...",
      "organization_name": "Acme Hospital",
      "matched_sectors": ["Healthcare"],
      "matched_regions": ["Germany"],
      "matched_requirements": [
        {"id": "...", "title": "Ransomware in healthcare", "priority": "HIGH", "scope": "ACCOUNT"}
      ],
      "exposure": null
    }
  ],
  "organizations_truncated": false,
  "intelligence_requirements": [...]
}

event_id on a source is your copy of that report; pass it to /events/{id}/ for your account's analysis of it. It is null for a public report you have not been rendered a copy of.

What you can and cannot see

You see a Threat Event when you are entitled to at least one of the reports behind it, and you see only those reports.

This matters more than it sounds. A single occurrence can carry a public news article, a premium vendor report one customer licenses, and a report another customer uploaded themselves. All three contribute to the same occurrence. Each customer sees the occurrence plus the sources they hold, never anyone else's.

report_count and source_count are computed the same way, over only the reports you can see. A count that included sources you are not entitled to would tell you they exist, which is why it does not.

Note

If you are entitled to an occurrence only through a report you uploaded or licensed privately, the title you see is your own report's title. Once public reporting names the occurrence, that public headline becomes the shared title for everyone, including you.

Reading the trust signals

Three separate judgements travel with every occurrence. They answer different questions and should not be collapsed into one number.

Source reliability (reliability, A to F): who said it. A property of the publisher, not of this occurrence. A is completely reliable, F means reliability cannot be judged. Grades start from the source class (government, vendor, news) and move on evidence.

Credibility (credibility, 1 to 6): how well-supported the claim is. Only public, attributable reporting counts, and reports that are the same story re-published are collapsed to one source.

BandLabelRead it as
1ConfirmedSeveral reliable independent sources, actionable
2Probably TrueIndependently corroborated, actionable
3Possibly TrueOne moderate source, corroborate before acting
4DoubtfulWeak or passing sourcing only
5ImprobableOnly unreliable-grade sourcing
6Cannot be judgedNo attributable sources

Verification (verification): where the occurrence stands overall. auto is machine-created from a single source; corroborated is reached automatically at two independent sources; verified, disputed and rejected are analyst judgements the automatic pipeline never overwrites. merged means it was folded into another occurrence, and merged_into names it.

Stance is a property of each report, not the occurrence: whether that source claims, corroborates, updates, mentions or disputes it. Disagreement stays visible rather than being averaged away.

Tip

For a triage queue, ?verification=corroborated&min_credibility=2 is a good starting filter: occurrences at least two independent sources agree on.

Relevance to your organizations

organizations[] answers why this matters to you, per organization, and it is the field that turns a feed into a work queue. An occurrence surfaces for an organization when it hits their sector, their region, something they actually run (exposure), or a topic they follow (matched_requirements). Each row says which.

# everything relevant to one organization
curl "https://api.liberty91.com/api/v1/threat-events/?organization=$ORG_ID" \
  -H "X-API-Key: $LIBERTY91_API_KEY"

IOCs and STIX

# indicators from the reporting you hold on this occurrence
curl ".../threat-events/$ID/iocs/" -H "X-API-Key: $KEY"
 
# a STIX 2.1 bundle carrying the occurrence AND its indicators, linked
curl ".../threat-events/$ID/iocs/export/" -H "X-API-Key: $KEY" -o bundle.json
 
# the occurrence, its sources and its entities as linked STIX objects
curl ".../threat-events/$ID/stix/" -H "X-API-Key: $KEY" -o event.json

These bundles are parented: they carry the occurrence itself plus relationships to each indicator, so a TIP keeps the context.

/stix/ additionally requires threats.read, because the bundle names the threat actors and malware involved with their aliases and ATT&CK identifiers, which is catalog data the threat library gates. The IOC endpoints additionally require iocs.read. The flat /iocs/export/?format=stix bundle is an indicator list with no such context: right for a blocklist, wrong for MISP or OpenCTI.

Classifying what happened

event_class puts an occurrence on one of a few axes, and event_type classifies within it. The security-incident types are the ENISA/TF-CSIRT RSIT machine tags verbatim.

event_classWhat it coversExample event_type values
security-incidentSomething adverse happened to an identifiable victimintrusions, availability, information-content-security, malicious-code, fraud, intrusion-attempts, information-gathering, vulnerable, abusive-content
vulnerabilityA vulnerability lifecycle event in a product, no named victimdisclosure, proof-of-concept, exploited-in-the-wild
threat-developmentCapability news with no victimnew malware or capability, actor tooling shifts
data-exposureUnderground listings and leaks as artifactsbreach listing, credential dump
Note

A vulnerability with a named exploited victim is a security-incident, not a vulnerability, because the axis is what happened in the world, not what the report is about. The report's own document type is separate, and travels on the report: see report_type on Events.

Frequently asked questions

What is the difference between /threat-events/ and /events/?

A Threat Event is the occurrence, one specific breach. An Event is one report about it. Six write-ups of the same breach are six Events and one Threat Event, and each Event names the Threat Event it belongs to.

Why can I see a Threat Event but only some of its sources?

You see the reports you are entitled to. A private source another customer licenses contributes to the occurrence but is masked out of your view of it, and never appears in your counts.

What do the credibility numbers mean?

They are the Admiralty information-credibility scale: 1 Confirmed, 2 Probably True, 3 Possibly True, 4 Doubtful, 5 Improbable, 6 Cannot be judged. Lower is better. Treat 1-2 as actionable and 3 as something to corroborate first.

Was this page helpful?