DEVELOPER DOCUMENTATION • V1.0

NIS2Engine API

Integrate NIS2 vendor assessments directly into your existing compliance infrastructure, GRC platform, or internal tooling.

Base URL: https://api.yourdomain.com

API access is available on the Enterprise plan only. Contact us to discuss your integration requirements.

Contact Sales

Authentication

All API requests (except /scan/demo and /health) require a valid JWT token obtained from your NIS2Engine account.

Include the token in the Authorization header:

http
Authorization: Bearer YOUR_JWT_TOKEN

Obtaining a Token:

Tokens are obtained by authenticating with Supabase Auth using your account credentials. Enterprise customers receive a long-lived API token. Contact support for setup.

bash
curl -X POST https://api.yourdomain.com/vendors \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain": "vendor.com", "consent_given": true}'

Rate Limits

EndpointLimit
POST /scan/demo2 per minute per IP
POST /scans/trigger5 per minute per account
GET endpoints100 per minute per account
POST /reports/letter10 per minute per account

When a rate limit is exceeded, the API returns HTTP 429 Too Many Requests with a Retry-After header.

json
{
  "detail": "Rate limit exceeded. Retry after 30 seconds."
}

Error Responses

The API uses standard HTTP status codes:

  • 200 Success
  • 201 Created
  • 400 Bad Request — invalid input
  • 401 Unauthorized — missing or invalid token
  • 403 Forbidden — insufficient permissions
  • 404 Not Found
  • 422 Validation Error — see details field
  • 429 Rate Limited
  • 500 Internal Server Error
json
{
  "detail": "Human readable error message",
  "code": "ERROR_CODE",
  "timestamp": "2026-06-27T10:00:00Z"
}

Endpoint Reference

GET

/health

No auth required. Returns platform health status.

json
{
  "status": "healthy",
  "version": "1.0.0",
  "timestamp": "2026-06-27T10:00:00Z"
}
GET

/vendors

Auth required. Returns all vendors for the authenticated account.

json
{
  "vendors": [
    {
      "id": "uuid",
      "domain": "stripe.com",
      "vendor_name": "Stripe Inc",
      "status": "complete",
      "current_score": 100,
      "current_grade": "A",
      "risk_level": "Low",
      "last_scanned_at": "2026-06-27T10:00:00Z",
      "created_at": "2026-01-15T08:00:00Z"
    }
  ],
  "total": 5
}
POST

/vendors

Auth required. Add a new vendor to your monitoring portfolio.

consent_given must be true. By submitting this request, you confirm that you are authorized to conduct security assessments of this domain and that this falls within the scope of your legitimate business operations.

json
// Request
{
  "domain": "vendor.com",          // required
  "vendor_name": "Vendor Ltd",     // optional
  "notes": "Payment processor",    // optional
  "consent_given": true            // required, must be true
}

// Response 201
{
  "id": "uuid",
  "domain": "vendor.com",
  "status": "pending",
  "created_at": "2026-06-27T10:00:00Z"
}
DELETE

/vendors/{id}

Auth required. Remove a vendor from monitoring.

json
// Response 200
{
  "message": "Vendor deleted successfully"
}
POST

/scans/trigger

Auth required. Trigger a manual security scan for a vendor. The scan runs asynchronously.

json
// Request
{
  "vendor_id": "uuid"
}

// Response 200
{
  "message": "Scan queued",
  "vendor_id": "uuid",
  "status": "scanning"
}
GET

/scans/history/{vendor_id}

Auth required. Returns scan history for a specific vendor.

json
{
  "scans": [
    {
      "id": "uuid",
      "score": 100,
      "grade": "A",
      "risk_level": "Low",
      "pdf_url": "https://...",
      "scanned_at": "2026-06-27T10:00:00Z",
      "score_data": {
        "deductions": [...],
        "bonuses": [...],
        "nis2_mapping": {...}
      }
    }
  ]
}
GET

/dashboard/summary

Auth required. Returns portfolio-level statistics.

json
{
  "total_vendors": 12,
  "scanned_this_month": 12,
  "critical_risks": 1,
  "average_score": 78,
  "grade_distribution": {
    "A": 6, "B": 3, "C": 2, "D": 1, "F": 0
  }
}
POST

/reports/letter

Auth required. Generate a remediation letter for a vendor.

json
// Request
{
  "vendor_id": "uuid",
  "language": "en"  // en, de, fr, es, ar
}

// Response 200
{
  "letter": "Full letter text...",
  "vendor": "vendor.com",
  "language": "en",
  "generated_at": "2026-06-27T10:00:00Z"
}
POST

/scan/demo

No auth required. Rate limited: 2/minute per IP. Run a demo scan for any domain. Does not store results or require an account.

Note: Internal IPs (localhost, 192.168.x.x, 10.x.x.x, 127.x.x.x) are blocked.

json
// Request
{
  "domain": "stripe.com"
}

Webhooks

Enterprise plan only. Configure webhook URLs in your account settings. NIS2Engine sends POST requests to your configured URL when specific events occur.

SCAN_COMPLETED

Fired when a vendor scan finishes.

json
{
  "event": "scan_completed",
  "vendor_id": "uuid",
  "domain": "vendor.com",
  "score": 78,
  "grade": "C",
  "risk_level": "Medium",
  "pdf_url": "https://...",
  "timestamp": "2026-06-27T10:00:00Z"
}

GRADE_CHANGED

Fired when a vendor's grade changes between scans.

json
{
  "event": "grade_changed",
  "vendor_id": "uuid",
  "domain": "vendor.com",
  "previous_grade": "B",
  "new_grade": "D",
  "score_change": -18,
  "timestamp": "2026-06-27T10:00:00Z"
}

CRITICAL_ALERT

Fired when a vendor drops to grade D or F.

json
{
  "event": "critical_alert",
  "vendor_id": "uuid",
  "domain": "vendor.com",
  "grade": "F",
  "score": 20,
  "critical_findings": [
    "Expired TLS certificate",
    "TLS 1.0 still supported"
  ],
  "timestamp": "2026-06-27T10:00:00Z"
}

Webhook Security

Verify webhook authenticity by checking the X-NIS2-Signature header against your webhook secret using HMAC-SHA256.

python
import hmac, hashlib

def verify(payload, secret, signature):
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Core Data Types

VENDOR OBJECT

json
{
  "id": "uuid string",
  "domain": "string — the vendor domain",
  "vendor_name": "string | null",
  "notes": "string | null",
  "consent_given": "boolean",
  "consent_timestamp": "ISO 8601 datetime",
  "status": "pending | scanning | complete | error",
  "current_score": "integer 0-100 | null",
  "current_grade": "A | B | C | D | F | null",
  "risk_level": "Low | Medium | High | Critical | null",
  "last_scanned_at": "ISO 8601 datetime | null",
  "created_at": "ISO 8601 datetime"
}

SCORE DATA OBJECT

json
{
  "score": "integer 0-100",
  "grade": "A | B | C | D | F",
  "risk_level": "Low | Medium | High | Critical",
  "deductions": [
    {
      "reason": "string",
      "penalty": "integer"
    }
  ],
  "bonuses": [
    {
      "reason": "string", 
      "bonus": "integer"
    }
  ],
  "nis2_mapping": {
    "article_21_2a": "compliant | partial | non-compliant",
    "article_21_2d": "compliant | partial | non-compliant",
    "article_21_2e": "compliant | partial | non-compliant",
    "article_21_2f": "compliant | partial | non-compliant",
    "article_21_2g": "compliant | partial | non-compliant",
    "article_21_2j": "compliant | partial | non-compliant"
  },
  "critical_risks": ["string"],
  "positive_findings": ["string"],
  "remediation_steps": [
    {
      "priority": "Critical | High | Medium",
      "action": "string",
      "deadline_days": "integer"
    }
  ],
  "technical_summary": "string",
  "executive_summary": "string"
}

Need help with your integration?

Enterprise customers have access to a dedicated integration support channel.

Contact Enterprise Support

Legal: Use of the NIS2Engine API is subject to our Terms of Service and Data Processing Agreement. By using the API you confirm that all scans are conducted with proper authorization and within the scope of legitimate security assessment activities.