reference

API Reference

Attestd exposes REST endpoints for vulnerability checks, product catalog, CVE detail lookup, usage quota, and webhook management. All responses are JSON unless noted.

Base URL

https://api.attestd.io

Authentication

Pass your API key in the Authorization header as a Bearer token.

Authorization: Bearer YOUR_API_KEY

Get an API key from the developer portal. Use Authorization: Bearer atst_... on every request.

endpoint

GET /v1/check

Returns the current risk assessment for a product version.

Query parameters

ParameterDescription
productRequired. Product slug (e.g. nginx, log4j, openssh). See Quickstart for the full list.
versionRequired. Version string in any standard format (e.g. 1.24.0, 2.14.1, 8.0p1).
includeOptional. Pass include=cves to receive a per-CVE breakdown in the cves array. Omit for the default compact response.

Example request

bash
curl "https://api.attestd.io/v1/check?product=nginx&version=1.20.0" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example with include=cves

Pass include=cves to receive per-CVE detail records in the cves array. See Response Fields for subfield semantics.

bash
curl "https://api.attestd.io/v1/check?product=log4j&version=2.14.1&include=cves" \
  -H "Authorization: Bearer YOUR_API_KEY"
json
{
  "product": "log4j",
  "version": "2.14.1",
  "supported": true,
  "risk_state": "critical",
  "risk_factors": [
    "active_exploitation",
    "remote_code_execution",
    "no_authentication_required",
    "internet_exposed_service",
    "patch_available"
  ],
  "actively_exploited": true,
  "remote_exploitable": true,
  "authentication_required": false,
  "patch_available": true,
  "fixed_version": "2.25.4",
  "confidence": 0.5,
  "cve_ids": ["CVE-2021-44228", "CVE-2021-45046", "CVE-2021-45105"],
  "max_epss": 0.99999,
  "cves": [
    {
      "cve_id": "CVE-2021-44228",
      "cvss_score": 10.0,
      "actively_exploited": true,
      "remote_exploitable": true,
      "epss_score": 0.99999,
      "epss_percentile": 1.0
    },
    {
      "cve_id": "CVE-2021-45046",
      "cvss_score": 9.0,
      "actively_exploited": true,
      "remote_exploitable": true,
      "epss_score": 0.97123,
      "epss_percentile": 0.998
    }
  ],
  "last_updated": "2026-07-08T10:58:13.230818Z",
  "supply_chain": null,
  "typosquat": null
}

Responses

200 OK(supported product)
json
{
  "product": "nginx",
  "version": "1.20.0",
  "supported": true,
  "risk_state": "high",
  "risk_factors": [
    "remote_code_execution",
    "no_authentication_required",
    "internet_exposed_service",
    "patch_available"
  ],
  "actively_exploited": false,
  "remote_exploitable": true,
  "authentication_required": false,
  "patch_available": true,
  "fixed_version": "1.20.1",
  "confidence": 0.88,
  "cve_ids": [
    "CVE-2021-23017"
  ],
  "cves": null,
  "max_epss": null,
  "supply_chain": null,
  "supply_chain_monitored": false,
  "typosquat": null,
  "last_updated": "2026-02-23T18:21:30Z"
}
200 OK(product not in coverage)
json
{
  "supported": false,
  "typosquat": {
    "detected": true,
    "kind": "hallucination",
    "resembles": "jscodeshift",
    "likely_intended": ["jscodeshift"],
    "confidence": 0.9,
    "ecosystem": "npm"
  }
}
batch endpoint

POST /v1/check/batch

Check up to 100 product versions in a single request. Each item in the batch is billed as one API call. If the batch would exceed your quota, a 429 is returned before any results are delivered and no calls are billed.

Request body

FieldDescription
itemsRequired. Array of { product, version } objects. Minimum 1, maximum 100.
items[].productProduct slug. Same format as the GET /v1/check product parameter.
items[].versionVersion string. Same format as the GET /v1/check version parameter.

The optional include=cves query parameter works the same as on GET /v1/check and applies to every item in the batch.

Example request

bash
curl -X POST "https://api.attestd.io/v1/check/batch" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "product": "log4j", "version": "2.14.1" },
      { "product": "nginx", "version": "1.27.4" }
    ]
  }'

Response

Each entry in results has a product, version, and result field. The result object is identical in shape to a GET /v1/check response. Results are returned in the same order as the input items.

json
{
  "results": [
    {
      "product": "log4j",
      "version": "2.14.1",
      "result": {
        "product": "log4j",
        "version": "2.14.1",
        "supported": true,
        "risk_state": "critical",
        "risk_factors": [
          "active_exploitation",
          "remote_code_execution",
          "no_authentication_required",
          "internet_exposed_service",
          "patch_available"
        ],
        "actively_exploited": true,
        "remote_exploitable": true,
        "authentication_required": false,
        "patch_available": true,
        "fixed_version": "2.17.1",
        "confidence": 0.94,
        "cve_ids": ["CVE-2021-44228", "CVE-2021-45046", "CVE-2021-45105"],
        "cves": null,
        "max_epss": null,
        "supply_chain": null,
        "typosquat": null,
        "last_updated": "2026-02-23T18:21:30Z"
      }
    },
    {
      "product": "nginx",
      "version": "1.27.4",
      "result": {
        "product": "nginx",
        "version": "1.27.4",
        "supported": true,
        "risk_state": "none",
        "risk_factors": [],
        "actively_exploited": false,
        "remote_exploitable": false,
        "authentication_required": false,
        "patch_available": false,
        "fixed_version": null,
        "confidence": 0.90,
        "cve_ids": [],
        "cves": null,
        "max_epss": null,
        "supply_chain": null,
        "typosquat": null,
        "last_updated": "2026-04-10T09:15:00Z"
      }
    }
  ],
  "count": 2
}
webhooks

Team-tier accounts can register HTTPS endpoints for supply_chain.compromise events. See Supply chain webhooks for payload shape, signature verification, and delivery semantics.

GET /v1/webhooks

List active webhook subscriptions for the authenticated account. Returns 403 if the API key is not on the Team plan.

bash
curl "https://api.attestd.io/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY"
json
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "url": "https://hooks.example.com/attestd",
    "events": ["supply_chain.compromise"],
    "created_at": "2026-07-08T12:00:00Z"
  }
]

POST /v1/webhooks

Create a subscription. Body fields: url (HTTPS), secret (16 to 64 characters), events (array; currently supply_chain.compromise only). Returns 201 on success, 400 on validation failure, 403 if not Team tier.

bash
curl -X POST "https://api.attestd.io/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/attestd",
    "secret": "your-signing-secret-min-16-chars",
    "events": ["supply_chain.compromise"]
  }'
json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "url": "https://hooks.example.com/attestd",
  "events": ["supply_chain.compromise"],
  "created_at": "2026-07-08T12:00:00Z"
}

DELETE /v1/webhooks/{id}

Soft-delete a subscription and cancel pending deliveries. Returns 204 on success, 404 if the subscription is not found or not owned by the account.

bash
curl -X DELETE "https://api.attestd.io/v1/webhooks/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_API_KEY"
products endpoint

GET /v1/products

Returns the full list of products Attestd covers: CVE-tracked software and monitored supply chain packages. Requires a valid API key. The CVE product slugs match the Products catalog.

Example request

bash
curl "https://api.attestd.io/v1/products" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

Three top-level fields: cve_products (slug and display_name for each CVE product), supply_chain_packages (package name, ecosystem, and optional display_name), and total (combined count). Arrays are truncated in the example below.

json
{
  "cve_products": [
    { "slug": "nginx", "display_name": "nginx" },
    { "slug": "log4j", "display_name": "Log4j" },
    { "slug": "postgresql", "display_name": "PostgreSQL" }
  ],
  "supply_chain_packages": [
    { "package": "langchain", "ecosystem": "pypi", "display_name": "LangChain" },
    { "package": "react", "ecosystem": "npm", "display_name": "React" }
  ],
  "total": 265416
}
cve endpoint

GET /v1/cve/{cve_id}

Returns full details for a single CVE: CVSS, EPSS, KEV status, and affected Attestd product slugs. Requires a valid API key. Returns 404 when the CVE is not in Attestd's database. Returns 400 on a malformed CVE id.

Example request

bash
curl "https://api.attestd.io/v1/cve/CVE-2021-44228" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

Fields include cve_id, description, cvss_score, cvss_vector, actively_exploited, remote_exploitable, authentication_required, affected_products, epss_score, epss_percentile, source_published_at, and last_checked_at.

json
{
  "cve_id": "CVE-2021-44228",
  "description": "Apache Log4j2 JNDI injection allows remote code execution.",
  "cvss_score": 10.0,
  "cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
  "actively_exploited": true,
  "remote_exploitable": true,
  "authentication_required": false,
  "affected_products": ["log4j"],
  "epss_score": 0.97568,
  "epss_percentile": 0.99976,
  "source_published_at": "2021-12-10T00:00:00Z",
  "last_checked_at": "2026-07-08T04:00:00Z"
}
usage endpoint

GET /v1/usage

Returns API call quota for the authenticated key: calls used this month, included cap, billing period start and end, and overage estimate. Returns 401 without a valid API key.

Example request

bash
curl "https://api.attestd.io/v1/usage" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

Compare key_calls_this_month against included_calls to monitor quota. account_calls_this_month aggregates usage across all keys on the account.

json
{
  "tier": "solo",
  "key_calls_this_month": 1200,
  "account_calls_this_month": 1200,
  "included_calls": 250000,
  "billing_period_start": "2026-07-01T00:00:00Z",
  "billing_period_end": "2026-08-01T00:00:00Z",
  "overage_calls": 0,
  "estimated_overage_usd": 0.0
}

Supply chain signals

For monitored PyPI and npm packages, the 200 OK response includes a supply_chain object with integrity data (compromised, sources, advisory_url, etc.). For CVE-only products (nginx, PostgreSQL, etc.), supply_chain is null.

See the Supply Chain Integrity guide for the full list of monitored packages and field semantics.

error codes
StatusMeaning
400Missing or invalid query parameters (product or version omitted)
401Missing or invalid API key
422Version string could not be parsed
429Rate limit exceeded (see Retry-After header)
500Internal server error (transient, safe to retry with backoff)
bash
HTTP/1.1 429 Too Many Requests
Retry-After: 60

{
  "detail": "Rate limit exceeded"
}
rate limits
TierMonthly limitPer-minute limit
Free5,000 calls60/min
Solo250k/monthNone
Team2M/monthNone
PlatformUnlimited (contract)None

Monthly limits reset on your billing anniversary. Free tier returns 429 when the monthly cap or the 60/min per-minute limit is reached. Solo returns 429 at 250,000 calls. Team returns 429 at 2,000,000 calls. Platform has no cap under contract. The 429 response includes a Retry-After header with seconds to wait.