CRAnotify Documentation

API v1 reference

The CRAnotify public API is a small, deliberate B2B surface: it registers an inbound security signal, reads the product catalogue and the compliance score, and receives bills of materials from pipelines. It always returns JSON. Every call is authenticated with an API key belonging to your organisation and is scoped to that organisation: a key never sees another customer's data, and the tenant comes from the key, never from the request body. To explore the endpoints interactively use the console at https://api.cranotify.eu/swagger, generated from the same OpenAPI 3 specification (https://api.cranotify.eu/swagger/openapi.json).

Key management. Creating keys, choosing scopes, rotation and revocation are covered in API and integration keys. This page documents the endpoint contract.

Base address

In production the API answers on the dedicated host api.<domain>. The three reads and incident intake also answer there in the short /v1 form:

https://api.cranotify.eu/v1/products

On every host (including the unified development host) the same endpoints answer under the full prefix /api/v1/external. SBOM ingest is available only in that full form. The downloaded specification reports the address of the host that served it.

Authentication

Present the key in the X-CRA-API-Key header or as a bearer token. The two are equivalent.

X-CRA-API-Key: cra_live_…
# or
Authorization: Bearer cra_live_…

Read endpoints allow only GET; incident intake and SBOM ingest accept only POST. Any other method returns 405.

Scopes

Each key carries one or more scopes; the required scope is specific to the endpoint. There are no all-purpose keys: a read-only key cannot open an incident or push an SBOM.

ScopeUnlocks
incidents:writeRegister an inbound security signal.
products:readRead the product catalogue with SBOM status and risk level.
compliance:readRead the organisation's compliance score.
products:writePush a bill of materials from your pipelines.

Endpoints

The public surface is four endpoints. There is no pagination: lists come back whole with their count.

Method and pathScopeDescription
POST /api/v1/external/incidentsincidents:writeRegisters an inbound security signal (INCOMING). It does not create a case: no awareness, no 24h/72h clock. Turning it into a case is a human decision in the console.
GET /api/v1/external/productsproducts:readProduct catalogue with bill-of-materials status and risk level derived from active cases. Returns {"products":[…],"count":N}.
GET /api/v1/external/compliance-scorecompliance:readReal-time compliance KPIs: rule-based CRA Health Score, average MTTN, SBOM coverage, active 24h/72h timers.
POST /api/v1/external/products/{sku}/sbomproducts:writeIngest a CycloneDX/SPDX SBOM for the product identified by SKU. Converges on the same release-versioned model as web and CLI uploads (see Bill of materials).

On the dedicated host api.cranotify.eu the first three also answer in the short form /v1/incidents, /v1/products, /v1/compliance-score.

There are no endpoints for reading cases, the key profile, the registry or registry verification from the public API: those are console-only operations. The API returns no paginated envelope.

Rate limit

Each key is limited to 100 requests per minute. Over the limit the response is 429 with the headers X-RateLimit-Limit, X-RateLimit-Remaining and Retry-After.

Examples

# Product catalogue
curl -H "X-CRA-API-Key: cra_live_…" https://api.cranotify.eu/v1/products

# Compliance score
curl -H "Authorization: Bearer cra_live_…" https://api.cranotify.eu/v1/compliance-score

# Open an inbound signal
curl -X POST -H "X-CRA-API-Key: cra_live_…" -H "Content-Type: application/json" \
     -d '{"title":"…","description":"…"}' \
     https://api.cranotify.eu/v1/incidents

# Push an SBOM for an SKU
curl -X POST -H "X-CRA-API-Key: cra_live_…" -H "Content-Type: application/json" \
     --data-binary @sbom.cyclonedx.json \
     https://api.cranotify.eu/api/v1/external/products/SKU-123/sbom

What the API does not expose

The product catalogue carries metadata and compliance status, never the organisation's secrets. A reporter's identity and contact, Privilege Vault notes, TOTP secrets and attachment storage keys are not reachable from the public API.

Error codes

CodeMeaning
401Missing, wrong, revoked or expired key.
403Valid key without the required scope.
405Method not allowed on the endpoint.
422Invalid body: missing fields on incident intake, or an SBOM that is neither CycloneDX nor SPDX.
429Rate limit exceeded (100/min per key).

Specification and API console

API consoleThe https://api.cranotify.eu/swagger page (/docs stays an alias) shows every endpoint, its parameters, schemas and examples. Self-hosted, no CDN.
OpenAPI 3 specificationThe raw document is at https://api.cranotify.eu/swagger/openapi.json — import it into Postman, Insomnia or a client generator.

Didn’t find the answer?

Support replies within one working day. Quote your organisation code and, if the request concerns a case, its number.

Documentation updated on 5 August 2026 · Legal notice · Privacy · support@cranotify.eu