Skip to content

How to send a transaction without paying twice

Build, simulate, submit, and check status — including the unknown outcome that matters most.

Updated View as Markdown

All four transaction routes need the sign scope and a working RPC endpoint for the address’s network. Read Networks and RPC first if you have not configured one.

The request body

One shape covers both VMs; which fields apply depends on the address you name.

{
  "address": "0xabc…",
  "to": "0xdef…",
  "value": "1000000000000000000",
  "data": "0x",
  "nonce": 42,
  "gasLimit": "21000",
  "maxFeePerGas": "30000000000",
  "maxPriorityFeePerGas": "1500000000"
}

to is required. Everything after it is optional — omitted fee fields and nonce are filled in by the endpoint.

{
  "address": "So1abc…",
  "recipient": "So1def…",
  "amount": "1000000",
  "tokenMint": "EPjFWdd5…",
  "recentBlockhash": "9xQe…"
}

recipient and amount are both required. tokenMint selects an SPL token instead of native SOL.

Build

Produces an unsigned transaction without touching your keys:

curl -X POST "$API_URL/transactions/build" \
  -H "Authorization: Bearer $TOKEN" \
  -H "content-type: application/json" \
  -d '{"address":"0xabc…","to":"0xdef…","value":"1000000000000000000"}'
{ "raw": { }, "vm": "evm", "network": "ethereum" }

The response carries an x-rpc-source header naming which endpoint tier served it.

Simulate

Same body, executed against the node without submitting:

curl -X POST "$API_URL/transactions/simulate" \
  -H "Authorization: Bearer $TOKEN" \
  -H "content-type: application/json" \
  -d '{"address":"0xabc…","to":"0xdef…","value":"1000000000000000000"}'
{ "success": false, "error": "execution reverted: insufficient balance", "gasUsed": "21000", "logs": [] }

An on-chain failure is a 200 with success: false and a revert reason. A simulation that could not complete at all — unreachable endpoint, transport refusal — is an error status instead, never a 200. That distinction is deliberate: it stops a network outage from reading as “the transaction would revert”.

Provider text is bounded before it reaches you: error and each log entry are truncated to 200 characters, and at most 32 logs are returned.

Send

Builds, signs, and submits in one call:

curl -X POST "$API_URL/transactions/send" \
  -H "Authorization: Bearer $TOKEN" \
  -H "content-type: application/json" \
  -d '{"address":"0xabc…","to":"0xdef…","value":"1000000000000000000"}'

Returns 202 — accepted for submission, not confirmed:

{ "hash": "0x…", "status": "pending", "network": "ethereum" }

The two statuses, and why the second one matters

status Meaning What to do
pending The network accepted it Poll for confirmation
unknown Submission timed out; the bytes may already have reached the network Poll status; see the warning below before resending

The returned hash is the signed transaction’s canonical identifier, computed before submission — so it is a valid lookup key even when the status is unknown.

Check status

A stateless passthrough to the network. The service stores nothing, so the network selector is required:

curl "$API_URL/transactions/0x…?network=ethereum" \
  -H "Authorization: Bearer $TOKEN"
{ "hash": "0x…", "found": true, "status": "confirmed" }
status Meaning
pending Not yet visible on the network (found: false)
confirmed Included and successful — one observation, not a finality guarantee
failed Mined but reverted, or explicitly errored

Because there is no lifecycle tracking or webhook, polling this route is the supported way to follow a transaction.

Nonces are not managed for you

The service does not exclusively own your addresses, so it does not cache or allocate nonces — pretending to would be worse than the occasional race. The endpoint assigns one unless you pass nonce explicitly. If you are also sending from the same address by other means, supply the nonce yourself.

Failures worth handling

Code Status What happened
rpc_not_configured 409 No usable endpoint for that network
rpc_unreachable 502 Endpoint did not respond
rpc_rejected 502 Endpoint refused the request
rpc_capacity_exceeded 429 Too many concurrent chain operations
tx_build_failed 422 The transaction could not be constructed
tx_submit_failed 502 The endpoint explicitly refused the submission
tx_timeout 504 Timed out — treat like unknown and check status
tx_dropped 409 Dropped before inclusion
tx_aborted 409 Aborted before submission completed
unsupported_for_kind 422 Field combination wrong for this address’s VM
Navigation

Type to search…

↑↓ navigate↵ selectEsc close