Skip to main content
GET
/
api
/
v1
/
articles
curl -H "Authorization: Bearer sk_live_..." \
  "https://socdefenders.ai/api/v1/articles?category=vulnerabilities&severity=critical&limit=10"
{
  "meta": {
    "limit": 3,
    "offset": 0,
    "total": null,
    "total_estimated": false,
    "generated_at": "2026-05-17T10:30:00Z",
    "feed_version": "1.0",
    "source": "SOC Defenders",
    "filters": {
      "time_field": "published_at",
      "since": "2026-05-10T00:00:00Z",
      "sort": "published:desc",
      "category": [
        "vulnerabilities"
      ]
    }
  },
  "data": [
    {
      "id": "e90ea8b7-8500-4a14-875c-1d64755c80ca",
      "title": "PoC Code Published for Critical NGINX Vulnerability",
      "url": "https://www.securityweek.com/poc-code-published-for-critical-nginx-vulnerability/",
      "canonical_url": "https://socdefenders.ai/item/e90ea8b7-8500-4a14-875c-1d64755c80ca",
      "summary": "Researchers have released proof-of-concept exploit code for a critical vulnerability in NGINX that could allow remote code execution...",
      "ai_summary": "A critical RCE vulnerability in NGINX (CVE-2026-12345) has working PoC code circulating. Affected versions: 1.20.0-1.24.0. CVSS 9.8.",
      "image_url": "https://www.securityweek.com/wp-content/uploads/2026/05/nginx-vuln.jpg",
      "published_at": "2026-05-16T10:02:00Z",
      "fetched_at": "2026-05-16T10:05:23Z",
      "modified_at": "2026-05-16T10:08:11Z",
      "source_name": "SecurityWeek",
      "source_type": "rss",
      "source_tier": 1,
      "category": "vulnerabilities",
      "category_label": "Vulnerabilities",
      "category_legacy": "Vulnerabilities",
      "content_type": "security",
      "severity_score": 9.2,
      "severity_label": "critical",
      "categorized_by": "ai",
      "categorized_at": "2026-05-16T10:07:55Z",
      "ai_classification": "critical-rce-with-poc",
      "ai_classification_confidence": 0.94,
      "tech_tags": [
        "nginx",
        "rce"
      ],
      "industry_tags": [
        "technology"
      ],
      "threat_actors": [],
      "has_iocs": false,
      "ioc_count": 0,
      "score": 0,
      "upvotes": 0,
      "downvotes": 0,
      "comment_count": 0,
      "vouch_count": 0,
      "rank_score": 0,
      "submission_type": "rss_auto",
      "submitted_by_username": null,
      "audio_url": null,
      "audio_duration_seconds": null,
      "audio_voice": null,
      "mitre_techniques": [
        {
          "id": "T1190",
          "name": "Exploit Public-Facing Application",
          "tactic": "initial-access",
          "confidence": "high"
        }
      ]
    }
  ],
  "links": {
    "self": "https://socdefenders.ai/api/v1/articles?category=vulnerabilities&limit=3",
    "next": "https://socdefenders.ai/api/v1/articles?category=vulnerabilities&limit=3&cursor=eyJrIjoicHVibGlzaGVkX2F0..."
  }
}

Documentation Index

Fetch the complete documentation index at: https://docs.socdefenders.ai/llms.txt

Use this file to discover all available pages before exploring further.

Authorizations

X-API-Key
string
header
required

API key in X-API-Key header

Query Parameters

source
string

Comma-separated source names. Use exact names from /api/v1/sources (or the supported sources docs).

Example:

"BleepingComputer,Krebs on Security"

source_type
enum<string>

Filter by content origin: rss (automated feeds, 99% of corpus) or community (user-submitted).

Available options:
rss,
community
Example:

"rss"

source_tier
string

Comma-separated source curation tiers. 1 = best-in-class (Krebs, BleepingComputer); 2 = solid vendors (Talos, Mandiant); 3 = community/aggregator; 4 = experimental.

Example:

"1,2"

category
string

Comma-separated canonical category slugs. Available: attacks-breaches, vulnerabilities, threat-intel, malware, cloud-security, endpoint-security, network-security, identity-access, application-security, data-security, security-operations, incident-response, compliance, ai-ml-security, iot-ot.

Example:

"vulnerabilities,malware"

content_type
string

Filter by AI-classified content type. Default queries return all; pass explicit values to narrow.

Example:

"security,educational"

tech_tags
string

Any-match against the per-article tech_tags array (GIN-indexed). Common tags: aws, azure, kubernetes, docker, windows, linux, ios, android, openssh, nginx, apache.

Example:

"aws,kubernetes"

industry_tags
string

Any-match against the industry_tags array. Available: finance, healthcare, government, technology, manufacturing, retail, energy, education, telecom, transportation, defense, water, unclassified.

Example:

"finance,healthcare"

threat_actor
string

Any-match against the threat_actors array (lowercase canonical names). Examples: lazarus, apt28, apt29, lockbit, blackcat, clop.

Example:

"lazarus,apt28"

min_severity
number

Minimum severity_score. Articles below this score are excluded. Use 7+ for "actionable" and 9+ for "drop everything".

Required range: 0 <= x <= 10
Example:

8

severity
string

Severity-bucket filter. Mutually exclusive with min_severity (use one). Mapping: critical=9-10, high=7-8.9, medium=4-6.9, low=0.1-3.9.

Example:

"critical,high"

has_iocs
boolean

Restrict to articles with extracted IOCs (true) or without (false). Useful for SIEM-feed use cases that only care about indicator-bearing content.

Example:

true

CVE ID substring match against title + ai_summary. Note: a proper join via cve_article_mentions is not yet populated; matches today are full-text only and may include false positives (e.g. CVE-2024-1234 matches CVE-2024-12345). The legacy cve parameter remains as a deprecated alias and triggers Deprecation / Sunset response headers.

Pattern: CVE-\d{4}-\d{4,7}
Example:

"CVE-2024-12345"

mitre_technique
string

Single MITRE ATT&CK technique ID. Backed by a GIN index on the per-article ai_mitre_techniques jsonb column.

Pattern: T\d{4}(\.\d{3})?
Example:

"T1566"

has_ai_summary
boolean

Restrict to articles with an AI-generated extended summary. Most articles >24h old have one; use this to skip articles awaiting processing.

Example:

true

has_audio
boolean

Restrict to articles with audio narration (TTS). Useful for podcast/audio-content integrations.

Example:

true

is_archived
boolean
default:false

Include archived articles. Archived articles are kept for history but hidden from normal listings.

submission_type
enum<string>

Filter by how the article entered the platform. rss_auto = harvested from an RSS feed (~99% of corpus). user_submitted = posted by an authenticated community member.

Available options:
rss_auto,
user_submitted
Example:

"rss_auto"

q
string

Full-text search query. Min 2 chars after sanitization (alphanumerics, spaces, ., ,, - only). Must contain ≥1 alphabetic token of length 3+ — gibberish like ' OR 1=1 is rejected with q_invalid.

Example:

"ransomware"

q_field
enum<string>
default:default

Which field to search. default searches title+summary using the GIN index. ai_summary is ILIKE-only (no index — slower).

Available options:
default,
title,
summary,
ai_summary
Example:

"default"

time_field
enum<string>
default:published_at

Which time field since/until apply to. published_at (default) is the article's original publication time. modified_at is when SOC Defenders last updated the row (use for delta polling). fetched_at is when we first crawled it. created_at is the DB insert time.

Available options:
published_at,
fetched_at,
modified_at,
created_at
Example:

"modified_at"

since
string<date-time>

Lower time bound (ISO 8601). Silently clamped to tier earliest — check X-Tier-Lookback-Clamped header to detect.

Example:

"2026-05-10T00:00:00Z"

until
string<date-time>

Upper time bound (ISO 8601). Cannot be in the future.

Example:

"2026-05-17T00:00:00Z"

modified_since
string<date-time>

Convenience alias for time_field=modified_at&since=<value>. Use this for delta-polling SIEM/SOAR sync.

Example:

"2026-05-16T00:00:00Z"

limit
integer
default:50

Results per page. Out-of-range values are silently clamped to tier max (and X-Limit-Capped header is emitted).

Required range: x >= 1
Example:

100

offset
integer
default:0

Offset pagination. Rejected above 1000 — use cursor instead. Cursor is stable across vote/score updates; offset is not.

Required range: x >= 0
Example:

0

cursor
string

Opaque pagination cursor from links.next or the X-Next-Cursor header. Encodes {sort_key, timestamp, id}; if you change the sort between calls, the cursor is rejected with invalid_cursor.

Example:

"eyJrIjoicHVibGlzaGVkX2F0IiwidCI6IjIw..."

format
enum<string>
default:json

Response format. ndjson and csv require the read:articles:export scope (Pro tier).

Available options:
json,
ndjson,
csv
Example:

"ndjson"

fields
string

Comma-separated field allowlist for sparse responses. Maps to a minimal SQL SELECT list — saves DB I/O and response bytes. Unknown fields are silently dropped.

Example:

"id,title,url,published_at,severity_score"

expand
string

Comma-separated expansions to include. mitre is on by default (already-fetched, zero overhead). iocs, cves, threat_actors each add one batched query.

Example:

"iocs,cves,threat_actors"

sort
enum<string>
default:published:desc

Sort order. published:desc (default) is newest-first. engagement:desc ranks by rank_score (HN-style decay). severity:desc surfaces critical vulnerabilities first.

Available options:
published:desc,
published:asc,
modified:desc,
severity:desc,
engagement:desc
Example:

"severity:desc"

count_strategy
enum<string>
default:none

How meta.total is computed. Default is none so consumers do not accidentally ship the ~6%-drift planned estimate as if it were exact. Opt in to planned for a fast estimate or exact for a slow full count.

Available options:
none,
planned,
exact
Example:

"none"

Response

Successful response. See Article for the complete per-row shape and headers section for pagination/clamping signals.

meta
object
data
object[]