---
title: "Build, simulate, send, and check transactions"
description: "Build, simulate, send, and check status."
---

> Documentation Index
> Fetch the complete documentation index at: https://tee.hypetrade.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Build, simulate, send, and check transactions

**Auth: workspace token. Scope: `sign` on every route.**

All four need a resolvable RPC endpoint for the address's network, and stamp
`x-rpc-source` on the response naming which tier served the call.

## The shared request body

`build`, `simulate`, and `send` take the same shape. Which fields apply depends
on the addressed VM.

| Field | VM | Required | Notes |
|---|---|---|---|
| `address` | both | yes | Public key, 1–128 characters |
| `to` | EVM | yes | Destination address |
| `value` | EVM | no | Decimal string or non-negative integer |
| `data` | EVM | no | Calldata |
| `nonce` | EVM | no | Non-negative integer; assigned by the endpoint when omitted |
| `gasLimit` | EVM | no | Decimal string or integer |
| `maxFeePerGas` | EVM | no | Decimal string or integer |
| `maxPriorityFeePerGas` | EVM | no | Decimal string or integer |
| `recipient` | SVM | yes | Destination address |
| `amount` | SVM | yes | Decimal string or integer |
| `tokenMint` | SVM | no | SPL token mint; omit for native SOL |
| `recentBlockhash` | SVM | no | Supplied by the endpoint when omitted |

> **Large numbers travel as strings**
>
> JSON has no bigint. Send `"1000000000000000000"`, not `1e18`.

Missing `to` on EVM, or `recipient`/`amount` on SVM, returns `400` with
`invalid_body`.

## `POST /v1/transactions/build`

Construct an unsigned transaction. Returns `200`.

```json
{ "raw": { }, "vm": "evm", "network": "ethereum" }
```

## `POST /v1/transactions/simulate`

Execute against the node without submitting. Returns `200`.

```json
{
  "success": false,
  "error": "execution reverted: insufficient balance",
  "gasUsed": "21000",
  "logs": []
}
```

| Field | Present | Meaning |
|---|---|---|
| `success` | always | Whether the simulated execution succeeded |
| `error` | on failure | Revert reason, truncated to 200 characters |
| `gasUsed` | when reported | Decimal string |
| `logs` | when reported | At most 32 entries, each truncated to 200 characters |

An on-chain failure is a `200` with `success: false`. A simulation that could
not complete — unreachable endpoint, transport refusal — is an error status
instead. That distinction stops an outage from reading as "would revert".

## `POST /v1/transactions/send`

Build, sign, and submit. Returns **`202`** — accepted, not confirmed.

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

| `status` | Meaning |
|---|---|
| `pending` | The network accepted it |
| `unknown` | Submission timed out; the bytes may already have reached the network |

> **Never resend on unknown without checking**
>
> `unknown` is not failure — it is an unestablished outcome. The signed
> transaction may well be in flight. Resending is how you pay twice. Call the
> status route with the returned `hash` first.

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

## `GET /v1/transactions/{hash}`

Stateless status lookup — one RPC call, nothing stored. Returns `200`.

### Query parameters

| Parameter | Required | Notes |
|---|---|---|
| `network` | yes | Network slug; required because no state is kept |

The hash must be 1–128 characters.

```json
{ "hash": "0x…", "found": true, "status": "confirmed" }
```

| `status` | Meaning |
|---|---|
| `pending` | Not yet visible (`found: false`) |
| `confirmed` | Included and successful |
| `failed` | Included but reverted, or explicitly errored |

Polling this route is the supported way to follow a transaction — there is no
lifecycle tracking and no webhook.

> **`confirmed` is one observation, not finality**
>
> The route reports what your endpoint says right now. It applies no confirmation
> depth on EVM, so a `confirmed` result can still be reorganised out. On Solana
> it does not read `confirmationStatus` either, so a signature that has only been
> `processed` reports `confirmed`.
>
> For anything where being wrong is expensive, poll until you are satisfied by
> your own depth or finality rule rather than stopping at the first `confirmed`.

## Nonces

The service does not cache or allocate nonces. It does not exclusively own your
addresses, so the endpoint assigns one unless you pass `nonce` explicitly. If
you also send from the same address by other means, supply it yourself.

> **There is no network field on a transaction**
>
> The chain comes from the `address` you name — every address belongs to exactly
> one network, fixed by its account's `defaultNetwork` at creation. A build or
> send cannot be redirected to another chain, and there is no way for a path and
> a body to disagree about which chain is in play.

## Errors

| Status | Code |
|---|---|
| 400 | `invalid_body`, `invalid_parameter`, `unsupported_network` |
| 404 | `account_not_found` — including a `?network=` this workspace does not define |
| 401 | `session_expired` |
| 403 | `scope_denied` |
| 404 | `account_not_found` |
| 409 | `rpc_not_configured`, `tx_dropped`, `tx_aborted` |
| 422 | `tx_build_failed`, `unsupported_for_kind` |
| 423 | `account_locked` |
| 429 | `rpc_capacity_exceeded` |
| 500 | `tx_sign_failed` |
| 502 | `rpc_unreachable`, `rpc_rejected`, `tx_submit_failed` |
| 504 | `tx_timeout` |

`tx_timeout` carries the same warning as `unknown`: check status before
resending.

## Related

- [Send transactions](/guides/send-transactions/) — the task walkthrough
- [Networks and RPC](/concepts/networks-and-rpc/) — endpoint resolution

Source: https://tee.hypetrade.xyz/api/transactions/index.mdx
