Public API

REST API

ZeroDrift REST endpoints, curl examples, and the finding response shape.

Base URL

https://zerodrift.xyz/api

Every request to the audit API takes a Bearer token. The token is scoped to the user account that created it, and session data is only returned to the owner of that session. GitHub repository selection is not exposed by the public API; every public audit starts from a direct zip upload.

The machine-readable OpenAPI 3.0 specification is available at /openapi.json. Regenerate it after changing a documented route with pnpm openapi:generate.

Endpoints

MethodPathAuthDescription
POST/audit/uploadBearerUpload a zip archive as multipart form data.
GET/audit/sessionsBearerList the authenticated user's audit sessions.
POST/audit/sessionsBearerCreate and queue an audit session from an uploaded archive.
GET/audit/sessions/:sessionId/statusBearerPoll session status and synchronize stored state.
GET/audit/sessions/:sessionId/findingsBearerRead findings for a session.

Uploading source

Upload a zip archive before creating an audit session. Send the file as multipart form data.

export TOKEN="<token>"
export ZIP="/path/to/protocol.zip"

curl -X POST "https://zerodrift.xyz/api/audit/upload" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@$ZIP"

Response:

{ "upload_id": "upl_123" }

Exclude node_modules, .git, build artifacts, caches, binaries, and generated output from the zip. Smaller source archives are faster to upload and easier to inspect.

Creating an audit

Create the audit session with the upload_id returned by the upload endpoint. Send it as uploadId in this request.

curl -X POST "https://zerodrift.xyz/api/audit/sessions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"uploadId":"upl_123"}'

Response:

{
  "session_id": "sess_abc",
  "status": "running",
  "dbRecord": {
    "id": 1,
    "sessionId": "sess_abc",
    "status": "running"
  }
}

The audit balance is charged before the backend session is created. If the balance is too low, the endpoint returns 402 and no session is created.

Polling status

Poll the status endpoint until running is false.

curl "https://zerodrift.xyz/api/audit/sessions/$SESSION_ID/status" \
  -H "Authorization: Bearer $TOKEN"

Response:

{
  "session_id": "sess_abc",
  "running": true,
  "remaining_percentage": 42,
  "dbRecord": {
    "id": 1,
    "sessionId": "sess_abc",
    "status": "running"
  }
}

Reading findings

Read findings once the backend has produced results. The endpoint can also be called while a session is still running if partial findings are available.

curl "https://zerodrift.xyz/api/audit/sessions/$SESSION_ID/findings" \
  -H "Authorization: Bearer $TOKEN"

Response:

[
  {
    "title": "Unchecked external call result",
    "severity": "high",
    "description": "...",
    "recommendation": "..."
  }
]

Finding response

Finding records are returned as JSON objects. The exact shape can expand over time, so clients should preserve unknown fields instead of dropping them.

{
  "title": "Unchecked external call result",
  "severity": "high",
  "description": "The contract ignores a downstream call result.",
  "recommendation": "Check the return value and revert on failure."
}

Status codes

CodeMeaning
400The request body is missing a required field.
401The bearer token is missing, malformed, expired, or revoked.
402The account balance is too low to create a session.
403The requested session belongs to another account.
404The requested session was not found or does not belong to the token owner.
5xxThe audit backend is temporarily unavailable.