> ## 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.

# Retrieve a single article with full expansions

> Fetches one article by UUID with **all expansions enabled by default** (`iocs`, `cves`, `threat_actors`, `mitre`). Use `?expand=mitre` to opt out of the heavy expansions if you just need the article body.

## Common use cases

### 1. Article detail page (web UI)
Fetch everything in one request:
```
GET /api/v1/articles/e90ea8b7-8500-4a14-875c-1d64755c80ca
```

### 2. IOC enrichment workflow
Click-through from an IOC search to the source article's full context:
```
GET /api/v1/articles/{id}?expand=iocs,threat_actors
```

### 3. Minimal lookup (just the body)
```
GET /api/v1/articles/{id}?expand=mitre&fields=id,title,url,ai_summary,severity_score
```

## Errors

| Status | Code | Meaning |
|--------|------|---------|
| 400 | `invalid_parameter` | id is not a valid UUID |
| 403 | `lookback_exceeded` | Article exists but published before your tier's lookback window |
| 404 | `article_not_found` | No article with that UUID |
| 410 | `article_archived` | Article was archived. Pass `?include_archived=true` to retrieve it anyway |

Responses are cached for 60 seconds (`Cache-Control: public, s-maxage=60, stale-while-revalidate=120`).



## OpenAPI

````yaml https://socdefenders.ai/api/openapi.json get /api/v1/articles/{id}
openapi: 3.0.3
info:
  title: SOC Defenders Threat Intelligence API
  description: >-
    # Overview


    The SOC Defenders Threat Intelligence API provides programmatic access to
    aggregated threat intelligence from 30+ cybersecurity sources. Export IOCs
    (Indicators of Compromise) in various formats including JSON, CSV, STIX 2.1,
    MISP, CEF, and OpenIOC.


    ## Authentication


    All API endpoints require authentication using an API key. Include your key
    in one of these ways:


    - **Authorization Header** (recommended): `Authorization: Bearer
    sk_live_xxx`

    - **X-API-Key Header**: `X-API-Key: sk_live_xxx`

    - **Query Parameter**: `?api_key=sk_live_xxx`


    ## Rate Limiting


    Rate limits vary by tier. When limits are exceeded, the API returns a 429
    status code.


    | Tier | Requests/min | Requests/day | Lookback | Formats |

    |------|-------------|--------------|----------|---------|

    | Free | 10 | 1,000 | 1 day | JSON / CSV |

    | Pro ($299/mo) | 1,000 | 1,000,000 | 365 days | All (STIX, TAXII, MISP,
    CEF, OpenIOC, Sigma) |


    Rate limit headers are included in all responses:

    - `X-RateLimit-Limit`: Maximum requests per minute

    - `X-RateLimit-Remaining`: Requests remaining in current window

    - `X-RateLimit-Reset`: Unix timestamp when the limit resets


    ## Error Handling


    All errors follow a consistent format:


    ```json

    {
      "error": {
        "code": "error_code",
        "message": "Human readable message",
        "details": {},
        "request_id": "req_abc123"
      }
    }

    ```


    ## STIX/TAXII Support


    For STIX 2.1 and TAXII 2.1 integration, see the TAXII endpoints section.
    TAXII endpoints are available at `/api/taxii2/`.
  version: 1.0.0
  contact:
    name: SOC Defenders Support
    url: https://socdefenders.ai/contact
    email: support@socdefenders.ai
  license:
    name: Proprietary
    url: https://socdefenders.ai/terms
servers:
  - url: https://socdefenders.ai
    description: Production server
security: []
tags:
  - name: IOCs
    description: Indicators of Compromise endpoints
  - name: Statistics
    description: Feed and IOC statistics
  - name: API Keys
    description: API key management (requires session auth)
  - name: TAXII
    description: TAXII 2.1 threat intelligence sharing endpoints
  - name: Export Formats
    description: Specialized export format endpoints (MISP, CEF, OpenIOC)
  - name: Articles
    description: >-
      Aggregated news articles from 30+ cybersecurity sources, with rich
      filtering and bulk-export support
  - name: Lookup
    description: >-
      Single-IOC enrichment lookup. Auto-detects type, aggregates reporting
      sources, returns AI risk + MITRE techniques + hunting queries. Free-tier
      friendly.
  - name: Detection Rules
    description: >-
      Generate ready-to-deploy SIEM detection rules from recent IOCs. Sigma
      rules ship as multi-document YAML covering network / DNS / proxy /
      process_creation logsources.
paths:
  /api/v1/articles/{id}:
    get:
      tags:
        - Articles
      summary: Retrieve a single article with full expansions
      description: >-
        Fetches one article by UUID with **all expansions enabled by default**
        (`iocs`, `cves`, `threat_actors`, `mitre`). Use `?expand=mitre` to opt
        out of the heavy expansions if you just need the article body.


        ## Common use cases


        ### 1. Article detail page (web UI)

        Fetch everything in one request:

        ```

        GET /api/v1/articles/e90ea8b7-8500-4a14-875c-1d64755c80ca

        ```


        ### 2. IOC enrichment workflow

        Click-through from an IOC search to the source article's full context:

        ```

        GET /api/v1/articles/{id}?expand=iocs,threat_actors

        ```


        ### 3. Minimal lookup (just the body)

        ```

        GET
        /api/v1/articles/{id}?expand=mitre&fields=id,title,url,ai_summary,severity_score

        ```


        ## Errors


        | Status | Code | Meaning |

        |--------|------|---------|

        | 400 | `invalid_parameter` | id is not a valid UUID |

        | 403 | `lookback_exceeded` | Article exists but published before your
        tier's lookback window |

        | 404 | `article_not_found` | No article with that UUID |

        | 410 | `article_archived` | Article was archived. Pass
        `?include_archived=true` to retrieve it anyway |


        Responses are cached for 60 seconds (`Cache-Control: public,
        s-maxage=60, stale-while-revalidate=120`).
      operationId: getArticle
      parameters:
        - name: id
          in: path
          required: true
          description: Article UUID (from a previous list response)
          schema:
            type: string
            format: uuid
            example: e90ea8b7-8500-4a14-875c-1d64755c80ca
        - name: expand
          in: query
          description: >-
            Comma-separated expansions. Defaults to all four
            (`mitre,iocs,cves,threat_actors`) since callers fetching one article
            usually want the full picture.
          schema:
            type: string
            example: iocs,cves
        - name: fields
          in: query
          description: Comma-separated field allowlist for sparse response.
          schema:
            type: string
            example: id,title,severity_score
        - name: include_archived
          in: query
          description: >-
            Return the article even if it has been archived. Default `false`
            returns `410 article_archived`.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Article found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArticleSingleResponse'
              example:
                meta:
                  generated_at: '2026-05-17T10:30:00Z'
                  feed_version: '1.0'
                  source: SOC Defenders
                data:
                  id: c59a6bb4-f69a-4b90-babe-ca1afcda3514
                  title: >-
                    Cryptomixer crypto laundering service taken down by law
                    enforcement
                  url: >-
                    https://www.bleepingcomputer.com/news/security/cryptomixer-takedown/
                  canonical_url: >-
                    https://socdefenders.ai/item/c59a6bb4-f69a-4b90-babe-ca1afcda3514
                  summary: International law enforcement seized cryptomixer.io...
                  ai_summary: >-
                    Joint operation by Europol, FBI, and German federal police
                    seized the cryptomixer.io domain and arrested two operators.
                    The service had laundered approximately $5.4 billion in
                    cryptocurrency since 2018.
                  image_url: null
                  published_at: '2025-12-01T12:37:52Z'
                  fetched_at: '2025-12-01T12:40:15Z'
                  modified_at: '2025-12-01T13:00:00Z'
                  source_name: BleepingComputer
                  source_type: rss
                  source_tier: 1
                  category: attacks-breaches
                  category_label: Attacks & Breaches
                  category_legacy: Cybercrime
                  content_type: security
                  severity_score: 6.5
                  severity_label: medium
                  categorized_by: ai
                  categorized_at: '2025-12-01T12:42:00Z'
                  ai_classification: law-enforcement-action
                  ai_classification_confidence: 0.91
                  tech_tags:
                    - cryptocurrency
                    - tor
                  industry_tags:
                    - finance
                  threat_actors: []
                  has_iocs: true
                  ioc_count: 1
                  score: 12
                  upvotes: 14
                  downvotes: 2
                  comment_count: 5
                  vouch_count: 3
                  rank_score: 23.4
                  submission_type: rss_auto
                  submitted_by_username: null
                  audio_url: null
                  audio_duration_seconds: null
                  audio_voice: null
                  mitre_techniques:
                    - id: T1657
                      name: Financial Theft
                      tactic: impact
                      confidence: high
                  cve_ids: []
                  iocs:
                    - id: 6fc99fbc-2c24-4ce2-8b42-48065d4976e7
                      type: domain
                      value: cryptomixer.io
                      confidence: high
                      first_seen: '2025-12-01T21:21:20Z'
                  iocs_truncated: false
                  cves: []
                  threat_actors_detail: []
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '410':
          description: Article has been archived
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: article_archived
                  message: >-
                    This article has been archived. Pass ?include_archived=true
                    to retrieve it anyway.
                  request_id: req_abc123
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
      x-codeSamples:
        - lang: cURL
          label: Full article + expansions
          source: |-
            curl -H "Authorization: Bearer sk_live_..." \
              "https://socdefenders.ai/api/v1/articles/e90ea8b7-8500-4a14-875c-1d64755c80ca"
        - lang: cURL
          label: Minimal lookup
          source: |-
            curl -H "Authorization: Bearer sk_live_..." \
              "https://socdefenders.ai/api/v1/articles/e90ea8b7-8500-4a14-875c-1d64755c80ca?expand=mitre&fields=id,title,url,severity_score"
components:
  schemas:
    ArticleSingleResponse:
      type: object
      properties:
        meta:
          type: object
          properties:
            generated_at:
              type: string
              format: date-time
            feed_version:
              type: string
            source:
              type: string
        data:
          $ref: '#/components/schemas/Article'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              description: Error code for programmatic handling
            message:
              type: string
              description: Human-readable error message
            details:
              type: object
              description: Additional error details
            request_id:
              type: string
              description: Unique request identifier for support
    Article:
      type: object
      description: >-
        A single news article — flat shape. Every field is top-level (no nested
        source.name etc.).
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        url:
          type: string
          format: uri
          description: Original source URL
        canonical_url:
          type: string
          format: uri
        summary:
          type: string
          nullable: true
        ai_summary:
          type: string
          nullable: true
        image_url:
          type: string
          format: uri
          nullable: true
        published_at:
          type: string
          format: date-time
        fetched_at:
          type: string
          format: date-time
          nullable: true
        modified_at:
          type: string
          format: date-time
          nullable: true
        source_name:
          type: string
        source_type:
          type: string
          enum:
            - rss
            - community
        source_tier:
          type: integer
          nullable: true
          minimum: 1
          maximum: 4
        category:
          type: string
          nullable: true
          description: Canonical category slug
        category_label:
          type: string
          nullable: true
        category_legacy:
          type: string
          nullable: true
        content_type:
          type: string
          nullable: true
          enum:
            - security
            - educational
            - marketing
            - other
        severity_score:
          type: number
          nullable: true
          minimum: 0
          maximum: 10
        severity_label:
          type: string
          nullable: true
          enum:
            - critical
            - high
            - medium
            - low
        categorized_by:
          type: string
          nullable: true
          enum:
            - ai
            - manual
            - rule-based
        categorized_at:
          type: string
          format: date-time
          nullable: true
        ai_classification:
          type: string
          nullable: true
        ai_classification_confidence:
          type: number
          nullable: true
          minimum: 0
          maximum: 1
        tech_tags:
          type: array
          items:
            type: string
        industry_tags:
          type: array
          items:
            type: string
        threat_actors:
          type: array
          items:
            type: string
          description: String names; resolve via expand=threat_actors
        has_iocs:
          type: boolean
        ioc_count:
          type: integer
          minimum: 0
        score:
          type: integer
        upvotes:
          type: integer
        downvotes:
          type: integer
        comment_count:
          type: integer
        vouch_count:
          type: integer
        rank_score:
          type: number
        submission_type:
          type: string
          nullable: true
          enum:
            - rss_auto
            - user_submitted
        submitted_by_username:
          type: string
          nullable: true
        audio_url:
          type: string
          format: uri
          nullable: true
        audio_duration_seconds:
          type: integer
          nullable: true
        audio_voice:
          type: string
          nullable: true
        mitre_techniques:
          type: array
          description: Present when expand=mitre (default for /articles)
          items:
            type: object
            properties:
              id:
                type: string
              name:
                type: string
              tactic:
                type: string
              confidence:
                type: string
                enum:
                  - high
                  - medium
                  - low
        cve_ids:
          type: array
          items:
            type: string
          description: Present when expand=cves
        iocs:
          type: array
          description: Present when expand=iocs. Max 25 per article — check iocs_truncated.
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              type:
                type: string
              value:
                type: string
              confidence:
                type: string
                enum:
                  - high
                  - medium
                  - low
              first_seen:
                type: string
                format: date-time
        iocs_truncated:
          type: boolean
          description: True if iocs[] is a capped subset of ioc_count
        cves:
          type: array
          description: Present when expand=cves
          items:
            type: object
            properties:
              cve_id:
                type: string
              cvss_score:
                type: number
                nullable: true
              severity:
                type: string
                nullable: true
        threat_actors_detail:
          type: array
          description: Present when expand=threat_actors
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              name:
                type: string
              aliases:
                type: array
                items:
                  type: string
              actor_type:
                type: string
                nullable: true
              confidence:
                type: number
                nullable: true
  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_parameter
              message: 'Invalid IOC type: invalid'
              details:
                valid_types:
                  - ipv4
                  - ipv6
                  - domain
                  - url
                  - md5
                  - sha1
                  - sha256
              request_id: req_abc123
    Unauthorized:
      description: Authentication required or invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: missing_api_key
              message: >-
                API key is required. Include it in the Authorization header as
                "Bearer sk_live_..."
              request_id: req_abc123
    Forbidden:
      description: Insufficient permissions or scope
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: insufficient_scope
              message: This endpoint requires the "read:stix" scope
              details:
                required_scope: read:stix
                your_scopes:
                  - read:iocs
                upgrade_url: https://socdefenders.ai/export#pricing
              request_id: req_abc123
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: not_found
              message: The requested resource was not found
              request_id: req_abc123
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: internal_error
              message: An internal error occurred. Please try again later.
              request_id: req_abc123
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key in X-API-Key header
    BearerAuth:
      type: http
      scheme: bearer
      description: 'API key in Authorization header: `Authorization: Bearer sk_live_xxx`'

````