Skip to main content

Error Handling

All API errors return a consistent JSON structure with an appropriate HTTP status code.

Error Format

{
"error": "Human-readable error message",
"details": "Additional context (optional)"
}

HTTP Status Codes

CodeMeaningWhen
400Bad RequestValidation failure, malformed JSON, missing required fields
401UnauthorizedMissing or invalid JWT token
403ForbiddenInsufficient permissions (e.g., Free tier accessing webhooks)
404Not FoundResource does not exist (DID, dispute, webhook)
409ConflictDuplicate resource (e.g., DID already registered for address)
429Too Many RequestsRate limit exceeded for your API tier
500Internal Server ErrorUnexpected server error

Common Errors

Invalid Ethereum Address

400 Bad Request
{
"error": "Invalid Ethereum address format",
"details": "Address must start with 0x followed by 40 hexadecimal characters"
}

Rate Limit Exceeded

429 Too Many Requests
{
"error": "Rate limit exceeded",
"details": "Free tier allows 10 requests per second. Upgrade at /api/v1/billing/checkout"
}

Response includes a Retry-After header indicating seconds until the next request will be accepted.

Monthly Query Limit

429 Too Many Requests
{
"error": "Monthly query limit exceeded",
"details": "Free tier allows 100 queries per month. Current usage: 100/100"
}

Webhook Tier Restriction

403 Forbidden
{
"error": "Webhooks are not available on the Free tier"
}

DID Not Found

404 Not Found
{
"error": "DID not found"
}

Invalid Proof

400 Bad Request
{
"error": "Invalid proof",
"details": "Proof verification failed: invalid encoding"
}

Handling Errors in SDKs

All CrowdProof SDKs throw typed exceptions:

import { CrowdProof, CrowdProofError } from '@crowdproof/sdk';

try {
const score = await client.getScore('0x1234...', 'DEFI_LENDING');
} catch (err) {
if (err instanceof CrowdProofError) {
console.error(`API error ${err.status}: ${err.message}`);
if (err.status === 429) {
// Back off and retry
await sleep(err.retryAfter * 1000);
}
}
}
from crowdproof import CrowdProofClient, CrowdProofError

try:
score = client.get_score("0x1234...", "DEFI_LENDING")
except CrowdProofError as e:
print(f"API error {e.status}: {e.message}")

Best Practices

  1. Always check HTTP status before parsing the response body
  2. Implement exponential backoff for 429 responses
  3. Log the full error including details for debugging
  4. Don't retry 400/403/404 — fix the request instead
  5. Monitor 500 errors — report persistent server errors to support