Technical Overview

This document lists every REST endpoint exposed by the ZigScan API along with authentication requirements, query parameters, and example payloads. The service is implemented with NestJS/Express and most endpoints proxy ClickHouse or Cosmos SDK data sources.

Base URL & Authentication

  • Default base URL: http://localhost:8000
  • API version prefix: /api/v2
  • Auth for data endpoints: API key header Authorization: Bearer <api-key>
  • Global throttle: 10 req / 60s per IP (Nest Throttler)
  • Per-key limit: 100 req / 60s per API key (non-admin)
  • Admin endpoints require an API key with role ADMIN.
  • Responses are JSON. Unless otherwise noted, successful calls return HTTP 200 OK; authentication failures return 401/403, validation errors 400, and upstream failures 5xx.

Example:

curl -H "Authorization: Bearer ${ZIGSCAN_API_KEY}" \
  http://localhost:8000/api/v2/health

Conventions

  • Pagination parameters use limit and offset. Unless a DTO states otherwise, limit defaults to 50 and offset to 0.
  • Date/time fields are returned as ISO 8601 strings.
  • ClickHouse-backed lists return an object with data and total_count.

Root Endpoint

MethodPathAuthDescription
GET/noneReturns service metadata (name/version).

Example response:

{
  "name": "ZIGScan API",
  "version": "1.2.0"
}

Core Service ( /api/v2 )

Health & General Stats

MethodPathAuthDescription
GET/api/v2/healthnoneHealth check plus ClickHouse status.
GET/api/v2/statsAPI keyAggregated chain stats (blocks, tx count).

GET /api/v2/health example:

{
  "status": "healthy",
  "service": "ZigScan API",
  "database": "ok",
  "database_error": null
}

Transactions

MethodPathAuthDescription
GET/api/v2/transactions/latestAPI keyLatest transactions with action type and signer. Supports filtering by action type and date range.
GET/api/v2/transactions/statsAPI keyAggregate transaction counts (7/15/30 days, TPS, hourly histogram).
GET/api/v2/transactions/message-typesAPI keyLists all message types with transaction counts, ordered by frequency.
GET/api/v2/transaction/:txHashAPI keyFetches raw transaction data from the chain RPC. Returns 404 if not found.

Query parameters for /transactions/latest :

NameTypeDefaultNotes
limitinteger (0–100)10Max records.
offsetinteger (0–100)0Skip records.
actionstringnoneFilter by action type (e.g., /cosmos.bank.v1beta1.MsgSend). Supports wildcards (%).
startDatestring (ISO 8601)noneStart date for filtering (e.g., 2025-10-01T00:00:00).
endDatestring (ISO 8601)noneEnd date for filtering (e.g., 2025-10-15T00:00:00).
heightWindowinteger (1–100000)1000Number of blocks to look back from the latest height (limits query scope).
beforeHeightinteger (>=1)noneHeight of the last transaction on the previous page; the next call returns entries strictly older than this height within the requested window (useful for paging back).

Example response (latest):

{
  "data": [
    {
      "height": 2885826,
      "tx_hash": "38E8...",
      "action_type": "/cosmos.bank.v1beta1.MsgSend",
      "status": 0,
      "signer": "zig1...",
      "created_at": "2025-10-10T14:04:46.591Z"
    }
  ],
  "total_count": 10
}

Example response (stats):

{
  "tx_total": 1234567,
  "tx_last_30d": 43210,
  "tx_last_15d": 21000,
  "tx_last_7d": 10500,
  "tps_all_time": 2.31,
  "true_tps_all_time": 0.54,
  "hourly_txns": {
    "2025-05-01 12:00:00": 145,
    "2025-05-01 13:00:00": 132
  }
}

Example response (message-types):

{
  "data": [
    {
      "transaction_type": "/cosmos.bank.v1beta1.MsgSend",
      "transaction_count": 125678
    },
    {
      "transaction_type": "/cosmos.staking.v1beta1.MsgDelegate",
      "transaction_count": 89234
    },
    {
      "transaction_type": "/cosmwasm.wasm.v1.MsgExecuteContract",
      "transaction_count": 45123
    },
    {
      "transaction_type": "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
      "transaction_count": 34567
    }
  ],
  "total_types": 42
}

GET /api/v2/transaction/:txHash mirrors the Cosmos /cosmos/tx/v1beta1/txs/{txHash} payload (minus tx_response.tx to reduce size).

Blocks

MethodPathAuthDescription
GET/api/v2/blocksAPI keyPaginated block minting snapshots with validator rewards.
GET/api/v2/blocks/statsAPI keyAverage/min block times, average tx count, daily block counts.
GET/api/v2/blocks/details/:heightAPI keyFull block metadata pulled from the chain RPC.
GET/api/v2/blocks/transactions/:heightAPI keyTransactions for a specific block.

Query parameters:

  • /blocks : limit (1–1000, default 10), offset (default 0)
  • /blocks/stats : days (1–365, default 30)

Example response ( /blocks ):

{
  "data": [
    {
      "height": 2885826,
      "created_at": "2025-10-10T14:04:46.591Z",
      "txs_results_count": 12,
      "minter": "zigvaloper1...",
      "inflation": 0.15,
      "validator_rewards": [
        {
          "validator_address": "zigvaloper1...",
          "reward_amount": "12345uzig"
        }
      ]
    }
  ],
  "total_count": 10
}

Example response ( /blocks/stats ):

{
  "avg_block_time_seconds": 6.1,
  "min_block_time_seconds": 4.2,
  "avg_txs_per_block": 9.8,
  "blocks_per_day": {
    "2025-04-30": 1432,
    "2025-05-01": 1440
  }
}

/blocks/details/:height returns the raw Tendermint block ( block , block_id , sdk_block ) from the ZigChain RPC.

Contracts & Codes

MethodPathAuthDescription
GET/api/v2/contractsAPI keyContract instantiations with filters.
GET/api/v2/contract/debug/:contractAddressAPI keyRaw instantiate event payloads for debugging.
GET/api/v2/contract/details/:contractAddressAPI keyFetches on-chain contract metadata.
GET/api/v2/contract/transactions/:contractAddressAPI keyContract executions involving the address (paginated).
GET/api/v2/codesAPI keyCode storage events with filters.
GET/api/v2/code/details/:codeIDAPI keyCode info and associated contracts.

Shared pagination ( /contracts , /contract/transactions , /codes ): limit (1–1000), offset (0+) default 50/0 via PaginationQueryDto .

Additional filters:

  • /contracts :
    • contract_address , sender , code_id (strings)
    • height_min , height_max (ints ≥ 1; height_min height_max )
  • /codes :
    • sender , code_id
    • height_min , height_max

Example response ( /contracts ):

{
  "data": [
    {
      "height": 2879000,
      "tx_hash": "A1B2...",
      "created_at": "2025-10-08T11:22:33.000Z",
      "code_id": "47",
      "sender": "zig1...",
      "contract_address": "zig1contract..."
    }
  ],
  "total_count": 50
}

/contract/debug/:contractAddress returns:

{
  "debug_data": [
    {
      "height": 2879000,
      "tx_hash": "A1B2...",
      "attrs_map": { "...": "..." },
      "available_keys": ["_contract_address", "sender", "code_id"]
    }
  ]
}

/contract/details/:contractAddress mirrors /cosmwasm/wasm/v1/contract/{address} .

/contract/transactions/:contractAddress returns { data: ContractTransaction[], total_count: number } with the same schema as account transactions.

/code/details/:codeId combines:

{
  "code_info": {
    "code_id": "47",
    "creator": "zig1...",
    "instantiate_permission": { "...": "..." }
  },
  "contracts": {
    "contracts": ["zig1...", "zig1..."],
    "pagination": { "next_key": null, "total": "2" }
  }
}

Accounts

MethodPathAuthDescription
GET/api/v2/account/details/:addressAPI keyAccount info plus balances grouped by token type, plus transaction totals and creation metadata.
GET/api/v2/account/delegations/:addressAPI keyActive delegations with total count and pagination cursor.
GET/api/v2/account/transactions/:addressAPI keyRecent transactions where the address appears as sender/recipient/fee payer.
GET/api/v2/account/token-metadataAPI keyMetadata for native/factory/CW20/IBC tokens (symbol, decimals, icon, etc.).
GET/api/v2/accounts/totalAPI keyTotal number of accounts (via Cosmos pagination metadata).

Notes:

  • :address must start with zig1 ; contract ( zig1 + > 50 chars) or zigvaloper addresses are rejected with 400 .
  • Balances group tokens into factory , cw20 , and IBC . Metadata includes symbol , decimals , and image_url .
  • /account/delegations returns { delegation_responses: DelegationResponse[], pagination: { next_key, total } } ; empty delegations yield an empty array with total 0 .
  • /account/transactions enforces pagination and clamps limit to 1–1000.

Query parameters for /account/transactions/:address :

NameTypeDefaultNotes
limitinteger (1–1000)50Maximum records per page.
offsetinteger (0+)0Number of records to skip.

Example ( /account/details ):

{
  "account_info": {
    "address": "zig1abcd...",
    "account_number": "12345",
    "sequence": "7",
    "pub_key": { "type_url": "...", "value": "..." }
  },
  "balance": {
    "factory": [
      {
        "denom": "uzig",
        "amount": "123456789",
        "metadata": {
          "name": "ZIG",
          "symbol": "ZIG",
          "decimals": 6,
          "image_url": "https://..."
        }
      }
    ],
    "cw20": null,
    "IBC": null
  },
  "total_transactions": 123,
  "first_block_height": 123456,
  "account_creation_time": "2025-10-01T12:34:56.000Z"
}

/account/token-metadata accepts a denom query parameter and returns the resolved metadata:

Example request:

Example response:

{
  "denom": "coin.zig109f7g2rzl2aqee7z6gffn8kfe9cpqx0mjkk7ethmx8m2hq4xpe9snmaam2.stzig",
  "metadata": {
    "name": "STZIG",
    "symbol": "STZIG",
    "description": "Factory token: STZIG",
    "decimals": 6,
    "image_url": "https://raw.githubusercontent.com/..."
  }
}
  • total_transactions counts every row in public_address_transactions for the address.
  • first_block_height is the earliest height in that table.
  • account_creation_time is the corresponding block time (all sourced from ClickHouse).

/accounts/total example:

{ "total": 98765 }

/account/delegations mirrors the Cosmos staking delegation response and always includes a pagination object. /account/transactions returns { data: AccountTransaction[], total_count: number } sorted by height DESC.

Validators

MethodPathAuthDescription
GET/api/v2/validatorsAPI keyLists validators (default bonded). Enriches with Keybase avatar.
GET/api/v2/validator/details/:validatorAddressAPI keyFetch single validator; returns 404 if not found.

Query parameters:

NameTypeDefaultNotes
statusstringBOND_STATUS_BONDEDAny Cosmos staking status.
limitinteger (1–1000)50
offsetinteger (0+)0

Example list response:

{
  "data": [
    {
      "operator_address": "zigvaloper1...",
      "description": { "moniker": "Validator 1", "identity": "12345" },
      "commission": { "commission_rates": { "rate": "0.050000000000000000" } },
      "status": "BOND_STATUS_BONDED",
      "tokens": "1234567890",
      "delegator_shares": "1234567890.000000000000000000",
      "jailed": false,
      "consensus_pubkey": { "@type": "...", "key": "..." },
      "min_self_delegation": "1",
      "keybase_image_url": "https://keybase.io/..."
    }
  ],
  "total_count": 50
}

Supply & Market Data

MethodPathAuthDescription
GET/api/v2/supplyAPI keyOn-chain supply plus derived circulating/non-circulating.
GET/api/v2/zig/market-dataAPI keyCurrent price/volume metrics from CoinGecko.
GET/api/v2/zig/staking-poolAPI keyBonded vs non-bonded staking pool balances.
GET/api/v2/zig/price-dataAPI keyHistorical price/volume chart data.

/zig/price-data query parameter:

NameTypeDefaultNotes
daysstring24hrPassed directly to CoinGecko (e.g. 7 , 30 , 90 , 1 , 7d ).

Example ( /supply ):

{
  "denom": "uzig",
  "amountMicro": "987654321000000",
  "amount": "987654.321",
  "circulatingSupply": 912345.67,
  "nonCirculatingSupply": 75308.651
}

Example ( /zig/market-data ):

{
  "name": "ZigChain",
  "symbol": "ZIG",
  "current_price": 0.12,
  "price_change_24h": 0.005,
  "price_change_7d": 0.02,
  "price_change_30d": -0.01,
  "price_change_90d": 0.11,
  "circulating_supply": 912345.67,
  "nonCirculatingSupply": 75308.651,
  "total_supply": 987654.321,
  "max_supply": null,
  "market_cap": 109481.48,
  "total_volume": 5321.77,
  "image": "https://assets.coingecko.com/.../zig.png"
}

/zig/price-data returns CoinGecko chart arrays:

{
  "prices": [[1714543200000, 0.12], [1714546800000, 0.118]],
  "market_caps": [[1714543200000, 105000]],
  "total_volumes": [[1714543200000, 3200]]
}

Example ( /zig/staking-pool ):

{
  "bondedTokensMicro": "123456789000000",
  "bondedTokens": "123456.789",
  "notBondedTokensMicro": "98765432100000",
  "notBondedTokens": "98.765432"
}

TVL

MethodPathAuthDescription
GET/api/v2/tvlAPI keyLatest TVL snapshot plus 30-day history aggregated by entity.

Response example:

{
  "latest": {
    "total_tvl": 123456.78,
    "valdora_staking": 45678.9,
    "oroswap": 23456.78,
    "permapod_red_bank": 12345.67,
    "nawa_vaults": 5432.1,
    "timestamp": "2025-10-12T08:00:00.000Z"
  },
  "history": [
     { "total_tvl": 120000.11, "valdora_staking": 45000, "oroswap": 22000, "permapod_red_bank": 12000, "nawa_vaults": 5000, "timestamp": "2025-10-11T08:00:00.000Z" }
  ]
}
  ]
}

Network

MethodPathAuthDescription
GET/api/v2/network/overviewAPI keyChain overview (heights, TPS, staking, validator totals) with caching.

Response mirrors NetworkOverview from NetworkService (heights, tx totals, staking pool, validator counts).

DeFi (Degenter Proxy)

All DeFi endpoints proxy DEGENTER_API responses. Authentication still uses ZigScan API keys.

MethodPathAuthDescription
GET/api/v2/tokensAPI keyLists Degenter tokens. Supports sorting.
GET/api/v2/tokens/details/:denomAPI keyToken profile, social links, and metrics.
GET/api/v2/tokens/:denom/poolsAPI keyPools for a token.
GET/api/v2/tokens/:denom/holdersAPI keyToken holders list.
GET/api/v2/tokens/:denom/ohlcvAPI keyOHLCV candles (default timeframe set by Degenter).
GET/api/v2/pools/:poolId/tradesAPI keyTrades for a pool.

Query parameters:

  • /tokens : limit , offset , sort , dir
  • /tokens/:denom/holders : limit , offset
  • /pools/:poolId/trades : limit (default 50), offset (default 0), unit ( usd by default), tf ( 24h by default)
  • /tokens/:denom/ohlcv : no additional query params; interval configured server-side.

Sample /tokens response:

{
  "success": true,
  "data": [
    {
      "tokenId": "123",
      "denom": "coin.xyz",
      "symbol": "XYZ",
      "name": "XYZ Token",
      "imageUri": "https://...",
      "createdAt": "2024-11-01T00:00:00.000Z",
      "priceNative": 1.23,
      "priceUsd": 0.12,
      "mcapUsd": 500000,
      "holders": 1234,
      "volUsd": 23000,
      "tx": 450
    }
  ],
  "meta": {
    "limit": 25,
    "offset": 0,
    "total": 142
  }
}

/tokens/details/:denom returns the Degenter token profile ( success , data with metadata, liquidity, price change buckets).

/tokens/:denom/ohlcv response example:

{
  "success": true,
  "data": [
    { "ts_sec": 1714543200, "open": 0.12, "high": 0.125, "low": 0.118, "close": 0.123, "volume": 5321.7 }
  ],
  "meta": { "tf": "5m", "unit": "usd", "priceSource": "degenter" }
}

/pools/:poolId/trades response example:

{
  "success": true,
  "data": [
    {
      "time": "2025-05-01T12:34:56Z",
      "txHash": "ABC123...",
      "pairContract": "zig1pool...",
      "signer": "zig1...",
      "direction": "buy",
      "offerDenom": "uzig",
      "offerAmount": 100,
      "askDenom": "coin.xyz",
      "returnAmount": 2500,
      "priceUsd": 0.12,
      "valueUsd": 12.5
    }
  ],
  "meta": { "limit": 50, "offset": 0, "unit": "usd", "tf": "24h", "total": 1000 }
}

Memes.fun (MDF)

MethodPathAuthDescription
GET/api/v2/mdf/coinsAPI keyPaginated Memes.fun coin feed.

Query params: page (default 1, min 1), limit (default 10, max 100). Uses MEMES_FUN_API_BASE_URL + MEMES_FUN_API_KEY .

Response shape mirrors the upstream MemesDotFunCoinsResponse with success , data , and pagination meta.

Saved Items (JWT)

All saved-items routes require a user JWT ( Authorization: Bearer <accessToken> ).

MethodPathAuthDescription
POST/api/v2/saved-itemsJWTSave an item ( itemSaved , optional itemType ).
GET/api/v2/saved-itemsJWTList saved items with limit , offset , optional itemType .
GET/api/v2/saved-items/statsJWTTotals grouped by itemType .
GET/api/v2/saved-items/check/:itemSavedJWTReturns { itemSaved, isSaved } .
GET/api/v2/saved-items/:idJWTFetch a saved item by id.
DELETE/api/v2/saved-items/:idJWTDelete a saved item.
DELETE/api/v2/saved-itemsJWTDelete all saved items for the user.

List response example:

{
  "items": [{ "id": "1", "itemSaved": "zig1...", "itemType": "contract", "createdAt": "..." }],
  "total": 1,
  "limit": 20,
  "offset": 0
}

Metrics

MethodPathAuthDescription
GET/metricsAdmin API keyPrometheus metrics (HTTP counters/histograms, API key usage, ClickHouse failures, SSH tunnel status).

Content-Type: text/plain; version=0.0.4 . Cached by Prometheus scrape interval only.

Error Handling Reference

  • 400 Bad Request – validation failures (e.g., invalid address format, height_min > height_max , non-SELECT query).
  • 401 Unauthorized – missing/invalid bearer token.
  • 403 Forbidden – admin guard rejection or admin window inactive.
  • 404 Not Found – missing on-chain resources (transactions, validators).
  • 502/504 – upstream APIs (Cosmos, CoinGecko, Degenter) not reachable.

When proxied services return errors, the ZigScan API wraps them as:

{ "error": "message" }

with the relevant HTTP status.

Testing & Tooling

  • Use the included rest-client.http or the Postman collection in docs/zigscan-postman.collection.json (see docs/POSTMAN.md ) for manual exploration.
  • For ClickHouse-heavy workflows, prefer scoped SELECT queries with explicit LIMIT s to minimize response sizes.