REST API

Every endpoint returns the same JSON shape across tiers. Fields your tier cannot see are replaced with upgrade_required and surfaced under _paywalled — no silent redactions, no missing keys.

Last updated · 2026-04-17

Quick start

Anonymous · 100/day, 7-day history, 1h delay
curl https://api.boarnet.local/api/threat/thr_demo01
Participant · 1,000/hr, real-time, full fidelity
curl -H "Authorization: Bearer snt_participant_demo_abc123" \
     https://api.boarnet.local/api/threat/thr_demo01

Authentication

Authenticated clients hit their tier's quota. Anonymous clients are keyed by source IP and share a single daily budget.

Header (preferred)
Authorization: Bearer snt_participant_demo_abc123
Query param (fallback for browser links)
GET /api/threat/thr_demo01?api_key=snt_participant_demo_abc123

Revoked keys return 401. Unknown keys fall through to the anonymous tier silently, so a forgotten key header doesn't break integrations catastrophically — just quietly downgrades them.

Response headers

Every response carries the client's current budget:

X-Tier: participant
X-Tier-Label: Participant
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1776484000   # unix seconds

When the budget is exhausted the next call returns 429 with a Retry-After header and a JSON body pointing to /pricing.

Redaction contract

Anonymous callers always get a useful payload: verdict, confidence, high-level tags, sighting totals. Fields your tier cannot see are explicitly marked:

anonymous response excerpt
{
  "id": "thr_demo01",
  "ip": "185.63.253.12",
  "confidence": 0.56,
  "tags": ["credential-stuffing", "ssh-bruteforce", "proxy-abuse"],
  "recommended_action": "drop",
  "sensor_sighting_summary": { "core_sightings": 4, "mesh_sightings": 0, "total_sensors": 4 },
  "data_freshness": "60m_delay",
  "history_window_days": 7,
  "_paywalled": {
    "ja3": "upgrade_required",
    "ja4": "upgrade_required",
    "sensor_sightings": "upgrade_required"
  },
  "_upgrade_url": "/pricing"
}

Endpoints

GET /api/threat/:id

Fetch a single record by record ID or IP address.

curl https://api.boarnet.local/api/threat/thr_demo01
curl https://api.boarnet.local/api/threat/185.63.253.12

Filter records by q (IP/ASN/country fragment) and tag. Result cap scales with tier.

curl "https://api.boarnet.local/api/search?tag=credential-stuffing"

GET /api/query

Run a DSL query. Same syntax as the Explore DSL editor and Alert Triggers.

curl "https://api.boarnet.local/api/query?dsl=tag%3Acredential-stuffing+AND+fleet%3Acore"

GET /api/events

Server-Sent Events stream of live attacks. Anonymous tier receives a reduced payload (JA4 hashes redacted).

curl -N https://api.boarnet.local/api/events

GET /api/export.csv

Export the current filter as CSV. Takes the same query params as /dashboard/explore. Row count caps by tier; anonymous exports redact fingerprint columns.

curl -o threats.csv \
  "https://api.boarnet.local/api/export.csv?tags=credential-stuffing"