GCD AI RADAR

API

Every number on GCD AI RADAR comes from static files anyone can fetch: no key, no sign-up, open to scripts on any site. This page lists each file with its fields, says how often it changes, and states the counting rules a figure must keep when it is carried elsewhere. Carry the numbers, cite the site and link back.

stable since 2026-10-18 · change policy

Quick start

For the headline figures, fetch summary.json. As of this build it says 117 incidents in the 12 months from 2025-11 to 2026-10, of which 85 real-world.

curl
curl -s https://gcd-ai-radar.vercel.app/data/summary.json
curl -s https://gcd-ai-radar.vercel.app/data/summary.json | jq '.trailing_12'
curl -sO https://gcd-ai-radar.vercel.app/data/incidents.csv
fetch (browser or Node 18+)
const res = await fetch("https://gcd-ai-radar.vercel.app/data/summary.json");
const s = await res.json();
const t = s.trailing_12;
console.log(`${t.incidents} AI cybersecurity incidents from ${t.from} to ${t.to}`
  + ` (${t.real_world} real-world), source: GCD AI RADAR, https://gcd-ai-radar.vercel.app`);

Files

All paths are on https://gcd-ai-radar.vercel.app. Stable files follow the change policy; internal files serve this site’s own pages and may change shape without notice.

Updates and caching

pathresponse headers
/data/*
Access-Control-Allow-Origin: *
Cache-Control: public, max-age=3600, stale-while-revalidate=86400
/feed.xml
Access-Control-Allow-Origin: *
Cache-Control: public, max-age=3600, stale-while-revalidate=86400
/og/*
Cache-Control: public, max-age=3600, stale-while-revalidate=86400

Read from the site’s vercel.json. Every response also carries the site’s security headers; everything except /embed refuses to be framed.

summary.json

The headline numbers, computed by the same functions as the dashboard on the same records. Months are placed by incident date; incidents known only to the year count in totals but in no month or window. Percent changes are rounded to a tenth, and are null when the earlier period had none (the dashboard shows that as “new”).

fieldtypemeaning
version1Bumped only for a breaking change, with a change-log entry.
generated_atstring (RFC 3339)When the deploy generated the file; the windows end in this month.
sitestring (URL)The site's base URL, for the link back.
last_collector_runstring (RFC 3339) | nullWhen the collector last finished a run.
date_basis"incident_date"Months are placed by incident date, the site's default axis.
counting_rulestringThe disclosed-vulnerability rule in one sentence.
totals{ records, incidents, real_world, disclosed_vulnerabilities }All-time counts. real_world is incidents of severity 3 or 4. records = incidents + disclosed_vulnerabilities.
this_month{ month, incidents, last_month, delta_pct }The current month so far against the whole of last month.
year_to_date{ year, incidents, last_year_same_period, delta_pct }This calendar year to date against the same span of last year.
trailing_12{ from, to, incidents, real_world, prior, delta_pct }The last 12 months including the current one; prior is the 12 before. Months are YYYY-MM, inclusive.
trailing_24{ from, to, incidents, real_world, prior, delta_pct }The same for 24 months.
provisional_fromstring (YYYY-MM)First month still provisional (within 60 days of generation): its count will rise.
monthly{ month, incidents, real_world, disclosed_vulnerabilities, provisional }[]The last 24 months, oldest first, ending with the current month. Sums to trailing_24.
licensestring"CC BY-SA 4.0".
license_urlstring (URL)The licence text.
cite_asstringA citation line; replace <date> with the date you accessed the data.
excerpt, as of this build
{
  "generated_at": "2026-10-19T13:12:44.504Z",
  "trailing_12": {
    "from": "2025-11",
    "to": "2026-10",
    "incidents": 117,
    "real_world": 85,
    "prior": 158,
    "delta_pct": -25.9
  },
  "monthly": [
    {
      "month": "2026-09",
      "incidents": 9,
      "real_world": 7,
      "disclosed_vulnerabilities": 200,
      "provisional": true
    },
    {
      "month": "2026-10",
      "incidents": 25,
      "real_world": 9,
      "disclosed_vulnerabilities": 105,
      "provisional": true
    }
  ],
  "…": "…"
}

Record fields

Full record

In incidents.json, years/<year>.json and incidents/<slug>.json. Types are generated from the validation schema, so a record that does not match them is never published. Definitions of each value are on the methodology page.

fieldtypemeaning
idstringStable identifier, AIR-<year>-<number>. Never reused.
slugstringURL slug; the record's page is /incidents/<slug>.
titlestring (≤ 160 chars)Headline written for the record.
summarystring (≤ 700 chars)Two sentences in the site's own words, never quoted article text.
type"attack_on_ai" | "ai_enabled_attack"Attack on AI, or AI-enabled attack.
categoriesenum[] (1–4 items)Ordered by relevance; the first is the primary category, which monthly counts use.
prompt_injection · jailbreak · agent_hijack · data_leak · model_theft_extraction · supply_chain · data_poisoning · adversarial_evasion · infra_vuln · deepfake_fraud · ai_generated_malware · ai_phishing_social_engineering · ai_assisted_intrusion · other
severity1 | 2 | 3 | 41 research, 2 disclosed vulnerability, 3 confirmed exploitation, 4 confirmed real-world loss. 3 and 4 are real-world.
targetsenum[] (1–6 items)Controlled list of who or what was hit.
OpenAI · Anthropic · Google · Microsoft · Meta · Mistral · xAI · Amazon · Apple · open_weight_model · framework_or_tooling · enterprise_deployment · individual_victims · n/a
productsstring[] (0–10 items)Free-text product names.
incident_datestringWhen it happened: YYYY, YYYY-MM or YYYY-MM-DD.
incident_date_precision"day" | "month" | "year"How precise incident_date is.
first_reportedstring (YYYY-MM-DD)Earliest source date.
sourcesobject[] (1–∞ items)The reporting: one entry per article, linking to the original.
sources[].urlstring (URL)Link to the original article or advisory (http or https only).
sources[].publisherstringPublisher name.
sources[].titlestringThe article's own title.
sources[].published_atstring (YYYY-MM-DD)Publication date.
source_countintegerAlways equals the length of sources.
confidencenumber (0–1)Classifier confidence, 0 to 1.
status"published" | "review" | "rejected"Always "published" in the public files.
originenumWhere the record came from; seed_* are historical backfills.
seed_aiid · seed_atlas · seed_avid · seed_nvd · seed_ghsa · news · manual
tagsstring[] (0–20 items)Free-text tags.
created_atstring (RFC 3339)When the record was created.
updated_atstring (RFC 3339)When the record last changed.

Slim record

In incidents.min.json: the full record without sources, confidence, status, tags and timestamps, plus two fields.

fieldtypemeaning
idstringAs in the full record.
slugstringAs in the full record.
titlestring (≤ 160 chars)As in the full record.
summarystring (≤ 700 chars)As in the full record.
type"attack_on_ai" | "ai_enabled_attack"As in the full record.
categoriesenum[] (1–4 items)As in the full record.
prompt_injection · jailbreak · agent_hijack · data_leak · model_theft_extraction · supply_chain · data_poisoning · adversarial_evasion · infra_vuln · deepfake_fraud · ai_generated_malware · ai_phishing_social_engineering · ai_assisted_intrusion · other
severity1 | 2 | 3 | 4As in the full record.
targetsenum[] (1–6 items)As in the full record.
OpenAI · Anthropic · Google · Microsoft · Meta · Mistral · xAI · Amazon · Apple · open_weight_model · framework_or_tooling · enterprise_deployment · individual_victims · n/a
productsstring[] (0–10 items)As in the full record.
incident_datestringAs in the full record.
incident_date_precision"day" | "month" | "year"As in the full record.
first_reportedstring (YYYY-MM-DD)As in the full record.
source_countintegerAs in the full record.
publishersstring[]Distinct publishers of the sources, in source order. Replaces the sources array.
originenumAs in the full record.
seed_aiid · seed_atlas · seed_avid · seed_nvd · seed_ghsa · news · manual
disclosedbooleanTrue for a disclosed vulnerability (a CVE or advisory with no confirmed exploitation). Count only records where this is false.

incidents.csv

Columns in this order. List fields (categories, targets, products, tags) are joined with “; ”. record_kind is incident or disclosed_vulnerability; first_source_url is the first source’s link and url the record’s page here. owasp_llm and atlas list the OWASP LLM Top 10 entries and MITRE ATLAS techniques an incident maps to; they are derived from its type and categories, not classified per record (standards mapping), and meta.json names the editions. A cell that a spreadsheet would run as a formula is prefixed with a single quote.

id, slug, title, type, categories, severity, targets, products, incident_date, incident_date_precision, first_reported, source_count, confidence, origin, record_kind, owasp_llm, atlas, tags, summary, first_source_url, url

meta.json

fieldtypemeaning
generated_atstring (RFC 3339)When the deploy generated the files.
sitestring (URL)The site's base URL.
recordsintegerEvery published record: incidents plus disclosed vulnerabilities.
incidentsintegerRecords that count as incidents.
disclosed_vulnerabilitiesintegerCVEs and advisories with no confirmed exploitation; not incidents.
counting_rulestringThe disclosed-vulnerability rule in one sentence.
yearsobject[]Per year of first report: year, records, incidents, disclosed_vulnerabilities, file (the years/<year>.json path).
last_collector_runstring (RFC 3339) | nullWhen the collector last finished a run; null before the first run.
standards_mapping{ owasp_llm_top_10, mitre_atlas_release, rule }The OWASP LLM Top 10 edition and MITRE ATLAS release the CSV's owasp_llm and atlas columns refer to. Those columns are derived from type and categories, not classified per record.
licensestring"CC BY-SA 4.0".
license_urlstring (URL)The licence text.

years/index.json

fieldtypemeaning
generated_atstring (RFC 3339)When the deploy generated the files.
yearsobject[]Newest year first: year, records, incidents, disclosed (disclosed vulnerabilities), file.

feed.xml

RSS 2.0. Each item has the title, a link to the record’s page, the record id as a non-permalink guid, the first-report date as pubDate, a description (summary, severity, type, source count) and one category per incident category.

Internal files

rows/<year>.json holds compact rows (id, slug, title, incident_date, incident_date_precision, first_reported, type, categories, severity, targets, source_count, disclosed, product); slim/<year>.json holds slim records; search-index.json maps title, id and product tokens to records. They exist for this site’s pages and are not covered by the change policy. Use the stable files instead.

Counting rules

A figure carried from these files means what it means here only if it keeps these rules. Quoted from the methodology:

Disclosed vulnerabilities. A record is a disclosed vulnerability when its severity is below 3 and it either comes from the NVD or GitHub advisory backfills or every one of its sources is a vulnerability database. Anything reported by the press or by researchers counts as an incident.

In code: severity < 3, and either origin is seed_nvd or seed_ghsa, or every source’s publisher is one of “NVD”, “GitHub Advisory Database”, “MSRC”. summary.json, meta.json and feed.xml already apply it; incidents.min.json carries it as disclosed and incidents.csv as record_kind. incidents.json and the year files hold both kinds without a flag, so apply the rule before counting them.

Full context, including the known limits of the numbers, is on the methodology page.

Embed

A card with the trailing count, its change, the real-world count and the monthly bars, linking back here. It is plain HTML that renders without JavaScript; with JavaScript it also fetches summary.json, so a copy cached by your page still shows the latest figures.

html
<iframe src="https://gcd-ai-radar.vercel.app/embed?theme=dark&amp;window=12m"
  title="GCD AI RADAR: AI cybersecurity incidents, last 12 months"
  width="360" height="260" loading="lazy"
  style="border:0;max-width:100%"></iframe>
<noscript><a href="https://gcd-ai-radar.vercel.app">GCD AI RADAR: AI cybersecurity incidents</a></noscript>
compact, light
<iframe src="https://gcd-ai-radar.vercel.app/embed?theme=light&amp;compact=1"
  title="GCD AI RADAR: AI cybersecurity incidents, last 12 months"
  width="360" height="150" loading="lazy"
  style="border:0;max-width:100%"></iframe>
<noscript><a href="https://gcd-ai-radar.vercel.app">GCD AI RADAR: AI cybersecurity incidents</a></noscript>
optionvalueseffect
themedark (default) | lightColours for a dark or a light page.
window12m (default) | 24mThe trailing window counted and drawn, compared with the window before it.
compact1One line of figures without the bars: 150 px tall at 320 px wide, 100 px from 480 px wide.

Any other value falls back to the default. The card fills the iframe: 260 px tall fits every width from 320 px, and from 480 px wide, where the bars sit beside the figures, 190 px is enough.

Attribution

The data is CC BY-SA 4.0. Reuse it, including commercially, as long as you credit GCD AI RADAR with a link and the date you accessed it, say if you changed it, and release a derived dataset under the same licence. Upstream sources carry their own notices, listed on the data page; keep them when you redistribute records.

cite as
GCD AI RADAR, https://gcd-ai-radar.vercel.app (accessed YYYY-MM-DD). Data licensed CC BY-SA 4.0.
cite as, html
Source: <a href="https://gcd-ai-radar.vercel.app">GCD AI RADAR</a>, accessed YYYY-MM-DD.
Data licensed <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>.

Stability and changes

Stable since 2026-10-18.

Change log