API Reference

Table of contents


Base URL and authentication

https://kief.dev/api/vekt

All requests must include an Authorization header with your API key:

Authorization: Bearer vkt_live_xxxxxxxxxxxxxxxxxxxx

Get an API key at kief.dev/vekt/signup.


Rate limiting

Every scan response includes rate limit headers:

Header Description
X-Vekt-Request-Id Unique request identifier
X-RateLimit-Remaining Scans remaining in the current period

When your quota is exhausted, the API returns 429 Too Many Requests with a Retry-After header. On paid plans, overage scans continue and are billed at $0.005 per scan.


POST /api/vekt/scan

Submit a lockfile for scanning. Returns a list of scan results grouped by lockfile.

Request

Content type: application/json

POST /api/vekt/scan
Authorization: Bearer <api-key>
Content-Type: application/json

Request body:

{
  "lockfile_type": "package-lock.json",
  "content": "<raw lockfile content as a string>"
}
Field Type Required Description
lockfile_type string Yes Filename of the lockfile format (see supported lockfile types)
content string Yes Raw text content of the lockfile

Content type: multipart/form-data

You can also upload the lockfile as a file:

POST /api/vekt/scan
Authorization: Bearer <api-key>
Content-Type: multipart/form-data

Form fields:

Field Type Required Description
file file Yes The lockfile to scan. The filename is used to detect the type if lockfile_type is not provided.
lockfile_type string No Override the lockfile type detection from the filename.

Maximum request size: 5 MB.

Response

HTTP 200 with a JSON array of scan results. An empty array means no findings were detected.

[
  {
    "lockfile": "package-lock.json",
    "type": "package-lock.json",
    "ecosystem": "npm",
    "packages_scanned": 312,
    "findings": [
      {
        "package": "lodash",
        "version": "4.17.15",
        "ecosystem": "npm",
        "malicious": false,
        "security_holder": false,
        "vulns": [
          {
            "id": "GHSA-jf85-cpcp-j695",
            "summary": "Prototype Pollution in lodash",
            "threat_level": "Vulnerability",
            "aliases": ["CVE-2019-10744"],
            "url": "https://osv.dev/vulnerability/GHSA-jf85-cpcp-j695"
          }
        ]
      }
    ]
  }
]

Response fields

Field Type Description
lockfile string Lockfile that was scanned
type string Lockfile format identifier
ecosystem string Ecosystem identifier (e.g., npm, PyPI, crates.io)
packages_scanned number Total packages checked
findings array Packages with findings
findings[].package string Package name
findings[].version string Package version
findings[].ecosystem string Ecosystem identifier
findings[].malicious boolean true if any finding is a confirmed malicious package
findings[].security_holder boolean true if the package is an inert registry security-placeholder
findings[].vulns array List of individual vulnerability or advisory findings
findings[].vulns[].id string Advisory identifier (e.g., GHSA-xxxx-yyyy-zzzz, CVE-2024-XXXXX, MAL-2024-XXXX)
findings[].vulns[].summary string Human-readable description of the finding
findings[].vulns[].threat_level string "Malicious", "Vulnerability", or "SecurityHolder"
findings[].vulns[].aliases array Alternative IDs for the same advisory
findings[].vulns[].url string Link to the full advisory

Example: curl with JSON body

curl -s -X POST https://kief.dev/api/vekt/scan \
  -H "Authorization: Bearer vkt_live_xxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "lockfile_type": "package-lock.json",
    "content": "'"$(cat package-lock.json | jq -Rs .)"'"
  }'

Example: curl with file upload

curl -s -X POST https://kief.dev/api/vekt/scan \
  -H "Authorization: Bearer vkt_live_xxxxxxxxxxxxxxxxxxxx" \
  -F "file=@package-lock.json"

Example: pipe a lockfile

cat Cargo.lock | \
  jq -Rs '{"lockfile_type": "Cargo.lock", "content": .}' | \
  curl -s -X POST https://kief.dev/api/vekt/scan \
    -H "Authorization: Bearer vkt_live_xxxxxxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d @-

Example response (clean scan)

[]

An empty array means all packages in the lockfile are clean.


Error responses

All error responses use the following format:

{
  "error": "Human-readable description of the problem"
}
Status Description
400 The request body is malformed, the lockfile_type is not recognized, or the content cannot be parsed
401 The Authorization header is missing or the API key is invalid
413 The request body exceeds the 5 MB limit
415 Unsupported Content-Type (must be application/json or multipart/form-data)
429 You have exceeded your scan quota for the current period
500 An unexpected server error occurred
502 The scanner binary returned an error

Status codes

Code Meaning
200 Scan completed. Response body contains the results array (may be empty).
400 Bad request -- check the request format or lockfile type.
401 Authentication required -- check your API key.
413 Lockfile too large -- maximum 5 MB per request.
415 Unsupported Content-Type.
429 Rate limit exceeded -- check Retry-After header.
500 Server error -- safe to retry.
502 Scanner error -- the lockfile may be malformed.