Introduction

The PrivaScan API gives you programmatic access to smart contract risk scores for EVM privacy protocols. One request returns a deterministic composite score (0-100), a letter grade, and six sub-scores covering code, ownership, liquidity, audits, compliance, and governance. No SDK required.

Base URL
https://api-production-c35ab.up.railway.app/api/v1
JSON responses only · CORS enabled · No SDK required

Authentication

Pass your API key in the X-API-Key header. Without a key you get 10 requests per hour based on your IP address. A free key gives you 500 per hour, isolated to your key so other users never affect your quota. Generate one at privascan.xyz/keys.

authenticated
curl https://api-production-c35ab.up.railway.app/api/v1/score/ethereum/0x910Cbd... -H "X-API-Key: ps_your_key_here"
no key (10 req/hr)
curl https://api-production-c35ab.up.railway.app/api/v1/score/ethereum/0x910Cbd...

Rate Limits

Two windows run simultaneously: per-minute prevents burst abuse, per-hour caps sustained usage. Both must be within limit for a request to succeed. On 429, check the Retry-After header for seconds to wait.

TIERPER MINPER HOURIDENTIFIER
Anonymous2/min10/hrClient IP
Free15/min500/hrKey hash
Pro60/min2000/hrKey hash

API Key Usage Credits

Every API request consumes 1 credit from your hourly allowance. Credits reset one hour after your first request in that window. Here is what counts and what does not:

YES200 OK responses
Consumes 1 credit
YESCached responses
Consumes 1 credit
NO400, 401, 422 client errors
Does NOT consume credits
NO500 server errors
Does NOT consume credits
NO429 rate limit responses
Does NOT consume credits

Track real-time usage at privascan.xyz/usage.

Endpoint Index

All available endpoints at a glance:

ENDPOINT TITLEPATH
GETGet Contract Risk Score/score/{chain}/{address}
GETGet Score History/score/{chain}/{address}/history
POSTQueue Background Scan/score/request
GETList Privacy Protocols/protocols/
GETGet Protocol Detail/protocols/{slug}
POSTGenerate API Key/keys/generate
GETCheck API Usage/keys/usage

Error Reference

All errors return a JSON object with a single detail field containing a human-readable explanation. Use the HTTP status code to identify the error class.

error shape
{ "detail": "Invalid or inactive API key." }
400Bad RequestMissing or invalid parameters. Check your request body.
401UnauthorizedAPI key is invalid, inactive, or missing the ps_ prefix.
404Not FoundUnknown protocol slug, expired task ID, or unindexed address.
422Validation ErrorWrong field type in request body. Check the endpoint schema.
429Rate LimitedCheck Retry-After header. Implement exponential backoff.
500Server ErrorSlither failed or upstream API unavailable. Retry in 60s.
GET

Get Contract Risk Score

GET/api/v1/score/{chain}/{address}

The primary endpoint. Runs a full 6-dimension risk analysis on any EVM contract and returns a composite score from 0 to 100 (lower is safer), a letter grade A through F, and detailed per-dimension sub-scores. First-time scans take 30-60 seconds while Slither analyses the bytecode. Results are cached for 1 hour after that.

chain*
string

EVM chain slug. One of: ethereum, arbitrum, optimism, base, polygon, bsc, avalanche

address*
string

Contract address. 0x-prefixed EVM address, 42 characters. Lowercased automatically.

request
curl https://api-production-c35ab.up.railway.app/api/v1/score/ethereum/0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF -H "X-API-Key: ps_your_key_here"
200 response
{ "address": "0x910cbd523d972eb0a6f4cae4618ad62622b39dbf", "chain": "ethereum", "chain_id": 1, "composite_score": 74.2, "grade": "B", "grade_label": "Moderate-Low Risk", "override_applied": false, "override_status": null, "sub_scores": { "code": 82, "ownership": 91, "liquidity": 71, "audit": 80, "compliance": 100, "governance": 50 }, "scored_at": "2026-05-17T21:00:00Z", "cached": false }
GET

Get Score History

GET/api/v1/score/{chain}/{address}/history

Returns historical score snapshots for a contract address, newest first. Curated protocols accumulate 4 snapshots per day (rescored every 6 hours). Community scans accumulate only on request. Use the limit query param to control how many you get back.

limit
integer (query)

Number of snapshots to return. Default: 10. Maximum: 30.

request + response
GET /api/v1/score/ethereum/0x910Cbd.../history?limit=3 { "history": [ { "composite_score": 74.2, "grade": "B", "scored_at": "2026-05-17T21:00:00Z" }, { "composite_score": 76.1, "grade": "B", "scored_at": "2026-05-17T15:00:00Z" }, { "composite_score": 74.8, "grade": "B", "scored_at": "2026-05-17T09:00:00Z" } ] }
POST

Queue Background Scan

POST/api/v1/score/request

Dispatches a Slither analysis to the background worker queue and returns a task ID immediately without waiting for the result. Poll the task endpoint to check completion. Useful when you want to trigger a rescore without blocking your application.

request
POST /api/v1/score/request Content-Type: application/json { "chain": "ethereum", "address": "0x910Cbd..." } -> { "task_id": "d9330c89-7ef8-4780-8a6e-663ba6741c49", "status": "queued" }
polling the result
GET /api/v1/score/task/d9330c89-7ef8-4780-8a6e-663ba6741c49 # While processing: { "status": "running" } # When complete: { "status": "complete", "result": { ...full score object... } } # If it failed: { "status": "failed", "error": "Slither analysis failed for unverified contract" }
GET

List Privacy Protocols

GET/api/v1/protocols/

Returns all 14 curated protocols with metadata and their latest ecosystem scores. These protocols are manually vetted, have verified source code, and are automatically rescored every 6 hours. Results include the aggregated ecosystem grade across all deployed contracts.

request + response
GET /api/v1/protocols/ { "count": 14, "protocols": [ { "slug": "railgun", "name": "Railgun", "description": "ZK shielded balances for private DeFi on Ethereum and L2s.", "website_url": "https://railgun.org", "github_url": "https://github.com/Railgun-Community", "latest_score": { "composite_score": 74.2, "grade": "B" } } ] }
GET

Get Protocol Detail

GET/api/v1/protocols/{slug}

Full protocol metadata, the complete list of all deployed contracts across all chains, and the latest ecosystem-level score. Use this to get contract addresses for individual scoring via the GET /score endpoint.

slug*
string

Protocol slug. Examples: railgun, aztec, privacy-pools, hinkal, tornado-cash

POST

Generate API Key

POST/api/v1/keys/generate

Generates a new ps_ prefixed API key. The raw key is returned exactly once and is never stored on the server. Save it immediately. If you lose it, generate a new one. Free keys require Telegram verification first — use the guided flow at privascan.xyz/keys.

request + response
POST /api/v1/keys/generate Content-Type: application/json { "email": "you@example.com", "tier": "free" } -> { "api_key": "ps_CwkQ0JQnWeTFIgJbNMZ7Jukxdftyd0RBPuiPAbtGGjQ", "tier": "free", "email": "you@example.com", "message": "Store this key safely. Rate limit: 500 req/hr." }
GET

Check API Usage

GET/api/v1/keys/usage

Returns detailed usage stats for an API key: credits used this hour, remaining credits, time until the window resets, all-time request count, and a daily breakdown for the last 7 days. Or use the visual usage dashboard.

key*
string (query)

Your full API key starting with ps_. Passed as a URL query parameter.

example
GET /api/v1/keys/usage?key=ps_your_key_here { "tier": "free", "email": "you@example.com", "rate_limits": { "per_minute": 15, "per_hour": 500 }, "current_hour": { "used": 42, "remaining": 458, "resets_in_seconds": 2341 }, "all_time": { "total_requests": 1847 }, "last_7_days": [ { "date": "20260517", "label": "May 17", "requests": 234 } ] }

Grade Reference

A
0-20
Low risk. Strong code, decentralised ownership, sufficient TVL, audited, clean compliance record.
B
21-40
Moderate-low risk. Generally sound with minor areas for improvement. Most established protocols land here.
C
41-60
Moderate risk. Multiple risk vectors present. Proceed carefully and verify independently.
D
61-80
High risk. Significant vulnerabilities or compliance concerns. Investigate thoroughly before interacting.
F
81-100
Critical or hard override active. OFAC cap (score 10) or exploit cap (score 30) may apply.

Supported Chains

ethereumEthereum Mainnet1
arbitrumArbitrum One42161
optimismOptimism Mainnet10
baseBase8453
polygonPolygon PoS137
bscBNB Smart Chain56
avalancheAvalanche C-Chain43114

Response Schema

Complete shape of the score response object:

ScoreResult
{ address: string // lowercased 0x contract address chain: string // chain slug chain_id: integer // EVM chain ID composite_score: float // 0-100, lower is safer grade: string // "A" | "B" | "C" | "D" | "F" grade_label: string // e.g. "Moderate-Low Risk" override_applied: boolean // true if OFAC or exploit override changed the score override_status: string|null // "ofac_active" | "exploit_active" | null sub_scores: { code: float // Slither analysis + custom privacy detectors ownership: float // Admin key, multisig, timelock, proxy liquidity: float // Protocol-level TVL via DefiLlama audit: float // Audit tier, recency, unresolved findings compliance: float // OFAC SDN + DeFiHackLabs exploit screening governance: float // v1.0: static 50.0 } details: object // per-dimension raw data (findings, TVL, etc.) scored_at: string // ISO 8601 timestamp cached: boolean // true if served from Redis cache }