# simulateTransaction

> Runs a transaction against current bank state without submitting it, returning logs, balance changes and any error.

Source: https://docs.constant-k.com/rpc/http/simulatetransaction/

`simulateTransaction` executes a transaction locally against current state and reports what would happen — compute units consumed, program logs, balance changes, and any error — without broadcasting or spending a fee. `sendTransaction`'s own preflight check uses this internally.

By default the transaction must be fully and validly signed, as for `sendTransaction`. `sigVerify: false` simulates an unsigned or placeholder-signed transaction instead, useful while accounts and instructions are still being iterated on.

- Transport: HTTP, JSON-RPC 2.0 `POST` to `https://rpc-newyork.constant-k.com/?api-key=YOUR_API_KEY` (New York) or `https://rpc-frankfurt.constant-k.com/?api-key=YOUR_API_KEY` (Frankfurt) or `https://rpc-amsterdam.constant-k.com/?api-key=YOUR_API_KEY` (Amsterdam). The key also works as an `x-api-key` header.
- Category: Transactions
- Availability: All plans
- Rate limits: Free 2/s · Operator 5/s · Blade Runner 50/s · Nexus 100/s

## Parameters

`params` is a positional JSON array, in this order:

- `transaction` (string, required): The transaction to simulate, wire-encoded per the `encoding` config field. Needs valid signatures unless `sigVerify` is set to false.
- `config` (object, optional): Optional configuration.
  - `commitment` (string, optional, one of `finalized`, `confirmed`, `processed`, default `"finalized"`): Bank state to simulate against.
  - `sigVerify` (boolean, optional, default `false`): When true, the node verifies every signature and rejects the transaction if any are invalid or missing. When false (the default), signatures are not checked, so `replaceRecentBlockhash` becomes the only reliable way to guarantee a valid blockhash.
  - `replaceRecentBlockhash` (boolean, optional, default `false`): Replace the transaction's blockhash with the node's current latest blockhash before simulating. Requires `sigVerify: false` (a replaced blockhash would invalidate any real signatures).
  - `encoding` (string, optional, one of `base58`, `base64`, default `"base58"`): Wire encoding of the `transaction` param.
  - `minContextSlot` (integer, optional): Minimum slot the node must have processed before simulating.
  - `innerInstructions` (boolean, optional, default `false`): When true, includes CPI (inner) instructions in the response's `innerInstructions` field. Off by default to keep the response smaller.
  - `accounts` (object, optional): Request post-simulation account state for specific accounts, instead of only balance/log/error information.
    - `addresses` (string[], required): Addresses to fetch post-simulation state for, base-58 encoded.
    - `encoding` (string, optional, one of `base58`, `base64`, `base64+zstd`, `jsonParsed`, default `"base64"`): Encoding for the returned account data.

## Result

- `result` (object, optional): Simulation outcome, wrapped with context.
  - `context` (object, required)
    - `slot` (integer, optional)
    - `apiVersion` (string, optional)
  - `value` (object, required)
    - `err` (object | string | null, required): Null if the transaction would succeed; a TransactionError otherwise.
    - `logs` (string[] | null, required): Program log output from the simulated execution.
    - `fee` (integer | null, optional): Fee, in lamports, the transaction would be charged.
    - `unitsConsumed` (integer | null, optional): Compute units the simulated execution consumed.
    - `returnData` (object | null, optional): Data returned by the last program invoked via `sol_set_return_data`, if any: `{programId, data: [base64String, "base64"]}`.
    - `preBalances` (integer[], optional): Lamport balance of each account referenced, before simulated execution.
    - `postBalances` (integer[], optional): Lamport balance of each account referenced, after simulated execution.
    - `preTokenBalances` (array, optional): Token balances before simulated execution, same shape as in getTransaction.
    - `postTokenBalances` (array, optional): Token balances after simulated execution.
    - `innerInstructions` (array | null, optional): CPI instructions triggered during simulation, only present when `config.innerInstructions` was true.
    - `loadedAccountsDataSize` (integer | null, optional): Total bytes of account data loaded to run the simulation.
    - `replacementBlockhash` (object | null, optional): Present only when `replaceRecentBlockhash` was true: `{blockhash, lastValidBlockHeight}` for the blockhash actually used.
    - `accounts` (array | null, optional): Post-simulation state for each address listed in `config.accounts.addresses`, in that order, or null for an address that doesn't exist. Only present when `config.accounts` was set.

## Example: Simulate a small SOL transfer

Request:

```bash
curl "https://rpc-newyork.constant-k.com/?api-key=YOUR_API_KEY" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "simulateTransaction",
    "params": [
      "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEDAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAse/3h063VQM6fWXnmiwuZsqOzfY4ONH/wXKeBcXTBpoBAgIAAQwCAAAA9AEAAAAAAAA=",
      { "sigVerify": false, "encoding": "base64" }
    ]
  }'
```

Response:

```json
{
  "jsonrpc": "2.0",
  "result": {
    "context": {
      "apiVersion": "4.3.0-rc.0",
      "slot": 447947977
    },
    "value": {
      "err": {
        "InsufficientFundsForRent": {
          "account_index": 1
        }
      },
      "logs": [
        "Program 11111111111111111111111111111111 invoke [1]",
        "Program 11111111111111111111111111111111 success"
      ],
      "fee": 5000,
      "unitsConsumed": 150,
      "returnData": null,
      "preBalances": [
        1000998,
        0,
        1
      ],
      "postBalances": [
        995998,
        0,
        1
      ],
      "preTokenBalances": [],
      "postTokenBalances": [],
      "innerInstructions": null,
      "loadedAccountsDataSize": 149,
      "replacementBlockhash": null,
      "accounts": null
    }
  },
  "id": 1
}
```

## Notes

- The transfer instruction succeeds, but the simulation fails because it would leave the destination account with a positive balance below the rent-exemption minimum: a System-owned account must end a transaction at 0 lamports or at least the rent-exempt minimum, nothing in between.
- `sigVerify: false` with `replaceRecentBlockhash: true` is the standard combination for iterating on an unsigned transaction; the node fills in a current blockhash without needing a throwaway signer.
- A successful simulation is not a landing guarantee — state can change between simulating and actually submitting, especially for accounts under contention.

