Skip to content

Quickstart

Fork mainnet at the current block, send a transaction against your private copy of it, and read the result back. Three requests, no local toolchain.

Before you start

You need an API key. Create one in the application at app.trilocore.ai under API keys; it looks like jns_…. Export it:

export TRILOCORE_API_KEY=jns_your_key_here

Everything below is https://api.trilocore.ai. See Authentication if you would rather drive the API with a browser session than a key.

1. Open a session

A session boots a private fork of the chain you name, pinned to a block, with the target contract loaded into scope.

curl -X POST https://api.trilocore.ai/api/v1/bevm/sessions \
  -H "Authorization: Bearer $TRILOCORE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "network": "eth",
        "rpc_url": "https://your-node.example/eth",
        "target_address": "0xYourTargetContract",
        "block": "latest"
      }'

The response opens the session and describes the fork it just built:

{
  "open": true,
  "session_id": "…",
  "fork_rpc": "http://127.0.0.1:…",
  "target": { "…": "…" },
  "target_balance_wei": 0,
  "auditor": "0x…",
  "chain_kind": "evm",
  "isolation_active": true,
  "durable": true
}

Two fields are worth knowing immediately. session_id identifies the fork for every later call. isolation_active says which way sends behave: with isolation on, each transaction is measured and then rolled back, so experiments do not contaminate each other. Turn it off — or send with "persist": true — to accumulate state across a sequence, which is what a multi-step reproduction needs. Both modes are explained in Core concepts.

The fork is yours

rpc_url is the upstream node the fork reads missing state from. Reads fall through to it; writes never do. The address in target_address is loaded into scope, and by default any contract hard-coded in its bytecode is pulled in alongside it.

2. Send a transaction

This is the core loop: one call against the fork, fully measured.

curl -X POST https://api.trilocore.ai/api/v1/bevm/transactions \
  -H "Authorization: Bearer $TRILOCORE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
        "to": "0xYourTargetContract",
        "signature": "transfer(address,uint256)",
        "args": ["0x0000000000000000000000000000000000000001", "1"],
        "value_wei": 0,
        "persist": true
      }'

The result reports whether the call succeeded, what it cost, what moved and what changed in storage:

{
  "result": {
    "ok": true,
    "gas_used": 51284,
    "tx_hash": "0x…",
    "execution_id": "exec_…",
    "sender_eth_delta_wei": "-51284000000000",
    "target_eth_delta_wei": "0",
    "slot_diffs": [["…", "…", "…"]],
    "error": "",
    "return_data": "0x…",
    "durable": true
  }
}

slot_diffs is the part that turns a hunch into evidence: every storage slot the call touched, with its value before and after. execution_id is a durable record — the execution survives the session, so a reproduction can be replayed and cited later.

Idempotency-Key is mandatory here

Requests that change the fork are rejected with 400 idempotency_key_required if the header is missing — before the body is even read. Mint one key per logical call and reuse it across retries, so a retry replays the stored result instead of firing a second transaction. See Idempotency.

3. Read the state back

curl -X GET https://api.trilocore.ai/api/v1/bevm/balances/{address} \
  -H "Authorization: Bearer $TRILOCORE_API_KEY"

Substitute the address you care about. Add ?erc20=<token address> to read a token balance instead of the native one. {address} also accepts the session's auditor and target aliases, so you can check the two accounts that matter without pasting hex.

What you just built

You have a private, funded copy of mainnet with one transaction on it, and a durable record of what that transaction did. From here:

  • Do the same thing with a UI, a call graph and a storage inspector attached — Auditing IDE.
  • Understand sessions, executions, findings and attestations — Core concepts.
  • Write the contract instead of taking it apart — Contract IDE.
  • Every endpoint, with its parameters and its idempotency rules — Endpoint reference; sessions and forks specifically are in Sessions and forks.