API documentation
The same intelligence the web interface shows - lookups, search,
and live SSVC decisions - served as a JSON API. No private, richer endpoint behind the curtain. Base
URL: https://api.harpia.ae/api/v1. All responses are JSON, UTF-8.
Machine-readable OpenAPI 3.1 spec - load it into Swagger UI,
Postman, or openapi-generator to scaffold a client.
On this page: Quickstart · Authentication · Limits explained · Endpoints · Query language · Decisions · Use cases · Errors · Plans · FAQ
Want to evaluate first? The homepage search is the API with a face - no account needed. For programmatic access, three steps:
- Create a free account - email and a password, no card.
- Mint an API key on your account page.
- Send it as a Bearer token on every request.
export HARPIA_KEY="hpk_…"
# Is this CVE exploited?
curl -s -H "Authorization: Bearer $HARPIA_KEY" \
"https://api.harpia.ae/api/v1/vulnerabilities/CVE-2024-3400" | jq '.x_intel_priority.exploit_maturity'
# Search the feed
curl -s -H "Authorization: Bearer $HARPIA_KEY" \
"https://api.harpia.ae/api/v1/vulnerabilities/search?term=product:openssl+version:%3C3.0" | jq '.total'
# What should MY team do about it? (live SSVC decision)
curl -s -H "Authorization: Bearer $HARPIA_KEY" \
"https://api.harpia.ae/api/v1/vulnerabilities/CVE-2024-3400/decision?exposure=exposed&mission_consequence=critical" \
| jq '.x_intel_priority.decision'
# → "immediate"
API keys
Keys are minted and revoked on your account page (browser session only - a key can never mint another key). Send the key on every request:
Authorization: Bearer hpk_…
Key mechanics worth knowing:
- A key inherits its owner's plan live. Upgrade your plan and every key you hold gets the new limits on its very next request - no re-issue needed.
- Keys expire. You choose a lifetime (up to 365 days) at mint time. Expired or
revoked keys return
401. - Revocation is immediate. Deleting a key kills it on the next request.
- Key count is capped per plan (see plans). Rotate by minting the replacement first, switching your integration, then revoking the old key - zero downtime.
Anonymous access
Without a token you can browse the web app freely - search and CVE pages work signed out, showing the exploitation basics: the maturity ladder, CISA KEV, CVSS, severity, CWE, EPSS, the exploit-evidence count, fix status, and malicious-package flags. The remaining first-party momentum and plan feeds are quota-free.
Direct anonymous API calls are not supported: requests that don't come from the web
app receive 401 with a pointer here. A free account gets
you an API key, higher limits, proprietary scoring (trending and risk), the SSVC
automatability input, and the live SSVC decision per CVE. Threat attribution, references,
exploit repositories, bulk and delta-sync are Pro and up; the raw TAXII feed is
Enterprise-only.
Your account carries two separate budgets: one for browsing this site, one shared by all of your API keys. They never draw from each other, so reading the site all day cannot exhaust the allowance your integration runs on. The browsing budget is deliberately generous; the API budget is the one sized to your plan.
Six independent mechanisms apply. Knowing which one you hit tells you exactly what to change:
| Mechanism | What it does | How you see it |
|---|---|---|
| Rate limit | Token bucket, a steady per-minute rate plus a burst allowance for short spikes. Your API keys and your web session have separate buckets. | 429 + Retry-After header (seconds). Body names the budget: {"error":"rate limit exceeded (30 requests/minute) …","scope":"api_key","tier":"free"} |
| Daily cap | Total requests per budget per calendar day, resetting at midnight UTC. Again two of them: browsing this site never spends your API-key allowance. | 429 + Retry-After to the reset. Body: {"error":"daily API request limit reached (500 requests) …","scope":"api_key","daily_limit":500,"resets_at":"…"} |
| Quota headers | Every metered response advertises what is left, so you can pace instead of discovering the ceiling by hitting it. | X-Tier, X-Quota-Scope, X-RateLimit-Limit, X-Daily-Limit, X-Daily-Remaining. |
| Page clamps | Search page and limit are silently clamped to your plan's maximum - the request succeeds, the window shrinks. Reported total is capped to what your plan can actually paginate through. | Response page/limit differ from what you sent. |
| Field stripping | Some plans omit specific fields from responses. The maturity ladder (exploit_maturity, weaponized, exploited_in_wild, cisa_kev) is open to every tier, as are epss_score, the exploit-evidence count (exploit_count - exploit repositories plus scoring references, not a count of working exploits), fix status and malicious-package flags. Anonymous callers lose the proprietary scoring (trending) and SSVC automatability inputs; free accounts additionally lose the attribution story (ransomware_use, both ATT&CK views, actors, origin, motivation, targeted sectors, victim geography) and the actor:/ttp:/tactic:/sector: search filters - those are Pro and up. | Field absent from the JSON. |
| Endpoint gating | Search and vulnerability lookup are open to everyone, including signed out. Affected software and the SSVC decision need a free account. References, repositories, bulk lookup, change feeds, decision summaries, and batch decisions require a paid (Pro) plan; the raw TAXII feed is Enterprise-only. A refused request does not consume your daily quota. | 403 with {"error":"this endpoint is not included in your plan","required_tier":"pro","unlocks":[…],"upgrade":"…"}, or 401 + a signup pointer when you are not signed in. |
Playing nicely with the limits
- Honor
Retry-After. On429, sleep the advertised seconds. Do not hammer - the bucket refills at a fixed rate regardless. - Sync deltas, not snapshots. Poll
/vulnerabilities/changes?since=…instead of re-fetching the world. A nightly delta is typically a few hundred records, not the entire corpus. - Batch. One
POST /vulnerabilities/lookupwith 100 IDs costs one request, not 100. Same forPOST /decisions/evaluate. - Cache lookups briefly. Exploitation state changes on feed-build cadence (hours), not per second. A 15-minute local cache removes most duplicate traffic.
- One key per integration. Separate CI, SOC, and dashboards - one noisy pipeline then cannot starve the others, and usage stays attributable on the usage page.
Every public endpoint, its parameters and the plan it needs. Base URL
https://api.harpia.ae/api/v1. The plan column is measured against the running
API, not transcribed: anything below the listed plan gets 403.
Search
| Endpoint | Plan | Parameters |
|---|---|---|
GET /vulnerabilities/search |
anonymous |
term — the query language (below); empty matches nothing and never dumps the corpus.page default 1; limit default 20.
Search depth is unlimited on every plan - page as deep as you like. What a plan
changes is the content of each row, not how many rows you may reach.
limit is capped at - rows per
response purely to bound payload size.sort = epss (default) · cvss · exploits ·
published · trendingseverity — comma-separated critical,high,medium,low
(either case)exploited · weaponized · ransomware ·
cisa_kev · malicious — value must be literally
1. Anything else, including true, is ignored and you get
unfiltered results rather than an error, so check this first if a filter looks like it did
nothing. (Inside term the qualifier form exploited:true is the one
that works — these are the panel filters, a different thing.)framework + decision + exposure + mission_consequence - filter by an SSVC priority or BOD 26-04 timeline
|
GET /decisions/summary |
Pro | Same parameters as /vulnerabilities/search. Choose framework=harpia_ssvc for
priority counts or framework=bod_26_04 for remediation timeline counts across
the whole result set, not just the current page. |
GET /exploits/repositories |
Pro | term, page, limit (1–200, default 25, then
clamped to your plan's window), sort = epss (default) ·
stars · repos · published.
CVEs ranked by public exploit-repository activity. |
GET /observed/trending |
Free | Regionally trending sensor activity. Optional country is an ISO-3166-1
alpha-2 code. Probing means exposure to attempts, not confirmed compromise. |
Lookup
| Endpoint | Plan | Parameters |
|---|---|---|
GET /vulnerabilities/{id} | anonymous | None. Full record: description, severity, CVSS, EPSS, maturity ladder position, exploit count, KEV, ransomware use, trending, CWE, aliases. Field visibility follows your plan. |
GET /vulnerabilities/{id}/software | Free | page (1–10000), limit default and max 100.
Affected vendor/product/ecosystem rows with version ranges and fixed versions. |
GET /vulnerabilities/{id}/references | Pro | page, limit — as above. Advisories, write-ups, patches. |
GET /vulnerabilities/{id}/repositories | Pro | page, limit — as above. Public exploit repositories with
confidence scoring. |
Decisioning
| Endpoint | Plan | Parameters |
|---|---|---|
GET /vulnerabilities/{id}/decision | Free | exposure = exposed (default) · controlled ·
not_exposedmission_consequence = critical (default) · high ·
moderate · lowframework = harpia_ssvc (default) · bod_26_04 - selects one complete decision modeldiscovered = YYYY-MM-DD - anchors the remediation window.
An invalid value is a 400, never a silent default. |
POST /decisions/evaluate | Pro | Body {"ids":[…],"framework":"bod_26_04","exposure":"exposed","mission_consequence":"high"} - up to - IDs,
32 KB body cap. Counts as one request against your rate and daily limits, which
makes it the cheapest way to consume the policy engine. |
CLI inventory scanning (Pro and up)
The Harpia CLI reads SBOMs, lockfiles, manifests, and resolved dependency reports on your machine. Files are never uploaded to this API. The CLI sends only normalized PURL or CPE coordinates, then evaluates each unique vulnerability once.
| Endpoint | Plan | Input and result |
|---|---|---|
POST /inventory/match | Pro | Up to 500 normalized component coordinates per request. The request body contains
package identity and version only. The response contains authoritative corpus matches
and an artifact-aware ETag for local revalidation. |
POST /decisions/evaluate | Pro | Up to 500 unique vulnerability IDs with one SSVC or BOD 26-04 asset context. Changing exposure, mission consequence, or framework repeats only this small call. |
curl -s -X POST \
-H "Authorization: Bearer $HARPIA_KEY" \
-H "Content-Type: application/json" \
-d '{"components":[{"purl":"pkg:npm/lodash@4.17.20"}]}' \
"https://api.harpia.ae/api/v1/inventory/match"
For normal use, install the CLI and run harpia scan <inventory-file>.
The default report is a readable table; select --output json for the complete
structured report or --output csv for finding rows. Run harpia serve
for the same workflow in a loopback-only browser interface.
Local limits: 100 MiB per file, 10,000 parsed components, and 5,000 findings
per report. A capped report returns "truncated":true. The CLI accepts CycloneDX
1.x JSON, SPDX 2.x JSON, npm inventories, pip reports and requirements, Maven inventories,
and Go module inventories. A JSON CycloneDX/SPDX file may use the .sbom extension.
XML, SPDX tag-value, Syft-native output, GitHub dependency snapshots, and plain PURL lists
are not accepted by this release.
Successful match batches are cached in the operating system user cache and revalidated
with an artifact-aware ETag. The cache contains no source file or API key, is
pruned at 256 MiB, and is invalidated automatically when the Harpia corpus changes.
Decisions are never reused: the CLI reevaluates them for the selected framework and asset
context on every scan.
Bulk & sync (Pro and up)
| Endpoint | Plan | Parameters |
|---|---|---|
POST /vulnerabilities/lookup | Pro | Body {"ids":["CVE-…","GHSA-…"]} — up to - IDs, 32 KB body cap.
One request instead of N. |
POST /weaknesses/resolve | Pro | Body {"ids":[…]} — same limits. Returns just the weakness classification per
CVE, for callers that want CWE mapping without the full record. |
GET /vulnerabilities/changes | Pro | since = YYYY-MM-DD (required; any other format is a
400). Returns {"since","count","ids"} — feed the IDs straight to
/vulnerabilities/lookup. This is the building block for keeping a local mirror current. |
Account
| Endpoint | Plan | Notes |
|---|---|---|
GET · POST · DELETE /keys | Free | Browser session only. An API key can never mint or manage keys — that would make a leaked key self-renewing. Use the account page. |
Browser session workflows
These routes belong to the first-party web app, not Bearer integrations. They are included here so the published HTTP contract matches the service.
match[...] extension.| Routes | Purpose |
|---|---|
GET /auth/me · GET /auth/usage · POST /auth/logout | Read or end the current cookie session without spending plan quota. |
PUT /auth/preferences · POST /auth/change-password · POST /auth/trial/accept · POST /auth/trial/decline | Signed-in account changes. |
POST /auth/login · POST /auth/register · POST /auth/resend · GET /auth/verify · POST /auth/forgot · POST /auth/reset | Conditional local-auth and recovery workflow. |
GET /auth/login/{provider} · GET /auth/callback/{provider} | OAuth browser redirects. |
GET · POST /auth/request-access · GET · POST /auth/access-decision | Tier-request and signed reviewer-decision workflow. |
/decisions/summary, which is a real API
endpoint because a decision count over a whole result set is an answer, not a chart.
For standards-based ingestion use the
STIX 2.1 / TAXII 2.1 feed. Need aggregate exports in your pipeline?
Talk to us — Enterprise delivery includes custom exports.Search response shape
{
"total": 128, // capped to your plan's reachable window
"page": 1, "limit": 20,
"results": [{
"id": "CVE-2024-3400",
"description": "…",
"published": "2024-04-12",
"severity": "CRITICAL", "cvss": 10.0,
"exploit_maturity": "active", // disclosed | poc | weaponized | active - every plan
"exploited_in_wild": true, "exploit_count": 58,
"weaponized": true, "cisa_kev": true,
"is_automatable": true, // SSVC automatability: registered plans and up
"is_fixable": true, // every plan
"epss_score": 0.99, // every plan
"trend_level": "trending", "trending_score": 97.2, // proprietary scoring: registered plans and up
"ransomware_use": true, // attribution fields: Pro and up
"is_malicious": false, "malicious_packages": null, "ttps": [...],
"cwe": ["CWE-77"], "aliases": ["USN-…","RHSA-…"]
}],
"facets": { "exploited": 12, "weaponized": 31, "ransomware": 4,
"cisa_kev": 12, "critical": 40, "high": 55, "medium": 30,
"low": 3, "malicious": 0 }
}
The term parameter accepts everything the search box does. AND is implicit;
OR, NOT, quoted phrases and
parentheses are supported. Negation binds to a whole qualifier or group, so
kev:true NOT ssvc:active and NOT (kev:true OR trend:trending) both do
what they look like. - and ! are accepted as shorthand for
NOT; the examples here spell it out because a leading hyphen is easy to misread
next to ids and hyphenated words.
Ordinary searches return CVEs and malicious-package findings. Advisory restatements stay
hidden so counts and remediation decisions are not duplicated. Enter an advisory id to resolve
it to the CVE or CVEs it covers, or use type:osv_advisory when the advisory records
themselves are required.
| Family | Syntax | Notes |
|---|---|---|
| Identifiers | CVE-2021-44228 · GHSA-jfh8-c2jp-5v3q · USN-7001-1 · RHSA-2025:1746 · DSA-5020-1 | Any vendor advisory alias resolves to its CVE. |
| Full text | "use after free" · heap OR "buffer overflow" · microsoft NOT windows | Quotes group a phrase; NOT negates (- and ! are accepted shorthand). A multi-word phrase must be quoted - unquoted, OR binds looser than the implicit AND, so heap OR buffer overflow reads as heap OR (buffer AND overflow). Common security phrases expand to their weakness class: "buffer overflow" answers as CWE-787/121/122, "use after free" as CWE-416. |
| Scores | epss:>0.9 · cvss:>=9 · epss:0.5..0.9 · exploits:>5 | Comparators and ranges. |
| Threat flags | kev:true · exploited:true · ransomware:true · maturity:weaponized · trending:true · zeroday:true | Boolean feed facts. maturity: is none · poc · weaponized · active. |
| has: | has:exploit · has:poc · has:fix · has:repo | Existence shorthands. |
| Software | vendor:microsoft · product:log4j · ecosystem:npm · product:openssl version:<3.0 · fixable:true | version: supports < <= > >= and exact. |
| Weakness | cwe:injection · cwe:rce · cwe:79 · cwe:CWE-416 | CWE classes by friendly name or number. |
| Time | age:<365 · published:2024 · modified:>2026-07-13 · added:>2025-01-01 | age: = days since publication. published/modified/added take a date or year (modified: = record's own update, added: = CISA KEV date-added). |
| Packages | malicious:true · ecosystem:npm · alias:GHSA-jfh8-c2jp-5v3q | Malicious-package records and advisory aliases. |
| Repositories | stars:>100 · repo_role:exploit · repo_since:>2026-07-01 · suspicious:true | Public exploit-repository signals, and what the repository actually is. |
| Movement | epss_change:>0.1 · epss_trend:up · trend:trending · scanning:up | Change rather than level - EPSS deltas, the trending tier, and whether observed probing is rising. |
| Observed probing | observed_in:AE · observed_from:CN · observed:>100 · observed_days:<3 | Sensor telemetry: hosts were probed for it. Exposure to attempts, not confirmed compromise. |
| Evidence | ref_type:exploited · ref_source:exploitdb · ref_since:>2026-07-01 | What is attached to the record, and who reported it. |
| Advisories | advisory:DSA-5020-1 · issuer:debian | 28 issuers, 860,359 links. "Which erratum closes the most exposure". |
| SSVC | ssvc:active · ssvc_automatable:true | CISA's own adjudication, separate from our rollups - useful where the two disagree. |
| Impact shape | attack_vector:network · tte:<7 · zeroday:true · cvss_version:4.0 | Vector, automation, and time from publication to first exploit evidence. |
| Arsenal Pro | malware:plugx · tool:mimikatz | Matched through the actors attributed to the CVE. |
| Who & why Pro | actor:qilin · origin:RU · motivation:espionage · sector:healthcare · target:"united arab emirates" | origin: (where the actor is from) and target: (who they hit) each take an ISO-3166 alpha-2 code, the full country name, or a partial word - origin:RU, origin:russia, target:AE, target:"united arab emirates" and target:saudi all resolve to the stored code(s). Below Pro these return 403 with a message naming the qualifier — the gate is on the compiled query, so an ordinary search that merely mentions an actor's name is unaffected. |
| ATT&CK Pro | ttp:T1190 · ttp:"public-facing" · tactic:TA0010 · tactic:"credential access" · capec:CAPEC-233 | Technique, tactic and CAPEC, by ID or by name. Names are matched on word boundaries, so tactic:"credential access" does not also match unrelated text. |
Worked examples
Each of these runs as-is. The attribution and ATT&CK ones need Pro.
| Question | Query |
|---|---|
| What is being exploited right now that I can actually fix? | exploited:true has:fix |
| Ransomware-adjacent healthcare exposure I can patch today | sector:healthcare kev:true has:fix |
| Nation-state pressure on my Microsoft estate | (origin:CN OR origin:RU) vendor:microsoft exploited:true |
| GCC-targeted and exploited in the wild | (target:"united arab emirates" OR target:"saudi arabia" OR target:qatar OR target:kuwait OR target:bahrain OR target:oman) exploited:true |
| Fresh in-the-wild initial-access plays | tactic:"initial access" exploited:true epss:>0.5 age:<365 |
| Perimeter exploitation, exploited, with a fix | ttp:T1190 exploited:true fixable:true |
| Espionage-motivated government targeting with no fix yet | motivation:espionage sector:government NOT has:fix |
| Recent KEV additions worth a look | kev:true age:<365 |
| High-probability exploitation, weaponized tooling exists | epss:>0.9 maturity:weaponized |
| Rising and not yet famous - EPSS climbing, probing climbing, not on KEV | epss_trend:up scanning:up NOT kev:true |
| New exploit code for something old and unpatched | repo_since:>2026-07-01 age:>365 NOT kev:true |
| Where CISA says active and our evidence is empty | ssvc:active NOT has:exploit |
| Is this specific dependency version affected? | product:openssl version:3.0 |
Severity describes a bug; a decision tells a team what to do. Select one framework per request. The endpoint merges locked feed facts with your context:
| Input | Values | Meaning |
|---|---|---|
| framework | harpia_ssvc · bod_26_04 | Harpia returns a priority and matching timeline. BOD returns its KEV-based timeline and forensic-triage requirement. |
| exposure | not_exposed · controlled · exposed | How reachable is the asset - isolated, behind controls, or effectively internet-facing. |
| mission_consequence | low · moderate · high · critical | Mission consequence if the asset is compromised. |
| Decision | Read it as |
|---|---|
| immediate | Act now. Timeline: 3 days. |
| out-of-cycle | Pull the fix forward. Timeline: 14 days. |
| scheduled | Use a managed maintenance cycle. Timeline: 60 days. |
| defer | Keep watching. Timeline: next system upgrade. |
GET /vulnerabilities/CVE-2024-3400/decision?framework=harpia_ssvc&exposure=exposed&mission_consequence=critical
{
"cve_id": "CVE-2024-3400",
"framework": "harpia_ssvc",
"inputs": {
"framework": {"value":"harpia_ssvc", "source":"customer", "defaulted":false},
"exposure": {"value":"exposed", "source":"customer", "defaulted":false},
"mission_consequence": {"value":"critical", "source":"customer", "defaulted":false}
},
"x_intel_priority": {
"decision": "immediate",
"exploit_maturity": "active", "exploited_in_wild": true,
"is_automatable": true,
"epss_score": 0.99, "attack_vector": "NETWORK",
"outcome": "Priority: immediate - … Exploitation=active, Exposure=exposed, …"
},
"policy_evaluated": true,
"engine_version": "harpia-decision-v3",
"facts": {
"exploitation": {"value":"active", "source":"harpia"},
"automatable": {"value":true, "source":"harpia"},
"technical_impact": {
"reported": {"value":"total", "source":"cisagov_ssvc"},
"derived": {"value":"total", "source":"harpia", "method":"cvss_v3_ci_v1"},
"effective": {"value":"total", "method":"conservative_max"},
"conflict": false
}
},
"guidance": {
"id": "harpia_ssvc",
"framework": "Harpia SSVC",
"source": "Harpia SSVC priority-to-timeline policy",
"reference": "https://harpia.ae/decisions#harpia-ssvc",
"timeline": "3_days",
"label": "3 days",
"window_days": 3,
"requires_forensic_triage": false,
"discovered_at": "2026-08-24",
"due_date": "2026-08-27",
"overdue": false,
"criteria": {"priority":"immediate"}
}
}
Select framework=bod_26_04 for the CISA timeline based on Publicly Exposed, On KEV, Automatable, and Technical Impact. BOD mode does not return a Harpia priority.
Decisions are computed live by the policy engine on every request - never cached, never pre-baked - so a CVE that gets weaponized overnight changes its answer the moment the feed updates.
CI/CD gate - block deploys on exploited dependencies
Parse the inventory locally and fail the build when something actively exploited ships in the artifact:
harpia scan --output json bom.json > scan.json
n=$(jq '[.findings[] | select(.vulnerability.maturity == "active" or .vulnerability.kev)] | length' scan.json)
[ "$n" -gt 0 ] && { echo "BLOCK: $n actively exploited findings"; exit 1; }
Nightly patch queue - rank by decision, not by CVSS
# 1. delta since last run (cheap - only what changed)
# → {"count": 464, "ids": ["CVE-…", …]}
curl -s -H "Authorization: Bearer $HARPIA_KEY" \
"https://api.harpia.ae/api/v1/vulnerabilities/changes?since=2026-07-16" > delta.json
# 2. one bulk decision call for the changed IDs under your context
# (chunk into batches of 500 when the delta is bigger)
jq '{ids:.ids[:500], exposure:"controlled", mission_consequence:"high"}' delta.json \
| curl -s -H "Authorization: Bearer $HARPIA_KEY" -H "Content-Type: application/json" \
-d @- "https://api.harpia.ae/api/v1/decisions/evaluate" \
| jq '.results | to_entries[]
| select(.value.x_intel_priority.decision | IN("immediate","out_of_cycle"))
| .key'
Two requests per night for a typical delta, regardless of estate size.
SOC alert enrichment
An IDS alert names a CVE. One call answers "is this noise or an incident?":
curl -s -H "Authorization: Bearer $HARPIA_KEY" \
"https://api.harpia.ae/api/v1/vulnerabilities/$CVE/decision?exposure=exposed&mission_consequence=critical" \
| jq '{decision:.x_intel_priority.decision, wild:.x_intel_priority.exploited_in_wild,
automatable:.x_intel_priority.is_automatable}'
Wire it into the SOAR playbook: immediate → page on-call; anything else →
enrich the ticket and move on.
Threat-intel platform ingestion (STIX/TAXII)
MISP, OpenCTI, and every TAXII 2.1 client can subscribe directly - no custom code:
curl -H "Accept: application/taxii+json;version=2.1" \
"https://harpia.ae/threatintel/" # discovery
curl -H "Accept: application/taxii+json;version=2.1" \
"https://harpia.ae/threatintel/collections/" # collections
Objects are STIX 2.1 (vulnerabilities, relationships, ATT&CK mappings). Browse interactively with the STIX explorer.
Vendor exposure watch
A weekly report of what is being hit in your vendor stack:
curl -s -H "Authorization: Bearer $HARPIA_KEY" \
"https://api.harpia.ae/api/v1/vulnerabilities/search?term=vendor:paloaltonetworks+exploited:true&sort=trending" \
| jq '.results[] | {id, exploit_maturity, trend_level}'
| Status | Body | What to do |
|---|---|---|
| 400 | {"message":"query syntax error: …"} | Fix the query - parentheses, operators, or an over-complex term (max 64 tokens). |
| 401 | {"message":"invalid or expired API token"} or {"error":"authentication required -- create a free account…","required_tier":"free","unlocks":[…],"signup":"…"} | Key revoked, expired, or malformed - mint a new one and check the Bearer prefix. No key at all? Direct anonymous API calls are not supported - create a free account. |
| 403 | {"error":"this endpoint is not included in your plan","tier":"free","required_tier":"pro","unlocks":[…],"upgrade":"…"} | Endpoint outside your plan - see plans or talk to us. Does not consume your daily quota. |
| 404 | {"message":"CVE not found"} | Unknown ID. Check the spelling; brand-new CVEs appear with the next feed build. |
| 413 | - | Request body too large (256 KB cap). Split the batch. |
| 429 | {"error":"rate limit exceeded -- try again shortly"} or {"error":"daily request limit reached -- resets at midnight UTC"} | Sleep Retry-After seconds. Recurring? Batch, cache, use delta sync - or contact us about a higher plan. |
| 5xx | - | Our side. Retry with exponential backoff; persistent failures → support@harpia.ae. |
Plans, limits, and the full feature matrix live in one place - see plans on the intelligence page, which now includes a Signed out column so you can see what an account actually changes.
Every account carries two separate budgets - one for browsing this site, one shared by all of your API keys - and they never draw from each other. Your live figures are on the usage page, and a banner appears once either passes 80%.
How fresh is the data?
The feed rebuilds continuously from upstream sources (NVD, OSV.dev, CISA KEV, EPSS, exploit telemetry). A CVE's exploitation state changes within hours of public evidence, and SSVC decisions reflect it on the next request - decisions are never cached.
How do I upgrade?
Harpia is invite-reviewed - we take on a limited number of accounts and read every request. Request access from your account and tell us what you're building; we reply to your account email, usually within a day or two.
I upgraded - when do the new limits apply?
On your very next request. Keys resolve their owner's plan live; nothing to re-issue.
Can I use the API from a browser app?
The API is same-origin by design and does not emit CORS headers. Call it from your backend - which is also where your key belongs. Browser sessions (the web UI) authenticate with an HttpOnly cookie instead of a key.
Does TAXII need authentication?
/taxii2/ discovery is public. STIX search requires Pro or above, and raw
collection, object, version, and manifest access requires an Enterprise key.
A CVE's state looks wrong.
Send the ID and evidence to feed@harpia.ae - corrections ship with the next feed build.
Something else?
Contact lists the right inbox for every topic - support, sales, security reports, and data corrections.
Ready to build? Is it being exploited right now?
