Documentation

Reference guides and examples for integrating with iocget

Authentication

Authenticated endpoints use API tokens for programmatic access. Most read endpoints are public and require no authentication.

API Tokens

Create a personal API token from Settings. Tokens are prefixed with ioc_ and are shown only once on creation.

Include your token as a Bearer token in the Authorization header:

import requests

API_BASE = "https://iocget.com/api"
API_TOKEN = "ioc_your_token_here"

headers = {
    "Authorization": f"Bearer {API_TOKEN}"
}

response = requests.get(f"{API_BASE}/auth/me", headers=headers)
print(response.json())

Submissions

Submissions represent documents or URLs submitted for IOC extraction. Requires authentication to create; read endpoints are public.

POST /api/submissions/file Auth required

Upload a file for IOC extraction. Supported types: PDF, TXT, HTML, DOCX, XLSX, PPTX, CSV, JSON, XML, and more. Max 10 MB.

FieldTypeDescription
filemultipart/form-dataThe file to extract IOCs from
import requests

headers = {"Authorization": "Bearer ioc_your_token_here"}

with open("threat_report.pdf", "rb") as f:
    response = requests.post(
        "https://iocget.com/api/submissions/file",
        headers=headers,
        files={"file": ("threat_report.pdf", f, "application/pdf")}
    )

submission = response.json()
print(f"Submission ID: {submission['id']}, Status: {submission['status']}")

Response

{
  "id": "sub_abc123",
  "status": "pending",
  "source_type": "file_upload",
  "original_filename": "threat_report.pdf",
  "created_at": "2024-01-15T14:30:00Z"
}
Note: Submissions are processed asynchronously. Poll GET /api/submissions/{id} until status is completed or failed. If the file was already submitted, the response includes "duplicate": true with the existing submission ID.
POST /api/submissions/url Auth required

Submit a URL for IOC extraction. The content is fetched and analyzed automatically.

FieldTypeDescription
urlstringThe URL to fetch and extract IOCs from
import requests
import time

headers = {
    "Authorization": "Bearer ioc_your_token_here",
    "Content-Type": "application/json"
}

# Submit URL
response = requests.post(
    "https://iocget.com/api/submissions/url",
    headers=headers,
    json={"url": "https://example.com/threat-report"}
)
submission = response.json()
submission_id = submission["id"]

# Poll for completion
while True:
    result = requests.get(
        f"https://iocget.com/api/submissions/{submission_id}",
        headers=headers
    ).json()

    if result["status"] in ("completed", "failed"):
        break
    time.sleep(5)

print(f"Found {result['ioc_count']} IOCs")
GET /api/submissions Public

List recent submissions, ordered by creation date descending. Supports incremental sync via the since parameter.

ParameterTypeDefaultDescription
limitinteger50Number of results (max 100)
offsetinteger0Pagination offset
sincestringISO 8601 UTC timestamp. When provided, returns only submissions created after this time, ordered oldest-first. Use this for incremental sync.
import requests

response = requests.get(
    "https://iocget.com/api/submissions",
    params={"limit": 20, "offset": 0}
)
submissions = response.json()

for sub in submissions:
    print(f"{sub['id']}: {sub['title'] or sub['source_identifier']} ({sub['ioc_count']} IOCs)")

Incremental Sync

Use the since parameter to maintain a local mirror of all submissions without re-fetching the entire table on each run. When since is provided, the endpoint filters on updated_at and returns results oldest-first, so you capture both new submissions and changes to existing ones (status transitions, admin edits, etc.). Store the updated_at of the last record you received and pass it as since on the next call.

import requests

API_BASE = "https://iocget.com/api"

def sync_submissions(cursor: str | None = None) -> tuple[list, str | None]:
    """Fetch submissions updated after `cursor`. Returns (submissions, next_cursor)."""
    params = {"limit": 100}
    if cursor:
        params["since"] = cursor

    response = requests.get(f"{API_BASE}/submissions", params=params)
    response.raise_for_status()
    submissions = response.json()

    next_cursor = submissions[-1]["updated_at"] if submissions else cursor
    return submissions, next_cursor

# Initial full sync
all_submissions = []
cursor = None
while True:
    batch, cursor = sync_submissions(cursor)
    if not batch:
        break
    all_submissions.extend(batch)
    if len(batch) < 100:
        break  # No more pages

# Later: incremental sync — pick up new and updated submissions
new_batch, cursor = sync_submissions(cursor)
print(f"Found {len(new_batch)} new/updated submissions")

For filtered search, use GET /api/submissions/search with optional q, status, and source_type query parameters.

GET /api/submissions/{submission_id} Public

Get full details for a submission, including all extracted IOCs.

import requests

submission_id = "sub_abc123"
response = requests.get(f"https://iocget.com/api/submissions/{submission_id}")
data = response.json()

print(f"Title: {data['title']}")
print(f"Status: {data['status']}")
print(f"IOC count: {data['ioc_count']}")

for ioc in data["iocs"]:
    print(f"  [{ioc['ioc_type']['name']}] {ioc['value']}")

Response

{
  "id": "sub_abc123",
  "title": "Threat Report Q1 2024",
  "summary": "Analysis of APT29 campaign targeting...",
  "status": "completed",
  "source_type": "file_upload",
  "original_filename": "threat_report.pdf",
  "ioc_count": 42,
  "iocs": [
    {
      "id": "ioc_xyz789",
      "value": "192.0.2.1",
      "refanged_value": "192[.]0[.]2[.]1",
      "ioc_type": { "name": "ipv4" },
      "context": "C2 server observed in network logs",
      "description": "C2 server",
      "created_at": "2024-01-15T14:30:00Z"
    }
  ],
  "created_at": "2024-01-15T14:28:00Z",
  "processed_at": "2024-01-15T14:30:00Z"
}
GET /api/submissions/{submission_id}/export Public

Export a completed submission in various formats.

ParameterValuesDescription
formatjson, csv, stix, ecs, mispExport format (default: json)
import requests

submission_id = "sub_abc123"

# Export as STIX 2.1
response = requests.get(
    f"https://iocget.com/api/submissions/{submission_id}/export",
    params={"format": "stix"}
)

with open("report.stix.json", "wb") as f:
    f.write(response.content)

# Export as CSV
response = requests.get(
    f"https://iocget.com/api/submissions/{submission_id}/export",
    params={"format": "csv"}
)
print(response.text)

IOCs

IOCs are deduplicated by value and type across all submissions. A single IOC can appear in multiple reports.

Supported IOC Types

ipv4 ipv6 domain url hash_md5 hash_sha1 hash_sha256 hash_sha512 email cve filename command filepath asn ip_range ip_port registry_key
GET /api/iocs/search Public

Search across all IOCs with optional filtering by value or type.

ParameterTypeDefaultDescription
qstringSearch query (partial match on value)
typestringFilter by IOC type (e.g. ipv4, domain)
limitinteger50Number of results (max 100)
offsetinteger0Pagination offset
import requests

# Search for all IPv4 IOCs
response = requests.get(
    "https://iocget.com/api/iocs/search",
    params={"type": "ipv4", "limit": 100}
)
data = response.json()
print(f"Found {data['total']} IPv4 IOCs")

# Search by value
response = requests.get(
    "https://iocget.com/api/iocs/search",
    params={"q": "192.168", "type": "ipv4"}
)
for ioc in response.json()["iocs"]:
    print(f"{ioc['value']} — seen in {ioc['submission_count']} reports")

Response

{
  "total": 1240,
  "limit": 50,
  "offset": 0,
  "iocs": [
    {
      "id": "ioc_xyz789",
      "value": "malicious-domain.example.com",
      "refanged_value": "malicious-domain[.]example[.]com",
      "type": "domain",
      "context": "Observed in phishing campaign targeting...",
      "submission_id": "sub_abc123",
      "submission_count": 3,
      "created_at": "2024-01-15T14:30:00Z"
    }
  ]
}
GET /api/iocs/{ioc_id} Public

Get full details for a specific IOC, including all submissions where it appears.

import requests

ioc_id = "ioc_xyz789"
response = requests.get(f"https://iocget.com/api/iocs/{ioc_id}")
ioc = response.json()

print(f"Value: {ioc['value']}")
print(f"Type: {ioc['ioc_type']['name']}")
print(f"First seen: {ioc['first_seen_at']}")
print(f"Seen in {ioc['submission_count']} reports:")
for sub in ioc["submissions"]:
    print(f"  - {sub['title'] or sub['source_identifier']}")
GET /api/iocs/stats Public

Get aggregate statistics: total IOC and submission counts, broken down by IOC type.

import requests

response = requests.get("https://iocget.com/api/iocs/stats")
stats = response.json()

print(f"Total IOCs: {stats['total_iocs']}")
print(f"Total reports: {stats['total_submissions']}")
print("\nBreakdown by type:")
for ioc_type, count in sorted(stats["iocs_by_type"].items(), key=lambda x: -x[1]):
    print(f"  {ioc_type}: {count}")

Response

{
  "total_iocs": 15820,
  "total_submissions": 342,
  "iocs_by_type": {
    "ipv4": 4210,
    "domain": 3890,
    "hash_sha256": 2540,
    "url": 1980,
    "hash_md5": 1430,
    ...
  }
}