Skip to main content
Choose a block before a query starts, reuse its hash for every state read, and return that identity with the result. This keeps proxy discovery, Multicall, and dependent calls on the same state as providers and regions change. Turn Block regression protection On in your custom profile’s chain settings to protect later block choices, with progress shared automatically across the fleet. See Block regression protection for the scope, recovery limits and freshness bound.

1. Choose a block once

Send this standard JSON-RPC request to your profile endpoint:
Keep result.number and result.hash. A null result or error means the query cannot start. If you already have a target, select it as follows: Resolve a number only once per query. Resolving it separately for each read can select different hashes across a reorg. An explicit historical target remains valid even when it is below the profile’s latest floor.

2. Reuse the hash for every read

Pass this object in the method’s existing block parameter:
The example below uses your client’s standard request({ method, params }) operation. Addresses, calldata, and decoding functions belong to your application. block is the block object selected in step 1.
Hash selectors are supported for eth_call, eth_getBalance, eth_getCode, eth_getStorageAt, eth_getTransactionCount, and eth_getProof. Storage and proof reads take the selector as their third parameter; the others take it as their second. See EIP-1898. Apply the selector before any discovery starts. Carry it into direct-call fallbacks, every Multicall chunk, and background workers. Scope cached state and proxy-resolution results to the chain and block hash. A JSON-RPC batch, connection, or shared API key cannot supply that query boundary for you. For a simpler account view, use the same selector for eth_getBalance and eth_getCode. For a historical query, use the hash resolved from your chosen number; the pool must include a provider with the required state history.

3. Return results with evidence

Use your usual profile URL with header metadata enabled:
Authenticate with x-lasso-api-key. At your HTTP transport, capture the following for block selection and each state request: A successful protected latest choice’s head_policy includes the number, hash, age, scope and serving instance. With protection On, policy=local adds the application generation, captured floor and best-effort recovery hint. Existing strict configurations report policy=global and can include attributed chain-change observations; their retained block responses have no executing upstream provider. State responses record routing evidence, but their scalar results do not independently attest which block executed. Explicit-number/hash selection can legitimately have no head_policy object. See routing evidence. Retain service_profile_id to check that responses belong to the same service profile. profile_id records the effective routing profile and can change during configured profile fallback. Both IDs are opaque. Aggregate the records in your application. For example, your query API can return this shape while each underlying Ethereum response stays standard:
Use individual HTTP RPC responses or on-chain Multicall to collect evidence for every operation. One HTTP batch exposes only one item’s routing metadata; oversized metadata can be omitted. Mark evidence incomplete when any record is missing, or fail the query if complete evidence is required.

Handle an interrupted query

A restarted query must not reuse state-derived discovery or cached values from the abandoned block. Never combine partial results from different hashes. Applications that need finality should choose a finalized block before reading; a successful tip query can still be affected by a later reorg.