KB Sync API¶
The Knowledge Base (KB) Sync API lets an installation push locally discovered CPE mappings and pull published mappings from the central server. The server stores pushed mappings only from Professional licenses and refuses them from other editions. This creates a community-driven knowledge base that improves vulnerability matching accuracy over time.
The server also maintains the software identity catalogue as a baseline.
These routes are on the license server, not on your own installation:
Authentication¶
KB Sync endpoints use a custom authentication scheme based on the signed license data:
Authorization: Bearer <first 64 chars of signed_data>
X-Installation-ID: SK-INST-<32 uppercase hex characters>
Authorization: First 64 characters of the signed license string (base64url(payload).base64url(signature))X-Installation-ID: The installation's unique ID. It must belong to an active, unexpired license whose signed token starts with the one you send
The edition is read from the license, not from any header you send. Pushing requires a Professional license.
Push Mappings¶
Submit locally discovered CPE mappings from a Professional installation.
POST /api/v1/kb/mappings/push
Authorization: Bearer <token>
X-Installation-ID: SK-INST-<32 uppercase hex characters>
Content-Type: application/json
Request Body¶
{
"mappings": [
{
"vendor_pattern": "apache software foundation",
"product_pattern": "http server",
"cpe_vendor": "apache",
"cpe_product": "http_server",
"confidence": 0.85
},
{
"vendor_pattern": "microsoft corporation",
"product_pattern": "visual studio code",
"cpe_vendor": "microsoft",
"cpe_product": "visual_studio_code",
"confidence": 0.90
}
]
}
| Field | Type | Required | Description |
|---|---|---|---|
mappings | array | Yes | List of mapping items (max 500) |
mappings[].vendor_pattern | string | Yes | Vendor name pattern to match (1-200 characters) |
mappings[].product_pattern | string | Yes | Product name pattern to match (1-200 characters) |
mappings[].cpe_vendor | string | Yes | Corresponding CPE vendor (1-200 characters) |
mappings[].cpe_product | string | Yes | Corresponding CPE product (1-200 characters) |
mappings[].confidence | float | No | Confidence score 0.0-1.0, default 0.8 (capped at 0.90 for community) |
timestamp | string | No | Optional client timestamp |
The installation is identified by the X-Installation-ID header only.
Response¶
Security Model¶
- Mappings are stored with
is_published=falseby default - A mapping is automatically published when 3 or more independent installations confirm the same vendor/product pair
- Confidence scores from community contributions are capped at 0.90
- A repeat push from an installation that already confirmed a mapping does not count as a second confirmation; only a new installation increments the
contribution_count
Pull Mappings¶
Download published mappings from the central KB. Available to all licensed installations.
GET /api/v1/kb/mappings/pull
Authorization: Bearer <token>
X-Installation-ID: SK-INST-<32 uppercase hex characters>
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
since | ISO 8601 datetime | None | Only return mappings updated after this timestamp. A value that is not ISO 8601 returns 400 |
since_id | integer | None | The id of the last mapping you consumed. Use it together with since (see Incremental Sync) |
source | string | all | Filter by source: community, nvd or curated. Omit for everything |
limit | integer | 50000 | Maximum number of entries to return (1-100000, values above 50000 are capped at 50000) |
offset | integer | 0 | Pagination offset |
Results are ordered by (updated_at, id), oldest first.
Response¶
{
"mappings": [
{
"id": 1021,
"vendor_pattern": "apache software foundation",
"product_pattern": "http server",
"cpe_vendor": "apache",
"cpe_product": "http_server",
"confidence": 0.85,
"source": "community",
"notes": "",
"updated_at": "2026-02-10T12:00:00"
},
{
"id": 1022,
"vendor_pattern": "microsoft",
"product_pattern": "windows_10",
"cpe_vendor": "microsoft",
"cpe_product": "windows_10",
"confidence": 1.0,
"source": "nvd",
"notes": "",
"updated_at": "2026-02-09T03:00:00"
}
],
"count": 2,
"timestamp": "2026-10-07T12:00:00"
}
count is the number of mappings in this response. To know whether there is more, request the next page (offset) or the next cursor until a response returns fewer rows than limit.
Incremental Sync¶
The cursor is the pair (updated_at, id) of the last mapping you received. Pass both: since alone can skip mappings that share one timestamp.
# First sync: read page by page (a call with no limit returns at most 50000 mappings).
# Continue with offset=5000, offset=10000 and so on, until a response has fewer rows than limit.
curl -H "Authorization: Bearer $TOKEN" \
-H "X-Installation-ID: $INST_ID" \
"https://api.sentrikat.com/api/v1/kb/mappings/pull?limit=5000&offset=0"
# Subsequent syncs: only changes after the last mapping you received
curl -H "Authorization: Bearer $TOKEN" \
-H "X-Installation-ID: $INST_ID" \
"https://api.sentrikat.com/api/v1/kb/mappings/pull?since=2026-02-10T12:00:00&since_id=1021"
Mapping Sources¶
| Source | Description | Published |
|---|---|---|
nvd | software identity catalogue | Always |
community | Submitted by Professional installations (confidence capped at 0.90) | After 3+ confirmations |
curated | Curated by the SentriKat team | Always |
Rate Limits¶
| Endpoint | Limit |
|---|---|
POST /api/v1/kb/mappings/push | 1 request per installation per hour |
GET /api/v1/kb/mappings/pull | 60 requests per installation per hour |
Note
Rate limits are per installation ID, not per IP. A request over the limit returns 429 with a Retry-After header giving the seconds to wait.
Error Codes¶
Errors carry a JSON body of the form {"detail": "..."}.
| Code | Description |
|---|---|
| 200 | Success |
| 400 | since is not an ISO 8601 timestamp |
| 401 | Missing or malformed Authorization header, token shorter than 64 characters, or missing X-Installation-ID |
| 403 | Token does not match an active license for this installation, license is expired, or the license is not Professional (push only) |
| 422 | Invalid request body, including more than 500 mappings |
| 429 | Rate limit exceeded |