Skip to content

Allowance Guard API v1 Reference

A RESTful API for retrieving token allowance and risk data for any Ethereum address. All endpoints are public and read-only. Data is indexed from the blockchain and updated continuously.

Quick Start

Base URL

https://www.allowanceguard.com/api

Authentication

Currently, the API is public and does not require an API key. For high-volume or production use cases, please contact us to request a key for rate limiting purposes.

Rate Limits

Public requests are limited to 5 requests per minute per IP address. For higher limits, use an API key.

Headers

Accept: application/json
Content-Type: application/json

Code Example

curl -X GET "https://www.allowanceguard.com/api/allowances?wallet=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&page=1&pageSize=25" \
  -H "Accept: application/json"

Endpoints

GET /allowances

Retrieves a paginated list of token allowances for a given address.

Parameters

ParameterTypeRequiredDescription
walletstringYesEthereum address (0x format)
pagenumberNoPage number (default: 1)
pageSizenumberNoResults per page (default: 25, max: 100)
riskOnlybooleanNoFilter to risky allowances only (default: false)

Response Body

{
  "allowances": [
    {
      "chain_id": 1,
      "token_address": "0xa0b86a33e6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6",
      "spender_address": "0xb1c97d44e7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d",
      "standard": "ERC20",
      "allowance_type": "per-token",
      "amount": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
      "is_unlimited": true,
      "last_seen_block": "18500000",
      "risk_score": 50,
      "risk_flags": ["UNLIMITED"],
      "token_name": "USD Coin",
      "token_symbol": "USDC",
      "token_decimals": 6,
      "spender_label": "Uniswap V3 Router",
      "spender_trust": "verified"
    }
  ],
  "page": 1,
  "pageSize": 25,
  "total": 42
}

Example Request

curl -X GET "https://www.allowanceguard.com/api/allowances?wallet=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&page=1&pageSize=25&riskOnly=true" \
  -H "Accept: application/json"

GET /receipts

Retrieves revocation receipts for a given wallet address.

Parameters

ParameterTypeRequiredDescription
walletstringYesEthereum address (0x format)
limitnumberNoNumber of receipts to return (default: 50, max: 100)

Response Body

{
  "receipts": [
    {
      "id": 123,
      "chain_id": 1,
      "token_address": "0xa0b86a33e6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6",
      "spender_address": "0xb1c97d44e7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d",
      "standard": "ERC20",
      "allowance_type": "per-token",
      "pre_amount": "1000000000000000000",
      "post_amount": "0",
      "tx_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "status": "verified",
      "error": null,
      "created_at": "2024-01-15T10:30:00Z",
      "verified_at": "2024-01-15T10:31:00Z"
    }
  ]
}

POST /scan

Triggers a blockchain scan for a wallet address across specified chains.

Request Body

{
  "walletAddress": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  "chains": ["eth", "arb", "base"]
}

Response Body

{
  "ok": true,
  "jobId": 456,
  "message": "Scan queued for 0xd8da6bf26964af9d7eed9e03e53415d37aa96045"
}

GET /jobs/{id}

Retrieves the status of a scan job.

Response Body

{
  "id": 456,
  "type": "scan",
  "status": "succeeded",
  "attempts": 1,
  "created_at": "2024-01-15T10:30:00Z",
  "started_at": "2024-01-15T10:30:05Z",
  "finished_at": "2024-01-15T10:32:00Z",
  "error": null
}

Data Types

Risk Level Enum

Risk assessment is based on the risk_score field and risk_flags array.

High Risk (score ≥ 50)

Unlimited allowances that pose immediate security risk. These allow complete drainage of token balances.

Medium Risk (score ≥ 10)

Stale allowances that have not been used for extended periods (90+ days). May indicate forgotten permissions.

Low Risk (score < 10)

Recent, limited allowances that are likely safe and actively used.

Chain ID Enum

Chain IDNetworkStatus
1Ethereum MainnetSupported
42161Arbitrum OneSupported
8453BaseSupported

Risk Flags

UNLIMITED

The allowance amount equals the maximum uint256 value, giving unlimited access to the token.

STALE

The allowance was last seen more than 90 days ago (650,000 blocks on Ethereum, 900,000 blocks on Arbitrum/Base).

Advanced

Data Freshness

Our indexer runs continuously. The last_seen_block field provides the block number when the allowance was last observed. For most addresses, data is no older than 5 minutes.

Error Codes

CodeDescriptionCause
400Bad RequestInvalid address format
404Not FoundAddress has no allowances
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer-side error

Using the Risk Data

The risk_flags array provides specific reasons for the risk score. Use these flags to build informative UI for your users. For example, display "Unlimited allowance" for UNLIMITED flag or "Stale allowance (90+ days)" for STALE flag.

Example Implementation

A step-by-step guide to building a simple integration.

Step 1: Fetch Allowances

async function fetchAllowances(walletAddress) {
  const response = await fetch(
    `https://www.allowanceguard.com/api/allowances?wallet=${walletAddress}&page=1&pageSize=100`
  );
  const data = await response.json();
  return data.allowances;
}

Step 2: Display Data

function renderAllowances(allowances) {
  return allowances.map(allowance => {
    const riskLevel = allowance.risk_score >= 50 ? 'high' : 
                     allowance.risk_score >= 10 ? 'medium' : 'low';
    
    return (
      <div key={`${allowance.token_address}-${allowance.spender_address}`}>
        <h3>{allowance.token_symbol} → {allowance.spender_label}</h3>
        <p>Amount: {allowance.is_unlimited ? 'Unlimited' : allowance.amount}</p>
        <p className={`risk-${riskLevel}`}>
          Risk: {riskLevel} ({allowance.risk_flags.join(', ')})
        </p>
      </div>
    );
  });
}

Step 3: Facilitate Action

async function revokeAllowance(tokenAddress, spenderAddress, signer) {
  const tokenContract = new ethers.Contract(tokenAddress, [
    'function approve(address spender, uint256 amount) returns (bool)'
  ], signer);
  
  const tx = await tokenContract.approve(spenderAddress, 0);
  await tx.wait();
  
  return tx.hash;
}