> For the complete documentation index, see [llms.txt](https://docs.flash.trade/flash-trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flash.trade/flash-trade/flash-trade-protocol/build-on-flash/flash-trade-api/flash-trade-v2/workflows/buildtransaction.md).

# BuildTransaction

Cookbook for building, signing, and submitting Flash Trade **v2** transactions. Every endpoint returns `{ "transactionBase64": "…" }` (or a quote object containing it). Prerequisite: the wallet is set up and delegated — see [SetupIntegration](/flash-trade/flash-trade-protocol/build-on-flash/flash-trade-api/flash-trade-v2/workflows/setupintegration.md).

## Transaction Flow

#### `POST /v2/transaction-builder/{action}`

Build the unsigned transaction via the API.

#### Decode base64

`VersionedTransaction.deserialize(Buffer.from(transactionBase64, "base64"))`.

#### Sign

Sign with the owner keypair.

#### Submit to the right RPC

Account & funds ops → Solana RPC. Trades → the v2 RPC.

#### Confirm

Confirm the signature, then read updated state from the basket snapshot (`GET /v2/owner/{owner}` or the WebSocket).

## Open Position

```bash
curl -X POST $FLASH_API_URL/v2/transaction-builder/open-position -H 'Content-Type: application/json' -d '{
  "inputTokenSymbol": "USDC",
  "outputTokenSymbol": "SOL",
  "inputAmountUi": "100.0",
  "leverage": 5.0,
  "tradeType": "LONG",
  "orderType": "MARKET",
  "owner": "<WALLET>",
  "slippagePercentage": "0.5"
}'
```

* **Limit order:** set `"orderType": "LIMIT"` and `"limitPrice": "150.00"`.
* **Attach TP/SL:** add `"takeProfit": "160.00"` and/or `"stopLoss": "130.00"`.
* **Preview only:** omit `owner` → response has `transactionBase64: null`.

## Close Position

```bash
curl -X POST $FLASH_API_URL/v2/transaction-builder/close-position -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL",
  "side": "LONG",
  "inputUsdUi": "500.00",
  "withdrawTokenSymbol": "USDC",
  "owner": "<WALLET>"
}'
```

Use the full position USD size for a full close, or a smaller `inputUsdUi` for a partial close.

## Reverse Position

```bash
curl -X POST $FLASH_API_URL/v2/transaction-builder/reverse-position -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL",
  "side": "LONG",
  "leverage": 5.0,
  "owner": "<WALLET>"
}'
```

Closes the current LONG and opens a SHORT (or vice versa) atomically. `side` is the **current** side.

## Add / Remove Collateral

```bash
# Add (reduce leverage)
curl -X POST $FLASH_API_URL/v2/transaction-builder/add-collateral -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL", "side": "LONG",
  "depositAmountUi": "50.0", "depositTokenSymbol": "USDC", "owner": "<WALLET>"
}'

# Remove (increase leverage)
curl -X POST $FLASH_API_URL/v2/transaction-builder/remove-collateral -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL", "side": "LONG",
  "withdrawAmountUsdUi": "25.00", "withdrawTokenSymbol": "USDC", "owner": "<WALLET>"
}'
```

## Trigger Orders (TP/SL)

```bash
# Place a single take-profit
curl -X POST $FLASH_API_URL/v2/transaction-builder/place-trigger-order -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL", "side": "LONG",
  "triggerPriceUi": "160.00", "sizeAmountUi": "0.5", "isStopLoss": false, "owner": "<WALLET>"
}'

# Place TP and SL atomically
curl -X POST $FLASH_API_URL/v2/transaction-builder/place-tp-sl -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL", "side": "LONG",
  "takeProfitUi": "160.00", "stopLossUi": "140.00", "sizeAmountUi": "0.5", "owner": "<WALLET>"
}'

# Edit an existing trigger (replaces price AND size)
curl -X POST $FLASH_API_URL/v2/transaction-builder/edit-trigger-order -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL", "side": "LONG", "orderId": 0, "isStopLoss": false,
  "triggerPriceUi": "170.00", "sizeAmountUi": "0.5", "owner": "<WALLET>"
}'

# Cancel a single trigger (orderId 0-4), or 255 to cancel all
curl -X POST $FLASH_API_URL/v2/transaction-builder/cancel-trigger-order -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL", "side": "LONG", "orderId": 0, "isStopLoss": false, "owner": "<WALLET>"
}'
```

## Limit Orders

```bash
# Place: use open-position with orderType=LIMIT (see above)

# Edit. limitPrice/size: omit or "0" keeps existing. TP/SL: send to set; "0"/omit removes (re-send to keep).
curl -X POST $FLASH_API_URL/v2/transaction-builder/edit-limit-order -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL", "side": "LONG", "orderId": 0,
  "limitPriceUi": "150.00", "sizeAmountUi": "0.5", "owner": "<WALLET>"
}'

# Cancel (returns reserved collateral, frees the slot)
curl -X POST $FLASH_API_URL/v2/transaction-builder/cancel-limit-order -H 'Content-Type: application/json' -d '{
  "marketSymbol": "SOL", "side": "LONG", "orderId": 0, "owner": "<WALLET>"
}'
```

## Funds Movement

```bash
# Withdraw — step 1 (request). Poll until the escrow closes; unwrap WSOL for SOL.
curl -X POST $FLASH_API_URL/v2/transaction-builder/request-withdrawal -H 'Content-Type: application/json' -d '{
  "owner": "<WALLET>", "tokenMint": "<MINT>", "amount": "12.5", "includeCustodySettlement": true
}'

# Withdraw — step 2 (recover) if it didn't complete automatically
curl -X POST $FLASH_API_URL/v2/transaction-builder/execute-withdrawal -H 'Content-Type: application/json' -d '{
  "owner": "<WALLET>", "tokenMint": "<MINT>", "includeCustodySettlement": true
}'
```

See [TransactionFlow → Withdraw](/flash-trade/flash-trade-protocol/build-on-flash/flash-trade-api/flash-trade-v2/transactionflow.md) for the full two-phase sequence.

## Signing & Submitting

```typescript
import { VersionedTransaction, Connection } from "@solana/web3.js";

async function buildSignSubmit(path: string, body: object, signers, rpcUrl: string) {
  const res = await fetch(`${FLASH_API_URL}${path}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  const data = await res.json();
  if (data.err) throw new Error(data.err);
  if (!data.transactionBase64) throw new Error("preview-only or no tx returned");

  const tx = VersionedTransaction.deserialize(Buffer.from(data.transactionBase64, "base64"));
  tx.sign(signers);

  const connection = new Connection(rpcUrl, "confirmed");
  const sig = await connection.sendRawTransaction(tx.serialize());
  await connection.confirmTransaction(sig, "confirmed");
  return sig;
}

// v2 trade → v2 RPC
await buildSignSubmit("/v2/transaction-builder/open-position", openReq, [ownerKeypair], V2_RPC_URL);

// Account/funds op → Solana RPC
await buildSignSubmit("/v2/transaction-builder/deposit-direct", depositReq, [ownerKeypair], SOLANA_RPC_URL);
```

## Error Recovery

* `{ "err": "…" }` in a `200` body → compute error; fix inputs (symbols, side, amounts) and rebuild.
* `400 { "error": "…" }` from trigger/limit builders → validation error (e.g. bad `orderId`, TP/SL price vs side).
* "Blockhash expired" → rebuild and submit immediately.
* Trade rejected → confirm the basket is delegated and you're submitting to the correct v2 RPC.
* Withdrawal stuck → call `execute-withdrawal` to recover.

See [ErrorReference](/flash-trade/flash-trade-protocol/build-on-flash/flash-trade-api/flash-trade-v2/errorreference.md) for the full matrix.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flash.trade/flash-trade/flash-trade-protocol/build-on-flash/flash-trade-api/flash-trade-v2/workflows/buildtransaction.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
