Reports API

HTTP reference for report profiles, per-pentest report settings, issued sealed reports and signed downloads.

All paths are relative to https://api.aleex-rank.ai/api/v2 and authenticate with X-API-Key: rk_... (see REST API). Profiles choose methodology, audience and formats; issued reports are sealed artifacts with a hash. Generating a new report is a streaming-backend call (below), not a REST POST. Cover logos and colours live on the Branding API. SARIF is not a report format — export findings from the Vulnerabilities API.

Caller default profile

GET /report-profiles
PUT /report-profiles

The caller’s default. GET returns the saved profile, the system_default, and field descriptors (fields). PUT replaces the caller’s profile and returns the saved object (without wrapping profile / system_default).

FieldTypeRequiredNotes
namestringNoDisplay name, 1–100 characters
methodologystringNowstg, asvs_l2, ptes or nist_800_115
compliance_overlaysstring[]Nopci_dss_11_4, soc2, iso27001, dora
audiencestringNoexecutive, technical or attestation
default_formatsstring[]NoNon-empty: pdf, html, markdown, docx, json — not SARIF
include_unvalidated_appendixboolNoAppend findings that are not yet validated
{
  "name": "Acme attestation",
  "methodology": "wstg",
  "compliance_overlays": ["pci_dss_11_4", "soc2"],
  "audience": "attestation",
  "default_formats": ["pdf", "html"],
  "include_unvalidated_appendix": false
}
{
  "success": true,
  "data": {
    "profile": {
      "id": 3,
      "owner_type": "user",
      "owner_id": 7,
      "name": "Acme attestation",
      "methodology": "wstg",
      "compliance_overlays": ["pci_dss_11_4", "soc2"],
      "audience": "attestation",
      "default_formats": ["pdf", "html"],
      "include_unvalidated_appendix": false,
      "is_default": true
    },
    "system_default": {
      "id": 0,
      "owner_type": "system",
      "name": "Rank Technical",
      "methodology": "wstg",
      "audience": "technical",
      "default_formats": ["pdf"],
      "include_unvalidated_appendix": true,
      "is_default": true
    },
    "fields": [
      {"key": "methodology", "type": "enum", "multiple": false, "options": [{"id": "wstg", "label": "OWASP Web Security Testing Guide"}]}
    ]
  }
}

Team profile

GET /teams/{id}/report-profiles
PUT /teams/{id}/report-profiles

Same shape as the caller default, scoped to the team. PUT is owner-only; other members receive 403.

Per-pentest settings

GET /pentests/{id}/report-settings
PUT /pentests/{id}/report-settings

Pins this pentest to a saved profile, or clears the pin so the tenant/team default applies. PUT accepts only report_profile_id (a positive integer, or null to unpin). GET returns the effective resolved profile plus the same field descriptors as the catalog (fields):

{
  "success": true,
  "data": {
    "effective": {
      "id": 3,
      "name": "Acme attestation",
      "methodology": "wstg",
      "compliance_overlays": ["pci_dss_11_4", "soc2"],
      "audience": "attestation",
      "default_formats": ["pdf", "html"],
      "include_unvalidated_appendix": false,
      "is_default": true
    },
    "fields": [
      {"key": "audience", "type": "enum", "multiple": false, "options": [{"id": "executive", "label": "Executive"}]}
    ]
  }
}
{"report_profile_id": 3}

Field catalog

GET /catalogs/report-profiles

Descriptors for the profile fields (enums, labels and allowed options), not a saved profile. The same list is embedded as fields on GET /report-profiles and GET /pentests/{id}/report-settings. See Catalogs for the full objects.

{
  "success": true,
  "data": {
    "fields": [
      {
        "key": "methodology",
        "label": "Testing methodology",
        "type": "enum",
        "multiple": false,
        "options": [
          {"id": "wstg", "label": "OWASP Web Security Testing Guide"},
          {"id": "asvs_l2", "label": "OWASP ASVS Level 2"},
          {"id": "ptes", "label": "PTES"},
          {"id": "nist_800_115", "label": "NIST SP 800-115"}
        ]
      }
    ]
  }
}

Issued sealed reports

GET /pentests/{id}/reports
GET /pentests/{id}/reports/{reportId}

GET /reports lists reports that have already been issued and sealed. The envelope is {items} with no pagination. Ids are integers.

{
  "success": true,
  "data": {
    "items": [
      {
        "id": 12,
        "pentest_id": 15,
        "issuance_group": "iss_8f2c",
        "report_profile_id": 3,
        "methodology": "wstg",
        "audience": "executive",
        "language": "en",
        "recipient_email": "ciso@acme.example",
        "format": "pdf",
        "payload_sha256": "7c4a8d09ca3762af61e59520943dc26494f8941b0123456789abcdef01234567",
        "content_sha256": "7c4a8d09ca3762af61e59520943dc26494f8941b0123456789abcdef01234567",
        "size_bytes": 245760,
        "mime_type": "application/pdf",
        "status": "sealed",
        "sealed_at": "2026-03-02 16:50:00"
      }
    ]
  }
}

GET …/reports/{reportId} returns {report, url}. The file is never inlined.

{
  "success": true,
  "data": {
    "report": {
      "id": 12,
      "format": "pdf",
      "payload_sha256": "7c4a8d09ca3762af61e59520943dc26494f8941b0123456789abcdef01234567",
      "status": "sealed",
      "sealed_at": "2026-03-02 16:50:00"
    },
    "url": "https://storage.googleapis.com/..."
  }
}

Generate a report

Issuing a new report is served by the streaming backend, not api/v2:

POST https://aleex.aleex-rank.ai/generate_report
Content-Type: application/json

pentest_id and recipient_email are required. Optional: recipient_name, subject, cc_emails, extended (0 or 1), formats[], audience.

{
  "pentest_id": 15,
  "recipient_email": "ciso@acme.example",
  "recipient_name": "Alex Rivera",
  "subject": "Q1 web assessment report",
  "cc_emails": ["soc@acme.example"],
  "extended": 1,
  "formats": ["pdf", "html"],
  "audience": "executive"
}

Rank emails the PDF only if the report is sealed. Other formats are stored as issued reports and downloaded through the signed URL above. This call is not wrapped in the REST success envelope. White-label the PDF with Branding.

Where to go next