Technical Writing Portfolio v1.0 · March 2026 · Shadow Sample

Threat Intelligence
API Reference

The Threat Intelligence API provides programmatic access to structured threat data, adversary profiles, and indicator of compromise enrichment. Security teams use this API to integrate real-time threat intelligence into SIEM platforms, automate alert enrichment, and accelerate incident response investigations.

IOC Enrichment Adversary Profiles MITRE ATT&CK Mapping SIEM Integration STIX 2.1 Export Bulk Lookup
Document Type: API Reference
Audience: Security Analysts · SOC Engineers · TI Practitioners
Frameworks: MITRE ATT&CK v18 · NIST SP 800-61r3 · RFC 7807
About This Document

This API reference is original technical writing produced as a portfolio sample demonstrating documentation structure, depth, and communication style consistent with Unit 42 External Engagement Team publications. All content is sourced from publicly available MITRE ATT&CK, NIST SP 800-61r3, and Unit 42 published research. No proprietary data is reproduced.

Endpoint Structure

https://api.threatintel.example.com/v1/{resource}

All requests must be made over HTTPS. Plain HTTP requests return 301 Moved Permanently. All endpoints return application/json by default. Pass Accept: application/stix+json to receive STIX 2.1 formatted output for downstream tool integration.

API Key Authentication

All API requests require a valid API key passed as a request header. Keys are scoped to a subscription tier and carry rate limits accordingly.

Required Header

X-API-Key: your_api_key_here

Obtaining an API Key

1. Log in to the Threat Intelligence Portal at portal.threatintel.example.com
2. Navigate to Settings → API Access
3. Select Generate New Key
4. Copy and securely store your key — it is displayed only once

⚠ Security Notice

Never embed API keys in client-side code, commit them to version control, or share them in plain text. Store keys in environment variables or a secrets manager such as AWS Secrets Manager or HashiCorp Vault.

Authentication Error Codes

HTTP StatusError CodeDescription
401AUTH_MISSINGNo API key provided in the request header
401AUTH_INVALIDAPI key is malformed or unrecognized
403AUTH_EXPIREDAPI key has expired — regenerate in the portal
403AUTH_INSUFFICIENTYour subscription tier lacks access to this endpoint

Request Limits by Tier

Requests are rate-limited per API key on a rolling 60-second window. When a limit is exceeded the API returns 429 Too Many Requests with the following response headers.

TierRequests / MinBulk IOCs / RequestDaily Quota
Free1010500
Standard6010010,000
Professional300500100,000
EnterpriseUnlimited1,000Unlimited

Rate Limit Response Headers

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711670400
Retry-After: 47
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the limit resets
Retry-AfterSeconds to wait before retrying

GET /indicators/{type}/{value}

GET /indicators/{type}/{value} Single IOC Lookup

Retrieve threat intelligence for a single indicator of compromise. Returns threat classification, severity rating, confidence score (0–100), associated malware families, linked threat actor profiles, and MITRE ATT&CK technique mappings. The confidence score is derived from telemetry volume, source reliability, and indicator age.

Path Parameters

ParameterTypeRequiredDescription
typestring Required Indicator type. Accepted values: ip · domain · url · hash · email
valuestring Required The indicator value to query (IP address, SHA256 hash, domain name, etc.)

Query Parameters

ParameterTypeRequiredDefaultDescription
include_contextboolean Optionalfalse When true, includes full threat actor profile and campaign context
formatstring Optionaljson Response format. Accepted values: json · stix2
Example Request
curl -X GET \
  "https://api.threatintel.example.com/v1/indicators/ip/198.51.100.42?include_context=true" \
  -H "X-API-Key: $API_KEY" \
  -H "Accept: application/json"
Response — 200 OK
{
  "status": "success",
  "indicator": {
    "type": "ip",
    "value": "198.51.100.42",
    "first_seen": "2025-11-03T08:14:22Z",
    "last_seen": "2026-03-15T17:42:09Z",
    "confidence": 94,
    "classification": "malicious",
    "severity": "critical",
    "threat_types": ["command-and-control", "data-exfiltration"],
    "associated_malware": ["POWERSTATS", "AshTag"],
    "attack_techniques": [
      {
        "technique_id": "T1071.001",
        "technique_name": "Application Layer Protocol: Web Protocols",
        "tactic": "Command and Control"
      },
      {
        "technique_id": "T1041",
        "technique_name": "Exfiltration Over C2 Channel",
        "tactic": "Exfiltration"
      }
    ],
    "context": {
      "threat_actor": "Boggy Serpens",
      "aliases": ["MuddyWater", "G0069", "TA450"],
      "campaign": "Operation Silent Harvest",
      "target_sectors": ["Government", "Defense", "Energy"],
      "target_regions": ["Middle East", "North Africa"],
      "actor_motivation": "Espionage"
    },
    "tags": ["apt", "nation-state", "c2", "persistent-threat"],
    "references": [
      "https://unit42.paloaltonetworks.com/boggy-serpens",
      "https://attack.mitre.org/techniques/T1071/001"
    ]
  },
  "meta": {
    "query_time_ms": 38,
    "api_version": "1.0",
    "timestamp": "2026-03-28T10:05:33Z"
  }
}
MITRE ATT&CK T1071.001 · T1041 · attack.mitre.org · Boggy Serpens / MuddyWater: MITRE ATT&CK G0069, updated October 2025 (v18) · Malpedia: malpedia.caad.fkie.fraunhofer.de/actor/muddywater

POST /indicators/bulk

POST /indicators/bulk Batch Enrichment — up to 500 IOCs

Submit up to 500 indicators in a single request for batch enrichment. Designed for high-volume SOC workflows and automated SIEM enrichment pipelines. Unknown indicators return classification: "unknown" and confidence: 0 rather than being omitted — ensuring your pipeline always receives a result for every submitted indicator and preventing silent failures in automated workflows.

Request Body

FieldTypeRequiredDescription
indicatorsarrayRequiredList of indicator objects. Maximum 500 per request.
indicators[].typestringRequiredIndicator type: ip · domain · url · hash · email
indicators[].valuestringRequiredThe indicator value to query
include_contextbooleanOptionalInclude full threat actor context for each matched result. Default: false
Example Request
curl -X POST \
  "https://api.threatintel.example.com/v1/indicators/bulk" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "indicators": [
      { "type": "ip",     "value": "198.51.100.42" },
      { "type": "domain", "value": "malicious-c2.example.net" },
      { "type": "hash",   "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }
    ],
    "include_context": false
  }'
Response — 200 OK
{
  "status": "success",
  "total_queried": 3,
  "total_matched": 2,
  "results": [
    { "type": "ip",     "value": "198.51.100.42",             "classification": "malicious", "severity": "critical",       "confidence": 94 },
    { "type": "domain", "value": "malicious-c2.example.net",    "classification": "malicious", "severity": "high",           "confidence": 87 },
    { "type": "hash",   "value": "e3b0c44298fc1c149afb...", "classification": "unknown",   "severity": "informational", "confidence": 0  }
  ],
  "meta": { "query_time_ms": 112, "api_version": "1.0", "timestamp": "2026-03-28T10:07:15Z" }
}

GET /actors/{actor_name}

GET /actors/{actor_name} Threat Actor Profile

Retrieve a detailed profile for a named threat actor or adversary group. Returns attributed campaigns, known tooling, targeted sectors and regions, and MITRE ATT&CK technique usage. Actor data is consistent with publicly documented MITRE ATT&CK Group profiles. Use underscores for multi-word names (e.g., boggy_serpens). Case-insensitive.

Example Request
curl -X GET \
  "https://api.threatintel.example.com/v1/actors/boggy_serpens" \
  -H "X-API-Key: $API_KEY"
Response — 200 OK
{
  "status": "success",
  "actor": {
    "name": "Boggy Serpens",
    "aliases": ["MuddyWater", "G0069", "TA450", "Mango Sandstorm", "MERCURY"],
    "origin": "Iran",
    "attribution": "Ministry of Intelligence and Security (MOIS)",
    "motivation": "Espionage",
    "active_since": "2017",
    "last_activity": "2026-03",
    "target_sectors": ["Government", "Defense", "Telecommunications", "Energy"],
    "target_regions": ["Middle East", "Europe", "North America"],
    "primary_tooling": ["POWERSTATS", "DCHSpy", "MoriAgent", "AshTag"],
    "techniques": [
      { "technique_id": "T1566.001", "technique_name": "Phishing: Spearphishing Attachment", "tactic": "Initial Access",  "frequency": "high"   },
      { "technique_id": "T1053.005", "technique_name": "Scheduled Task/Job",                 "tactic": "Persistence", "frequency": "high"   },
      { "technique_id": "T1059.001", "technique_name": "PowerShell",                          "tactic": "Execution",  "frequency": "medium" }
    ],
    "campaigns": [
      {
        "name": "Operation Silent Harvest",
        "period": "2025-Q3 to present",
        "description": "Cyberespionage campaign targeting Middle Eastern government entities using enhanced social engineering and the AshTag malware suite."
      }
    ],
    "references": [
      "https://unit42.paloaltonetworks.com/boggy-serpens",
      "https://attack.mitre.org/groups/G0069"
    ]
  }
}
MITRE ATT&CK G0069 · attack.mitre.org/groups/G0069 · Updated October 2025 (v18) · Lookout DCHSpy Report July 2025 · FBI/CISA/CNMF Iranian Cyber Operations Advisory, February 2022

GET /search

GET /search Full-text Intelligence Search

Full-text and filtered search across the threat intelligence database. Search by keyword, indicator type, threat actor name, MITRE ATT&CK technique ID, or date range. Returns paginated results sorted by relevance score descending.

ParameterTypeRequiredDefaultDescription
qstringRequiredSearch query: actor name, malware family, campaign name, or technique ID (e.g., T1566)
typestringOptionalallFilter by: indicator · actor · campaign · malware
classificationstringOptionalallFilter indicators by: malicious · suspicious · benign
sinceISO 8601OptionalReturns results observed on or after this date
untilISO 8601OptionalReturns results observed on or before this date
limitintegerOptional25Results to return. Maximum: 100
offsetintegerOptional0Pagination offset for large result sets
Example Request
curl -X GET \
  "https://api.threatintel.example.com/v1/search?q=ransomware&type=indicator&classification=malicious&since=2026-01-01&limit=10" \
  -H "X-API-Key: $API_KEY"

Core Response Fields

FieldTypeDescription
classificationstringOne of: malicious · suspicious · benign · unknown
severitystringOne of: informational · low · medium · high · critical
confidenceintegerScore 0–100 derived from telemetry volume, source reliability, and indicator age
first_seenISO 8601Timestamp of earliest observed activity in UTC
last_seenISO 8601Timestamp of most recent observed activity in UTC
threat_typesarrayActivity classifications: command-and-control · data-exfiltration · phishing · malware-distribution
attack_techniquesarrayMITRE ATT&CK technique objects with technique_id, technique_name, tactic, and optional frequency
associated_malwarearrayKnown malware family names linked to this indicator as documented in open threat research
contextobjectThreat actor attribution, campaign, target sectors and regions. Returned only when include_context=true
tagsarrayAnalyst-assigned classification tags for filtering and correlation
referencesarraySource URLs for further reading and attribution
meta.query_time_msintegerServer-side query duration in milliseconds
meta.timestampISO 8601Response generation time in UTC

HTTP Status Codes

All error responses follow a consistent structure per IETF RFC 7807 Problem Details, returning a JSON body with status, error.code, error.message, and optional error.details fields.

Error Response Structure
{
  "status": "error",
  "error": {
    "code":    "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded for your subscription tier.",
    "details": "Wait 47 seconds before retrying. Upgrade to Professional for higher limits."
  },
  "meta": { "api_version": "1.0", "timestamp": "2026-03-28T10:00:00Z" }
}
CodeMeaningCommon CauseRecommended Action
200OKRequest succeededProcess response normally
207Multi-StatusBulk request with partial resultsCheck per-item status fields in results array
400Bad RequestMissing required parameter or invalid valueCheck request format against this reference
401UnauthorizedMissing or invalid API keyVerify key is present and correctly formatted
403ForbiddenKey expired or insufficient subscription tierRegenerate key or upgrade subscription
404Not FoundIndicator or actor not in databaseTreat as unknown — log and continue
422UnprocessableBulk request exceeds 500 indicator limitSplit into smaller batches and retry
429Too Many RequestsRate limit exceededWait for Retry-After seconds before retrying
500Internal Server ErrorUnexpected server-side failureRetry with exponential backoff; report if persistent
503Service UnavailablePlanned maintenance or temporary overloadCheck status page; retry after delay
Error structure: IETF RFC 7807 Problem Details for HTTP APIs · tools.ietf.org/html/rfc7807

Python — Single IOC Lookup

import requests
import os

API_KEY  = os.environ.get("THREAT_INTEL_API_KEY")
BASE_URL = "https://api.threatintel.example.com/v1"


def get_indicator(indicator_type: str, value: str, include_context: bool = False) -> dict:
    """
    Query threat intelligence for a single indicator of compromise.

    Args:
        indicator_type: One of 'ip', 'domain', 'url', 'hash', 'email'
        value:          The indicator value to query
        include_context: When True, includes full threat actor profile and campaign data

    Returns:
        dict: API response containing threat intelligence enrichment data

    Raises:
        requests.HTTPError:  For 4xx / 5xx responses
        requests.Timeout:    If the request exceeds the timeout threshold
    """
    url     = f"{BASE_URL}/indicators/{indicator_type}/{value}"
    headers = {"X-API-Key": API_KEY}
    params  = {"include_context": str(include_context).lower()}

    response = requests.get(url, headers=headers, params=params, timeout=10)
    response.raise_for_status()
    return response.json()


# Example usage
result    = get_indicator("ip", "198.51.100.42", include_context=True)
indicator = result["indicator"]

print(f"Classification : {indicator['classification']}")
print(f"Severity       : {indicator['severity']}")
print(f"Confidence     : {indicator['confidence']}%")
print(f"Threat Actor   : {indicator['context']['threat_actor']}")

Python — Bulk Lookup with Retry Logic

import time


def bulk_lookup(indicators: list[dict], max_retries: int = 3) -> dict:
    """
    Submit multiple indicators for batch enrichment with automatic retry.

    Args:
        indicators:  List of dicts, each with 'type' and 'value' keys.
                     Maximum 500 indicators per request.
        max_retries: Number of retry attempts on 429 or 5xx responses.

    Returns:
        dict: API response with enrichment results for every submitted indicator.
              Unknown indicators return classification 'unknown' — never omitted.

    Raises:
        ValueError:          If more than 500 indicators are submitted
        requests.HTTPError:  For unrecoverable 4xx errors
        RuntimeError:        If all retry attempts are exhausted

    Example:
        indicators = [
            {"type": "ip",     "value": "198.51.100.42"},
            {"type": "domain", "value": "malicious-c2.example.net"},
            {"type": "hash",   "value": "e3b0c44298fc1c149afb..."}
        ]
    """
    if len(indicators) > 500:
        raise ValueError("Bulk endpoint accepts a maximum of 500 indicators per request.")

    url     = f"{BASE_URL}/indicators/bulk"
    headers = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
    payload = {"indicators": indicators}

    for attempt in range(max_retries):
        try:
            response = requests.post(url, headers=headers, json=payload, timeout=30)

            if response.status_code == 429:
                wait = int(response.headers.get("Retry-After", 60))
                print(f"Rate limited. Retrying in {wait} seconds...")
                time.sleep(wait)
                continue

            response.raise_for_status()
            return response.json()

        except requests.exceptions.Timeout:
            wait = 2 ** attempt  # Exponential backoff: 1s, 2s, 4s
            print(f"Request timed out. Retrying in {wait}s... (attempt {attempt + 1}/{max_retries})")
            time.sleep(wait)

        except requests.exceptions.HTTPError as e:
            if e.response.status_code >= 500:
                wait = 2 ** attempt
                print(f"Server error {e.response.status_code}. Retrying in {wait}s...")
                time.sleep(wait)
                continue
            raise  # Do not retry 4xx errors other than 429

    raise RuntimeError(f"Request failed after {max_retries} attempts.")

SIEM Enrichment Workflow

The following five-step pipeline describes how to use this API to automatically enrich SIEM alerts with threat intelligence context during incident triage. Structured around NIST SP 800-61r3 incident response lifecycle guidance and MITRE ATT&CK v18 tactic-based detection conventions.

The 2026 Unit 42 Global Incident Response Report documents that attackers move from initial access to data exfiltration in under one hour in the fastest observed incidents — a 4x speed increase over prior years. Identity-based techniques drove initial access in 65% of investigated incidents. This pipeline is designed for the speed and triage discipline that threat environment demands.

StepActionTool / MethodATT&CK AlignmentOutput
01 Extract IOCs from Alert
Parse incoming SIEM alerts for IPs, domains, hashes, and URLs. Normalize formats before querying — strip port numbers from IPs, lowercase domain values.
SIEM parsing rules
Cortex XSOAR automation
All tactics — pre-enrichment Normalized IOC list
02 Bulk IOC Lookup
Submit all IOCs from a single alert in one request. Batching minimizes API latency and preserves rate limit quota.
POST /indicators/bulk T1071 · T1041 · T1566 Enriched IOC records
03 Apply Confidence Threshold
Filter results by confidence score. A threshold of 75+ is recommended for automated escalation to reduce false positive alert fatigue.
Threshold table (below)
SOAR decision logic
All — reduces false positives Prioritized alert queue
04 Map to MITRE ATT&CK
Tag the SIEM alert with ATT&CK tactic and technique IDs from the attack_techniques array. Enables automated correlation across alerts sharing adversary behavior patterns.
attack_techniques array
ATT&CK Navigator overlay
Tactic-based detection
MITRE v18, Oct 2025
Tagged, correlated alert
05 Update Case & Notify
Write enriched context back to the SIEM case. If severity is critical or high and confidence is 85+, trigger an automated analyst notification immediately.
SIEM case management
Cortex XSIAM · Splunk
Responds to all phases Enriched case record

Confidence Threshold Reference

Confidence RangeClassificationRecommended Action
90 – 100 High confidence — malicious Auto-escalate to analyst. Block at perimeter if policy permits.
75 – 89 Likely malicious Flag for priority analyst review within 30 minutes.
50 – 74 Suspicious — low confidence Log and monitor. Include in threat hunting queue.
0 – 49 Unknown or benign Log only. Do not auto-escalate. Revisit if correlated with other signals.
Sources: NIST SP 800-61r3 Computer Security Incident Handling Guide · MITRE ATT&CK v18 Enterprise Matrix, October 2025 · Unit 42 2026 Global Incident Response Report (unit42.paloaltonetworks.com) · Cortex XSOAR Unit 42 Integration Pack v1.0.15, March 2026

Changelog

v1.0
March 2026
Initial release. Endpoints: single IOC lookup, bulk IOC enrichment, threat actor profiles, full-text search. Authentication, rate limiting by tier, Python examples with docstrings and retry logic, SIEM enrichment pipeline, confidence threshold reference, and full HTTP error reference.

Citations & References

All technical content is sourced from publicly available research. No proprietary Palo Alto Networks data is reproduced.

SourceReference
MITRE ATT&CK v18Enterprise Matrix, October 2025 · attack.mitre.org
MITRE ATT&CK G0069MuddyWater / Boggy Serpens Group Profile · attack.mitre.org/groups/G0069
NIST SP 800-61r3Computer Security Incident Handling Guide · csrc.nist.gov
IETF RFC 7807Problem Details for HTTP APIs · tools.ietf.org/html/rfc7807
Unit 42 2026 IR ReportGlobal Incident Response Report · unit42.paloaltonetworks.com
Cortex XSOAR MarketplaceUnit 42 Threat Intelligence Integration Pack v1.0.15, March 2026 · cortex.marketplace.pan.dev
MalpediaMuddyWater Actor Profile · malpedia.caad.fkie.fraunhofer.de/actor/muddywater
Lookout SecurityDCHSpy — Iranian APT MuddyWater, July 2025
FBI / CISA / CNMFIranian Government-Sponsored Cyber Operations Advisory, February 2022