{
  "openapi": "3.1.0",
  "info": {
    "title": "Tokenistry EVM Indexer",
    "description": "Configurable EVM log indexing service. Contracts and events are configuration, decoding is dynamic, and events are served in blockchain order with cursor pagination plus an SSE live stream.",
    "license": {
      "name": "LicenseRef-Tokenistry-Commercial",
      "identifier": "LicenseRef-Tokenistry-Commercial"
    },
    "version": "1.0.0"
  },
  "paths": {
    "/health": {
      "get": {
        "tags": [
          "system"
        ],
        "summary": "Liveness and database reachability.",
        "operationId": "health",
        "responses": {
          "200": {
            "description": "Service and database are reachable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          },
          "500": {
            "description": "The database is unreachable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contracts": {
      "get": {
        "tags": [
          "contracts"
        ],
        "summary": "List contracts, optionally for one network.",
        "operationId": "list_contracts",
        "parameters": [
          {
            "name": "network_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configured contracts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ContractResponse"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "contracts"
        ],
        "summary": "Register a contract to watch.",
        "operationId": "create_contract",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContractRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Contract registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid address or duplicate contract",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Unknown network",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contracts/{id}": {
      "get": {
        "tags": [
          "contracts"
        ],
        "summary": "Fetch one contract.",
        "operationId": "get_contract",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Contract id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contract",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown contract",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "contracts"
        ],
        "summary": "Delete a contract, its subscriptions and their decoded events.",
        "description": "The raw logs stay: they belong to the network, so re-registering the same\ncontract can be rebuilt with a re-decode instead of refetching from the\nprovider.",
        "operationId": "delete_contract",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Contract id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Contract, subscriptions and events deleted"
          },
          "404": {
            "description": "Unknown contract",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contracts/{id}/reindex": {
      "post": {
        "tags": [
          "status"
        ],
        "summary": "Reprocess history for a contract.",
        "description": "`refetch` rewinds the watermarks so the range is fetched from the provider\nagain. `redecode` rebuilds decoded events straight from stored raw logs and\nmakes no RPC calls at all, which is the repair path after an ABI fix.\nBoth are idempotent: rows are upserted on their blockchain key.",
        "operationId": "reindex",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Contract id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReindexRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Reindex accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReindexResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown contract or subscription",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contracts/{id}/status": {
      "get": {
        "tags": [
          "status"
        ],
        "summary": "Sync status for a contract.",
        "description": "Completeness is tracked per subscription; the contract level figures are\nderived from them, and `covered_ranges` shows gaps honestly rather than\nimplying a single watermark tells the whole story.",
        "operationId": "contract_status",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Contract id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Per-subscription sync status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractStatusResponse"
                }
              }
            }
          },
          "404": {
            "description": "Unknown contract",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contracts/{id}/subscriptions": {
      "get": {
        "tags": [
          "subscriptions"
        ],
        "summary": "List the contract's event subscriptions.",
        "operationId": "list_subscriptions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Contract id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Subscriptions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SubscriptionResponse"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Unknown contract",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Subscribe to one of the contract's events.",
        "description": "Supply either a human readable `signature` or a JSON `abi` item. The resolved\nABI is stored with the subscription, which is why no event definition is\ncompiled into the service.",
        "operationId": "create_subscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Contract id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubscriptionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Subscription created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid ABI, signature or duplicate event",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Unknown contract",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contracts/{id}/subscriptions/{subscription_id}": {
      "delete": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Delete one subscription, with its coverage and decoded events.",
        "description": "The contract's raw logs stay, so the same event can be re-subscribed and\nrebuilt with a re-decode and no RPC calls.",
        "operationId": "delete_subscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Contract id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "subscription_id",
            "in": "path",
            "description": "Subscription id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Subscription and its events deleted"
          },
          "404": {
            "description": "Unknown contract or subscription",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "tags": [
          "events"
        ],
        "summary": "Read canonical events in blockchain order.",
        "description": "Pagination is a keyset scan on `(block_number, transaction_index, log_index)`,\nso a consumer can store `next_cursor`, disconnect, reconnect and continue with\nno gaps and no duplicates, or replay everything from block 0 to rebuild its own\nderived state. Events orphaned by a reorg are never returned.",
        "operationId": "list_events",
        "parameters": [
          {
            "name": "network_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "contract",
            "in": "query",
            "description": "Contract id filter.",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "subscription_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "event",
            "in": "query",
            "description": "Event name filter, for example `Transfer`.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "in": "query",
            "description": "Contract address filter, `0x`-prefixed.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from_block",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "to_block",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "minimum": 0
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Return only events strictly after this cursor.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "1..=1000, defaults to 100.",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of events in blockchain order",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventPageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid cursor, address or limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/stream": {
      "get": {
        "tags": [
          "events"
        ],
        "summary": "Stream newly committed events.",
        "description": "Each frame's `id` is the blockchain position (`block-txIndex-logIndex`) and the\npayload is the same object `GET /v1/events` returns, including its `cursor`.",
        "operationId": "stream_events",
        "parameters": [
          {
            "name": "network_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "contract",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "subscription_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "event",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A text/event-stream of committed events",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/v1/metrics": {
      "get": {
        "tags": [
          "system"
        ],
        "summary": "RPC efficiency and indexing lag.",
        "description": "`blocks_scanned_per_rpc_request` and `logs_returned_per_rpc_request` are the\nnumbers that show whether address, topic and block bucketing are paying off.",
        "operationId": "metrics",
        "responses": {
          "200": {
            "description": "Counters and derived efficiency ratios",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/networks": {
      "get": {
        "tags": [
          "networks"
        ],
        "summary": "List configured networks and their chain head.",
        "operationId": "list_networks",
        "responses": {
          "200": {
            "description": "Configured networks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/NetworkResponse"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "networks"
        ],
        "summary": "Register a network.",
        "description": "The supervisor picks it up immediately, so indexing starts as soon as\ncontracts and subscriptions exist.",
        "operationId": "create_network",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateNetworkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Network registered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input or duplicate name",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The installed licence does not entitle this chain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/networks/{id}": {
      "delete": {
        "tags": [
          "networks"
        ],
        "summary": "Delete a network and everything indexed for it.",
        "description": "This cascades to the network's contracts, subscriptions, coverage, raw logs\nand events, and its worker is stopped as soon as the supervisor reconciles.\nDestructive on purpose: to stop indexing but keep the data, disable instead.",
        "operationId": "delete_network",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Network id",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Network and all its indexed data deleted"
          },
          "404": {
            "description": "Unknown network",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "BlockRangeResponse": {
        "type": "object",
        "required": [
          "from_block",
          "to_block"
        ],
        "properties": {
          "from_block": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "to_block": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          }
        }
      },
      "ContractResponse": {
        "type": "object",
        "required": [
          "id",
          "network_id",
          "address",
          "start_block",
          "enabled"
        ],
        "properties": {
          "address": {
            "type": "string"
          },
          "code_hash": {
            "type": [
              "string",
              "null"
            ],
            "description": "keccak256 of the runtime bytecode from `eth_getCode`."
          },
          "code_size": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "minimum": 0
          },
          "decimals": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32"
          },
          "enabled": {
            "type": "boolean"
          },
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "ERC-20 `name()`, when the contract answers that call."
          },
          "network_id": {
            "type": "integer",
            "format": "int64"
          },
          "start_block": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "symbol": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ContractStatusResponse": {
        "type": "object",
        "description": "Contract level status, derived from the enabled subscriptions rather than\nstored separately.",
        "required": [
          "contract_id",
          "network_id",
          "address",
          "confirmations",
          "subscriptions"
        ],
        "properties": {
          "address": {
            "type": "string"
          },
          "confirmations": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "contract_id": {
            "type": "integer",
            "format": "int64"
          },
          "head_block": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "minimum": 0
          },
          "lag_blocks": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "minimum": 0
          },
          "network_id": {
            "type": "integer",
            "format": "int64"
          },
          "subscriptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubscriptionStatusResponse"
            }
          },
          "synced_through": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Lowest watermark across enabled subscriptions, or null if any of them has\nproven nothing yet.",
            "minimum": 0
          }
        }
      },
      "CreateContractRequest": {
        "type": "object",
        "required": [
          "network_id",
          "address",
          "start_block"
        ],
        "properties": {
          "address": {
            "type": "string",
            "example": "0x5fbdb2315678afecb367f032d93f642f64180aa3"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "example": "TestToken"
          },
          "network_id": {
            "type": "integer",
            "format": "int64"
          },
          "start_block": {
            "type": "integer",
            "format": "int64",
            "description": "Deployment block. Nothing before it is ever fetched.",
            "minimum": 0
          }
        }
      },
      "CreateNetworkRequest": {
        "type": "object",
        "required": [
          "name",
          "chain_id",
          "http_url"
        ],
        "properties": {
          "chain_id": {
            "type": "integer",
            "format": "int64",
            "example": 31337,
            "minimum": 0
          },
          "confirmations": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Confirmation depth for this network. Defaults to `DEFAULT_CONFIRMATIONS`.",
            "example": 1,
            "minimum": 0
          },
          "http_url": {
            "type": "string",
            "example": "http://127.0.0.1:8545"
          },
          "name": {
            "type": "string",
            "example": "anvil"
          },
          "ws_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "WebSocket endpoint used for `newHeads`. Without it the worker falls back\nto polling.",
            "example": "ws://127.0.0.1:8545"
          }
        }
      },
      "CreateSubscriptionRequest": {
        "type": "object",
        "description": "Configure an event subscription. Supply either `signature` or `abi`; the\nresolved ABI item is stored so decoding never depends on compiled-in types.",
        "required": [
          "abi"
        ],
        "properties": {
          "abi": {
            "type": "object",
            "description": "A JSON ABI event item."
          },
          "event_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional cross-check against the ABI's event name.",
            "example": "Transfer"
          },
          "signature": {
            "type": [
              "string",
              "null"
            ],
            "example": "Transfer(address indexed from, address indexed to, uint256 value)"
          },
          "start_block": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Defaults to the contract's start block.",
            "minimum": 0
          },
          "topic0": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional getLogs topic0. Defaults to keccak of the ABI signature.\nSupply this when the event name is unknown but the on-chain topic is not.",
            "example": "0xd3d9e1a09064deb3c770a5fe297b1154653156dd30fe6570337ea0dd0eb6d326"
          }
        }
      },
      "ErrorBody": {
        "type": "object",
        "description": "Machine readable error envelope, identical for every failing endpoint.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        }
      },
      "ErrorDetail": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable, snake_case error code.",
            "example": "not_found"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "EventPageResponse": {
        "type": "object",
        "required": [
          "events",
          "has_more"
        ],
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventResponse"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor to resume from; `null` when the page is empty."
          },
          "next_position": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/PositionResponse",
                "description": "The same position in readable form."
              }
            ]
          }
        }
      },
      "EventResponse": {
        "type": "object",
        "required": [
          "id",
          "network_id",
          "contract_id",
          "subscription_id",
          "address",
          "event_name",
          "topic0",
          "block_number",
          "block_hash",
          "transaction_hash",
          "transaction_index",
          "log_index",
          "decoded",
          "position",
          "cursor"
        ],
        "properties": {
          "address": {
            "type": "string"
          },
          "block_hash": {
            "type": "string"
          },
          "block_number": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "contract_id": {
            "type": "integer",
            "format": "int64"
          },
          "cursor": {
            "type": "string",
            "description": "Cursor pointing *at* this event; pass it as `cursor` to resume after it."
          },
          "decoded": {
            "type": "object",
            "description": "Decoded parameters keyed by ABI name. `uint256` values are decimal\nstrings so no precision is lost in JSON."
          },
          "event_name": {
            "type": "string",
            "example": "Transfer"
          },
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "log_index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "network_id": {
            "type": "integer",
            "format": "int64"
          },
          "position": {
            "$ref": "#/components/schemas/PositionResponse"
          },
          "subscription_id": {
            "type": "integer",
            "format": "int64"
          },
          "topic0": {
            "type": "string"
          },
          "transaction_hash": {
            "type": "string"
          },
          "transaction_index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          }
        }
      },
      "HealthResponse": {
        "type": "object",
        "required": [
          "status",
          "database"
        ],
        "properties": {
          "database": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "example": "ok"
          }
        }
      },
      "NetworkResponse": {
        "type": "object",
        "required": [
          "id",
          "name",
          "chain_id",
          "http_url",
          "confirmations",
          "enabled"
        ],
        "properties": {
          "chain_id": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "confirmations": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "enabled": {
            "type": "boolean"
          },
          "head_block": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "minimum": 0
          },
          "head_block_hash": {
            "type": [
              "string",
              "null"
            ]
          },
          "http_url": {
            "type": "string"
          },
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          },
          "ws_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "PositionResponse": {
        "type": "object",
        "required": [
          "block_number",
          "transaction_index",
          "log_index"
        ],
        "properties": {
          "block_number": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "log_index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          },
          "transaction_index": {
            "type": "integer",
            "format": "int32",
            "minimum": 0
          }
        }
      },
      "ReindexMode": {
        "type": "string",
        "enum": [
          "refetch",
          "redecode"
        ]
      },
      "ReindexRequest": {
        "type": "object",
        "properties": {
          "from_block": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "First block to reprocess. Defaults to each subscription's start block.",
            "minimum": 0
          },
          "mode": {
            "$ref": "#/components/schemas/ReindexMode"
          },
          "subscription_id": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "Restrict to one subscription instead of all of the contract's."
          }
        }
      },
      "ReindexResponse": {
        "type": "object",
        "required": [
          "contract_id",
          "mode",
          "subscriptions"
        ],
        "properties": {
          "contract_id": {
            "type": "integer",
            "format": "int64"
          },
          "from_block": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "minimum": 0
          },
          "mode": {
            "$ref": "#/components/schemas/ReindexMode"
          },
          "subscriptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReindexSubscriptionResult"
            }
          }
        }
      },
      "ReindexSubscriptionResult": {
        "type": "object",
        "required": [
          "subscription_id"
        ],
        "properties": {
          "events_written": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "raw_logs_scanned": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "subscription_id": {
            "type": "integer",
            "format": "int64"
          },
          "synced_through": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "minimum": 0
          }
        }
      },
      "SubscriptionResponse": {
        "type": "object",
        "required": [
          "id",
          "contract_id",
          "event_name",
          "signature",
          "topic0",
          "start_block",
          "enabled",
          "abi"
        ],
        "properties": {
          "abi": {
            "type": "object"
          },
          "contract_id": {
            "type": "integer",
            "format": "int64"
          },
          "enabled": {
            "type": "boolean"
          },
          "event_name": {
            "type": "string"
          },
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "signature": {
            "type": "string"
          },
          "start_block": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "synced_through": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "End of the contiguous proven range starting at `start_block`.",
            "minimum": 0
          },
          "topic0": {
            "type": "string"
          }
        }
      },
      "SubscriptionStatusResponse": {
        "type": "object",
        "required": [
          "subscription_id",
          "event_name",
          "enabled",
          "start_block",
          "canonical_event_count",
          "covered_ranges"
        ],
        "properties": {
          "canonical_event_count": {
            "type": "integer",
            "format": "int64"
          },
          "covered_ranges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlockRangeResponse"
            },
            "description": "Proven, merged block ranges. Gaps here are the honest picture of a partly\nfailed backfill."
          },
          "enabled": {
            "type": "boolean"
          },
          "event_name": {
            "type": "string"
          },
          "start_block": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "subscription_id": {
            "type": "integer",
            "format": "int64"
          },
          "synced_through": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "minimum": 0
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "networks",
      "description": "EVM networks and their chain head"
    },
    {
      "name": "contracts",
      "description": "Contracts to watch"
    },
    {
      "name": "subscriptions",
      "description": "Per-contract event subscriptions, the unit of completeness"
    },
    {
      "name": "status",
      "description": "Sync status and reprocessing"
    },
    {
      "name": "events",
      "description": "Reading events: cursor pagination and live stream"
    },
    {
      "name": "system",
      "description": "Health and RPC efficiency metrics"
    }
  ]
}
