API Documentation

Integrate Vericode security audits into your CI/CD pipeline. Get findings as JSON with SARIF output for GitHub Code Scanning.

Base URLhttps://vericodeai.com/audit-api

Quick Start

Get your first automated audit running in under 5 minutes. You need a Pro or Enterprise subscription and an API key from Dashboard → Settings.

GitHub Actions Example

.github/workflows/vericode.yml
name: Vericode Security Audit

on:
  push:
    paths: ['contracts/**']
  pull_request:
    paths: ['contracts/**']

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Vericode Audit
        id: audit
        run: |
          # Read all .sol files into JSON
          FILES_JSON=$(python3 -c "
          import json, glob
          files = {}
          for f in glob.glob('contracts/**/*.sol', recursive=True):
              with open(f) as fh:
                  files[f.split('/')[-1]] = fh.read()
          print(json.dumps({'files': files}))
          ")

          # Start audit
          RESULT=$(curl -s -X POST \
            https://vericodeai.com/audit-api/api/ci/audit \
            -H "X-API-Key: ${{ secrets.VERICODE_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d "$FILES_JSON")

          JOB_ID=$(echo "$RESULT" | jq -r '.job_id')
          echo "job_id=$JOB_ID" >> $GITHUB_OUTPUT

          # Poll until completed (max 15 min)
          for i in $(seq 1 90); do
            STATUS=$(curl -s \
              "https://vericodeai.com/audit-api/api/ci/audit/$JOB_ID" \
              -H "X-API-Key: ${{ secrets.VERICODE_API_KEY }}")
            STATE=$(echo "$STATUS" | jq -r '.status')
            if [ "$STATE" = "completed" ]; then
              echo "$STATUS" | jq '.sarif' > results.sarif
              echo "status=completed" >> $GITHUB_OUTPUT
              break
            elif [ "$STATE" = "failed" ]; then
              echo "Audit failed: $(echo $STATUS | jq -r '.error')"
              exit 1
            fi
            echo "Waiting... ($STATE, attempt $i/90)"
            sleep 10
          done

      - name: Upload SARIF to GitHub
        if: steps.audit.outputs.status == 'completed'
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif
Tip: Add your API key as a repository secret: Settings → Secrets → VERICODE_API_KEY

Simple curl Example

bash
# Start an audit
curl -X POST https://vericodeai.com/audit-api/api/ci/audit \
  -H "X-API-Key: ci_vericodeai_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "files": {
      "MyContract.sol": "pragma solidity ^0.8.20;\ncontract MyContract { ... }"
    }
  }'

# Response:
# {"job_id": "a1b2c3d4", "status": "queued", "poll_url": "/api/ci/audit/a1b2c3d4"}

# Poll for results
curl https://vericodeai.com/audit-api/api/ci/audit/a1b2c3d4 \
  -H "X-API-Key: ci_vericodeai_YOUR_KEY"

Authentication

All CI/CD endpoints use API key authentication via the X-API-Key header. Keys are linked to your subscription and respect plan limits.

Getting an API Key

  1. Sign in at vericodeai.com/login
  2. Subscribe to Pro ($99/mo) or Enterprise ($499/mo)
  3. Go to Dashboard → Settings
  4. Click Create Key, copy the key immediately (shown only once)
Request Header
X-API-Key: ci_vericodeai_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
Important: Keep your API key secret. Do not commit it to source code. Use environment variables or CI/CD secrets.

Plan Access

EndpointPro ($99/mo)Enterprise ($499/mo)
POST /api/ci/audit4 audits/moUnlimited
GET /api/ci/audit/:idYesYes
POST /api/deep-fuzz-Unlimited
GET /api/deep-fuzz/:id-Yes

Rate Limits

LimitValueScope
Start audit5 requests/minutePer IP
Hourly audit cap50 audits/hourPer API key
Poll status60 requests/minutePer IP
Deep fuzz5 requests/minutePer IP

When a rate limit is exceeded, the API returns 429 Too Many Requests with a descriptive message.

CI/CD Audit

POST/api/ci/auditPro+

Submit Solidity source files for a full 10-stage security audit. Runs static analysis (Slither, Mythril, Aderyn, Semgrep), multi-model AI analysis, Halmos + Echidna formal verification, auto PoC generation, and adversarial review.

Request Body

JSON
{
  "files": {
    "MyToken.sol": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n...",
    "Vault.sol": "pragma solidity ^0.8.20;\ncontract Vault { ... }"
  },
  "config": null
}
FieldTypeRequiredDescription
filesobjectYesMap of filename → Solidity source code. Keys must end in .sol
configobjectNoReserved for future use (custom rules, severity threshold)

Response

JSON — 200 OK
{
  "job_id": "a1b2c3d4",
  "status": "queued",
  "poll_url": "/api/ci/audit/a1b2c3d4",
  "files_accepted": ["MyToken.sol", "Vault.sol"],
  "queue_position": 2,
  "estimated_wait": 180
}

Audit Status & Results

GET/api/ci/audit/{job_id}Pro+

Poll audit progress. When status is "completed", the response includes full findings, severity counts, SARIF output, verification data, and disproved findings.

In Progress Response

JSON — 200 (running)
{
  "job_id": "a1b2c3d4",
  "status": "running",
  "progress": 45,
  "step": "Running Echidna fuzzing...",
  "queue_position": 0,
  "estimated_wait": 0
}

Completed Response

JSON — 200 (completed)
{
  "job_id": "a1b2c3d4",
  "status": "completed",
  "contract_name": "MyToken",
  "chain": "",
  "risk_level": "high",
  "total_findings": 7,
  "severity_counts": {
    "critical": 1,
    "high": 2,
    "medium": 3,
    "low": 1,
    "informational": 0
  },
  "findings": [
    {
      "severity": "critical",
      "title": "Reentrancy in withdraw()",
      "description": "The withdraw function calls msg.sender before...",
      "location": "MyToken.sol:45-52",
      "recommendation": "Use the checks-effects-interactions pattern...",
      "confidence": "high",
      "found_by": ["slither", "claude-3.5-sonnet", "gpt-4o"],
      "poc_code": "function testReentrancy() public { ... }",
      "poc_status": "proven_exploitable",
      "adversarial_status": "confirmed"
    }
  ],
  "verification": {
    "halmos": {"properties_tested": 4, "properties_violated": 1},
    "echidna": {"properties_tested": 5, "properties_broken": 2},
    "poc": {"total": 7, "proven": 3, "failed": 4},
    "adversarial": {"confirmed": 5, "disputed": 1, "disproved": 1}
  },
  "disproved_findings": [
    {
      "title": "Potential integer overflow in fee calculation",
      "severity": "medium",
      "adversarial_reasoning": "Solidity 0.8+ has built-in overflow checks..."
    }
  ],
  "disproved_count": 1,
  "summary": "7 findings identified: 1 critical, 2 high...",
  "sarif": { "...SARIF 2.1.0 object..." }
}

Finding Fields

FieldTypeDescription
severitystringcritical | high | medium | low | informational
titlestringShort finding title
descriptionstringDetailed description of the vulnerability
locationstringFile and line reference (e.g. Token.sol:45-52)
recommendationstringHow to fix the issue
confidencestringhigh | medium | low
found_bystring[]Tools/models that detected this finding
poc_codestringFoundry test proving exploitability (may be empty)
poc_statusstringproven_exploitable | compilation_failed | test_failed | ""
adversarial_statusstringconfirmed | disputed | disproved

Status Values

StatusDescription
queuedWaiting in queue
runningAudit in progress (check progress 0-100)
completedFull results available
failedAudit failed (check error field)

Deep Fuzz (Enterprise)

POST/api/deep-fuzzEnterprise

Run extended Echidna fuzzing for ~30 minutes with protocol-aware invariant checks. Automatically classifies your protocol type (lending, AMM, vault, staking) and generates targeted property tests. Enterprise subscription required.

Request Body

JSON
{
  "source_code": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\ncontract Vault { ... }"
}
FieldTypeRequiredDescription
source_codestringYesRaw Solidity source code (min 20 characters)

Response

JSON — 200 OK
{
  "job_id": "e5f6a7b8",
  "status": "running",
  "mode": "deep_fuzz",
  "estimated_time": "~30 minutes",
  "poll_url": "/api/deep-fuzz/e5f6a7b8"
}

Deep Fuzz Status

GET/api/deep-fuzz/{job_id}Enterprise

Poll deep fuzz results. Returns Echidna output including broken invariants and findings.

Completed Response

JSON — 200 (completed)
{
  "job_id": "e5f6a7b8",
  "status": "completed",
  "success": true,
  "properties_tested": 12,
  "properties_broken": 3,
  "findings": [
    {
      "title": "Invariant violated: total supply conservation",
      "severity": "high",
      "description": "Echidna found a sequence of calls that breaks...",
      "location": "Vault.sol"
    }
  ],
  "echidna_time_seconds": 1803,
  "error": null
}

SARIF Integration

Every completed CI audit includes a sarif field containing a valid SARIF 2.1.0 document. You can upload this directly to GitHub Code Scanning to see findings as inline annotations on pull requests.

SARIF Structure

SARIF 2.1.0
{
  "version": "2.1.0",
  "$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/...",
  "runs": [{
    "tool": {
      "driver": {
        "name": "VericodeAI",
        "version": "1.0.0",
        "rules": [
          {
            "id": "VERI-CRITICAL-001",
            "shortDescription": { "text": "Reentrancy in withdraw()" },
            "properties": {
              "security-severity": "9.5",
              "tags": ["security", "smart-contract", "solidity"]
            }
          }
        ]
      }
    },
    "results": [
      {
        "ruleId": "VERI-CRITICAL-001",
        "level": "error",
        "message": { "text": "Reentrancy in withdraw()\n\nThe withdraw function..." },
        "locations": [{
          "physicalLocation": {
            "artifactLocation": { "uri": "MyToken.sol" },
            "region": { "startLine": 45, "endLine": 52 }
          }
        }]
      }
    ]
  }]
}

GitHub Actions Upload

yaml
# After polling and saving SARIF:
- name: Upload SARIF to GitHub Code Scanning
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif
    category: vericode-audit
Note: GitHub Code Scanning requires GitHub Advanced Security (free for public repos, paid for private repos on Team/Enterprise plans).

Error Codes

CodeMeaningAction
401Missing or invalid API keyCheck X-API-Key header
403Plan doesn't allow this endpointUpgrade to Pro or Enterprise
400Invalid request bodyCheck request format — files must contain .sol keys
404Audit job not foundCheck job_id
429Rate limit exceededWait and retry. Check Retry-After header
500Internal server errorContact [email protected]
Error responses always include a detail field with a human-readable message:
{"detail": "CI/CD integration requires Pro ($99/mo) or Enterprise ($499/mo) subscription"}

Need help with integration?

Email us at [email protected] or reach out on X/Twitter.