Skip to main content
A draft link opens the Tenderly Simulator with a pre-filled form. Nothing runs until the recipient clicks Simulate, so the link is safe to share in test reports, pull requests, or alerts. A draft prefills a single simulation, not a bundle. It populates one transaction form (one row); it does not reconstruct a multi-step bundle.

URL format

The link is the Simulator’s new-simulation route with a draft query parameter: https://dashboard.tenderly.co/<org>/<project>/simulator/new?draft=<value> <value> is the draft JSON payload, UTF-8 encoded, then base64url: standard base64 with + replaced by -, / replaced by _, and = padding stripped.
For a one-off share you do not need a script. Fill the form in the Simulator and click Copy draft link in the page header (shown while the bundle has a single simulation). The rest of this page is for generating links programmatically, from CI, test reports, or other tooling.

Quick start

A minimal raw-calldata draft is all most CI scripts need. The to address goes in contractAddress, and the calldata goes in rawFunctionInput:
{
  "v": 1,
  "network": { "id": "1" },
  "row": {
    "contractAddress": "0xdac17f958d2ee523a2206206994597c13d831ec7",
    "from": "0xab5801a7d398351b8be11c439e05c5b3259aec9b",
    "inputDataType": "raw",
    "rawFunctionInput": "0xa9059cbb…"
  }
}
Encode that payload and append it to the URL:
import base64, json

payload = {
    "v": 1,
    "network": {"id": "1"},
    "row": {
        "contractAddress": "0xdac17f958d2ee523a2206206994597c13d831ec7",
        "from": "0xab5801a7d398351b8be11c439e05c5b3259aec9b",
        "inputDataType": "raw",
        "rawFunctionInput": "0xa9059cbb…",
    },
}

draft = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().rstrip("=")
url = f"https://dashboard.tenderly.co/<org>/<project>/simulator/new?draft={draft}"
// Node.js
const payload = {
  v: 1,
  network: { id: "1" },
  row: {
    contractAddress: "0xdac17f958d2ee523a2206206994597c13d831ec7",
    from: "0xab5801a7d398351b8be11c439e05c5b3259aec9b",
    inputDataType: "raw",
    rawFunctionInput: "0xa9059cbb…",
  },
};

const draft = Buffer.from(JSON.stringify(payload)).toString("base64url");
const url = `https://dashboard.tenderly.co/<org>/<project>/simulator/new?draft=${draft}`;
# Shell, reading the payload from payload.json (GNU coreutils)
DRAFT=$(jq -c . payload.json | basenc --base64url -w0 | tr -d '=')
# macOS fallback:
DRAFT=$(jq -c . payload.json | base64 | tr '+/' '-_' | tr -d '=\n')

Top-level payload

FieldTypeRequiredDescription
vnumberyesSchema version. Must be 1.
network{ "id": string } or nullyesChain id as a string ("1" is Mainnet, "56" is BNB Chain, and so on). Must be a network enabled on the recipient’s project, otherwise they get a “network not available” error and an empty form. Always set it. null is accepted but skips the contract lookup and leaves the form mostly unusable. See Supported Networks for chain ids.
rowobjectyesThe form fields. See row fields below.

row fields

Only contractAddress is required. Omit anything you do not need. Omitted fields keep the form’s defaults, and unknown extra fields are ignored.

Contract and function

FieldTypeDescription
contractAddressstringRequired. The “to” address. The contract and its ABI are fetched on the recipient’s side when the link opens.
inputDataType"decoded" or "raw"Selects the function-input mode. Use "raw" with rawFunctionInput, or "decoded" with contractFunction and functionInputs.
rawFunctionInputstringHex calldata (0x…) for raw mode. No ABI needed, which makes it the most robust option for scripts.
contractFunctionobject or nullDecoded-mode function reference: { "name": string, "selector"?: string, "signature"?: string }. name is required inside the object. selector (4-byte hex, e.g. "0xa9059cbb") is optional but preferred: it is matched first and is exact for overloaded functions. Without it, matching falls back to name and may pick the wrong overload. signature is informational only.
functionInputsarray or objectDecoded-mode argument values. Preferred: a positional array in ABI order, for example ["0xabc…", "1000000", ["0xa…", "0xb…"]]. Values are strings, numbers, or booleans. Array and tuple arguments may be passed natively as nested arrays or objects, with no pre-stringifying needed. The keyed form { "input_0": … } is also accepted (it is what the UI’s Copy button emits).
contractAbiImportstringPre-fills the in-app “Edit ABI” field. Function matching on open uses the fetched ABI only, so this field does not make decoded mode work for unverified contracts. Use raw calldata for those.

Transaction parameters

FieldTypeDescription
fromstringSender address.
gasstring or numberGas limit, e.g. "8000000".
gasPricestring or numberGas price in wei.
valuestring or numberNative-token value in wei.

Block selection

FieldTypeDescription
blockstring or numberBlock number to simulate at. Omit for the chain head.
blockIndexstring, number, or nullTransaction position inside the block. null or omitted means the start of the block.
endOfBlockbooleantrue runs the simulated transaction after every transaction in the block (overrides blockIndex).
usePendingBlockbooleantrue simulates on the pending block instead of a fixed number.
See Simulation Parameters for how block selection and transaction index behave in the UI.

L2 parameters

These fields apply to OP-stack and Boba networks only.
FieldTypeDescription
depositTxbooleanMark as an L2 deposit transaction.
systemTxbooleanMark as an L2 system transaction.
mintstringDeposit mint amount.
l1BlockNumberstringOriginating L1 block number.
l1TimestampstringOriginating L1 timestamp.
l1MessageSenderstringL1 message sender address.
l1TuringstringBoba Turing data.

Overrides

FieldTypeDescription
blockHeaderOverridesobject{ "number"?: …, "timestamp"?: … }, each a string, number, or null. Overrides the simulated block header.
stateOverridesarrayPer-contract state overrides: { "id"?: string, "contractAddress": string, "balance": string, "storage"?: [{ "key": string, "value": string }], "code"?: string }. id is optional and generated when absent. balance is in wei ("" means no balance override). storage keys and values are 32-byte hex.
accessListarrayEIP-2930 access list: { "address": string, "storageKeys": string[] }.
Two override types are UI-only and cannot be set in a draft. Configure them in the app after opening the link: fund-address ERC-20 overrides and custom Solidity sources (the in-app “Edit source” feature).

Validation

Draft hydration is all-or-nothing. A missing required field, a wrong v, or any wrong-typed field rejects the whole payload: the recipient sees “This draft link is invalid or corrupted” and an empty form. There is no partial hydration, so a broken script fails visibly instead of half-working.

Limits and tips

  • Keep the final URL under 2000 characters. The app refuses to copy longer links, and browsers and proxies may truncate them. Decoded calls with many inputs land around ~1900.
  • Discovering payload shapes: fill the form in the Simulator UI, click Copy draft link, and base64url-decode the draft value. The result is a known-good payload for your exact use case, and it is the best way to get the advanced shapes (stateOverrides, accessList) right.
  • The contract ABI is fetched when the link opens. If it cannot be resolved (an unverified contract), decoded-mode drafts open with the address filled but no function selected. Raw mode is immune to this.
For the form fields a draft populates, see Simulation Parameters. To keep a modified state as a persistent environment instead of a one-shot simulation, use Virtual Environments.