Skip to main content

Endpoint

GET https://api.vulnzap.com/api/scan/jobs/:jobId

Description

Retrieves the status and results of a specific scan job. Use this endpoint to poll for scan completion or retrieve final results.

Headers

x-api-key
string
required
Your VulnZap API key

Path Parameters

jobId
string
required
Job ID returned from scan initiation (/github or /commit endpoints)

Job Status Values

StatusDescription
pendingJob is queued and waiting to start
runningScan is currently in progress
completedScan finished successfully
failedScan encountered an error
cancelledScan was cancelled by user

Response (Running)

{
  "success": true,
  "data": {
    "jobId": "550e8400-e29b-41d4-a716-446655440000",
    "projectId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "status": "running",
    "progress": 45,
    "metadata": {
      "repository": "owner/repo",
      "branch": "main",
      "scanType": "full_repository"
    },
    "startedAt": "2025-11-14T10:30:00.000Z",
    "completedAt": null,
    "error": null
  }
}

Response (Completed)

When scan completes successfully, full results are included:
{
  "success": true,
  "data": {
    "jobId": "550e8400-e29b-41d4-a716-446655440000",
    "projectId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "status": "completed",
    "progress": 100,
    "metadata": {
      "repository": "owner/repo",
      "branch": "main",
      "scanType": "full_repository"
    },
    "startedAt": "2025-11-14T10:30:00.000Z",
    "completedAt": "2025-11-14T10:35:30.000Z",
    "error": null,
    "results": {
      "scanId": "repositoryscan_1731582930000_abc123",
      "repositoryId": "project-id",
      "timestamp": "2025-11-14T10:35:30.000Z",
      "scanType": "full",
      "totalFiles": 150,
      "linesOfCode": 25000,
      "vulnerabilities": [
        {
          "id": "vuln_1731582930000_abc123",
          "type": "SQL_INJECTION",
          "severity": "critical",
          "confidence": "high",
          "location": {
            "file": "src/api/users.ts",
            "startLine": 45,
            "startColumn": 12,
            "endLine": 45,
            "endColumn": 65,
            "codeSnippet": "const query = `SELECT * FROM users WHERE id = ${userId}`;"
          },
          "description": "SQL injection vulnerability detected in user query",
          "evidence": "Unsanitized user input directly concatenated into SQL query",
          "cwe": "CWE-89",
          "owasp": "A03:2021-Injection",
          "tags": ["sql", "injection", "critical"],
          "falsePositive": false,
          "detectionMethod": "taint",
          "createdAt": "2025-11-14T10:35:25.000Z",
          "source": {
            "file": "src/api/users.ts",
            "startLine": 42,
            "startColumn": 8,
            "endLine": 42,
            "endColumn": 30,
            "codeSnippet": "const userId = req.params.id;"
          },
          "sink": {
            "file": "src/api/users.ts",
            "startLine": 45,
            "startColumn": 12,
            "endLine": 45,
            "endColumn": 65,
            "codeSnippet": "const query = `SELECT * FROM users WHERE id = ${userId}`;"
          },
          "taintFlowPath": [
            {
              "stepNumber": 1,
              "file": "src/api/users.ts",
              "line": 42,
              "column": 8,
              "codeSnippet": "const userId = req.params.id;",
              "description": "User input received from request parameters"
            },
            {
              "stepNumber": 2,
              "file": "src/api/users.ts",
              "line": 45,
              "column": 12,
              "codeSnippet": "const query = `SELECT * FROM users WHERE id = ${userId}`;",
              "description": "Tainted data flows into SQL query without sanitization"
            }
          ]
        }
      ],
      "summary": {
        "critical": 5,
        "high": 12,
        "medium": 8,
        "low": 3,
        "info": 2,
        "total": 30
      },
      "processingStats": {
        "duration": 330000,
        "tokensUsed": 125000,
        "falsePositivesFiltered": 15,
        "duplicatesRemoved": 8
      }
    },
    "resultId": "result-uuid",
    "createdAt": "2025-11-14T10:35:30.000Z",
    "publicShareUrl": "abc123de"
  }
}

Response (Shared Scan)

For scans that share results with other users scanning the same repository/branch:
{
  "success": true,
  "data": {
    "jobId": "your-job-id",
    "projectId": "your-project-id",
    "status": "running",
    "progress": 45,
    "metadata": {
      "repository": "owner/repo",
      "branch": "main"
    },
    "startedAt": "2025-11-14T10:30:00.000Z",
    "completedAt": null,
    "error": null,
    "isSharedScan": true,
    "originalJobId": "original-job-uuid"
  }
}

Vulnerability Object Schema

Each vulnerability includes the following fields:

Common Fields

id
string
Unique vulnerability identifier
type
string
Vulnerability type (e.g., SQL_INJECTION, XSS, PATH_TRAVERSAL)
severity
enum
Severity level: critical, high, medium, low, or info
confidence
enum
Detection confidence: high, medium, or low
location
object
Primary location with file path, line numbers, and code snippet
description
string
Clear description of the vulnerability
evidence
string
Evidence supporting the finding
cwe
string
CWE identifier (e.g., CWE-89)
owasp
string
OWASP category (e.g., A03:2021-Injection)
tags
array
Tags for categorization
falsePositive
boolean
Whether Faraday’s Context Validator marked this as a false positive
detectionMethod
enum
Detection method: standalone or taint

Taint-Specific Fields

Only present when detectionMethod: "taint":
source
object
Where tainted data originates (e.g., user input)
sink
object
Where tainted data reaches dangerous operation
taintFlowPath
array
Step-by-step flow from source to sink

Example Request

curl -X GET https://api.vulnzap.com/api/scan/jobs/550e8400-e29b-41d4-a716-446655440000 \
  -H "x-api-key: your_api_key_here"

Error Responses

{
  "success": false,
  "error": "Job not found or doesn't belong to your account"
}

Best Practices

If using polling instead of SSE, poll every 5-10 seconds to avoid rate limits.
For real-time updates, use the SSE endpoints (/github/:scanId/events or /commit/:jobId/events) instead of polling.
Check for the isSharedScan field. When true, multiple users are scanning the same repo/branch and share results.