Events: individual reports, and ingesting your own.
An Event is one report: a vendor write-up, a news article, an advisory, a leak-site post, or something you uploaded yourself. This endpoint is the raw reporting layer.
Most integrations want Threat Events instead: the occurrences those reports describe. Come here when you need the individual documents: to read your account's analysis of one, to see who published what, or to push your own intelligence in.
Reading requires events.read; ingesting requires events.write.
List reports
GET /api/v1/events/ returns your reports, cursor-paginated.
{
"results": [
{
"id": "a1b2c3d4-...",
"title": "Hospital group confirms ransomware incident",
"criticality": "high",
"tlp": "TLP:GREEN",
"enrichment_status": "complete",
"threat_event_id": "8f1a2b3c-...",
"event": {
"id": "9a8b7c6d-...",
"title": "Hospital group confirms ransomware incident",
"source": "BleepingComputer",
"module": "Cyber news and reports",
"source_icon_url": "https://api.liberty91.com/static/.../news.png",
"reliability": "C",
"report_type": "news-article",
"report_subtype": null,
"url": "https://example.test/report",
"timestamp": "2026-07-24T16:03:00Z",
"sectors": ["healthcare"],
"regions": ["de"],
"enrichment_status": "complete"
}
}
]
}threat_event_id is the field that connects the two layers. Several
reports about one breach share it. It is null for a report not yet matched to
an occurrence, and for one whose occurrence was rejected or merged away.
| Filter | Meaning |
|---|---|
threat_event | Only reports describing this occurrence |
enrichment_status | new, in_progress, enriched_for_user, enriched_for_billing_account, complete, failed |
since | ISO 8601 date or datetime |
An unrecognised enrichment_status is a 400. It used to return an empty page
with a 200, which reads as "nothing in that state".
report_type classifies what kind of document a report is, independently of
what occurred, since a news article and a vendor advisory can describe the same
breach. reliability is the publisher's Admiralty grade, so you can weigh a
report without fetching its occurrence.
module and source_icon_url
module names the module the report arrived through, using the module's own name. Ransomware
leak-site victim claims come back as "Ransomware.live", with the dot, on reports titled
after the group and the company it names, and with reliability of B. The frontend route
for the same module is spelled ransomwarelive without the dot, so do not derive one from
the other.
source_icon_url is an absolute URL to an icon for the source: the source's own icon where
it has one, a generic dark-web icon for forum posts, the module's logo otherwise, and a
favicon derived from the article URL as a last resort. It is null when none of those
resolve. Liberty91's own assets resolve against the host you called, but the first and last
cases can point at a third-party host, such as the avatar on a social post or a favicon
service, which is worth knowing if your egress is restricted. Treat it as an opaque URL to
fetch rather than a path to construct. Dark-web forum posts deliberately share one generic
icon, because onion sites cannot be fetched for a favicon.
Report detail
GET /api/v1/events/{id}/ adds the description, the full content, and the
analysis written for your account, plus the linked entities.
The description, content and analysis fields contain rich-text HTML.
Sanitise them the way you would any HTML from an external system.
Ingest your own intelligence
Anything you can turn into text, whether a premium vendor report, a trust-group advisory, or an internal incident write-up, can be ingested and treated like any other reporting.
curl -X POST "https://api.liberty91.com/api/v1/events/ingest/" \
-H "X-API-Key: $LIBERTY91_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Trust group advisory: new phishing kit targeting EU banks",
"text": "Full text of the advisory goes here...",
"source": "FS-ISAC",
"url": "https://example.test/advisory",
"threat_actors": [{"name": "Scattered Spider"}],
"vulnerabilities": [{"name": "CVE-2026-1234"}]
}'title is required and the body goes in text (description is accepted as an
alias). The entity arrays are optional hints: pass {"id": ...} or
{"name": ...} to link known entities up front, and the pipeline extracts the
rest from the text.
{
"event_instance_id": "a1b2c3d4-...",
"event_id": "d4c3b2a1-...",
"status": "accepted"
}Your uploads are a private source
An ingested report is private to your account, and IOCs extracted from it
are marked TLP:RED. It does more than sit in your feed: it contributes to
Threat Events for you. If it describes an occurrence you can already see, it
attaches to it as another source; if it describes something new, it creates an
occurrence only you can see. Either way it is masked out of every other
account's view, so your reporting never feeds anyone else's intelligence.
Polling to completion
POST /api/v1/events/ingest/and keep the returnedevent_instance_id.- Poll
GET /api/v1/events/{event_instance_id}/and readenrichment_status. It starts atnew, moves throughin_progress, and settles atcomplete(orfailed). - Once complete,
threat_event_idnames the occurrence it was matched to, and the extracted entities and IOCs are available through the read endpoints.
Enrichment typically takes a few minutes depending on the length of the text, so poll every 15 to 30 seconds rather than in a tight loop. Each poll is a normal detail read and costs 1 credit; ingestion itself costs 10.
Frequently asked questions
Should I read /events/ or /threat-events/?
Read /threat-events/ for what happened and /events/ for who reported it.
Events are one row per report, so the same breach appears several times; each
row names the Threat Event it belongs to.
Can I push my own intelligence into Liberty91 via the API?
Yes. POST a title and text to /api/v1/events/ingest/ and the platform creates
a private report, enriches it, and matches it into a Threat Event for your
account only.
Are ingested reports visible to other Liberty91 customers?
No. An ingested report is private to your account. It contributes to Threat
Events for you and is masked out of every other account's view, and IOCs
extracted from it are marked TLP:RED.