> ## Documentation Index
> Fetch the complete documentation index at: https://docs.avnu.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Build Private Transaction

> Build an apply_action transaction and get the pool fee to withdraw

## Overview

JSON-RPC method `paymaster_buildTransaction` with the `apply_action` type. Returns the fee estimate and the `fee_action`: the pool fee that must be withdrawn (inside the private transaction) to reimburse the paymaster. Use `invoke_and_apply_action` instead when a signed user call must be wrapped in the same transaction (e.g. an `approve` for a deposit) — the response then also contains the `typed_data` to sign.

The endpoint is the base URL itself (no path): `https://starknet.paymaster.avnu.fi` (mainnet) or `https://sepolia.paymaster.avnu.fi` (testnet).

## Headers

<ParamField header="x-paymaster-api-key" type="string" required>
  [Portal](https://portal.avnu.fi) API key. Required for the sponsored fee modes (`sponsored`, `sponsored_private`)
</ParamField>

## Body (JSON-RPC 2.0)

<ParamField body="method" type="string" required>
  `paymaster_buildTransaction`
</ParamField>

<ParamField body="params.transaction.type" type="string" required>
  `apply_action`, or `invoke_and_apply_action` when a signed user call is required
</ParamField>

<ParamField body="params.transaction.apply_action.pool_address" type="string" required>
  The privacy pool address. Must be the pool whitelisted by the paymaster (exported by the SDK as `PRIVACY_POOL_ADDRESS` / `SEPOLIA_PRIVACY_POOL_ADDRESS`)
</ParamField>

<ParamField body="params.transaction.invoke" type="object">
  Only for `invoke_and_apply_action`: `{ user_address, calls }` — the user calls to wrap
</ParamField>

<ParamField body="params.parameters.version" type="string" required>
  `0x1`
</ParamField>

<ParamField body="params.parameters.fee_mode" type="object" required>
  `{ mode: 'sponsored_private', pool_fee_token, tip? }`. `pool_fee_token` is the token the pool fee is paid in; `tip` is `slow` | `normal` | `fast` (default `normal`)
</ParamField>

<ParamField body="params.parameters.time_bounds" type="object">
  Optional `{ execute_after, execute_before }` (unix seconds)
</ParamField>

## Response

<ResponseField name="type" type="string">
  Echoes the transaction type
</ResponseField>

<ResponseField name="fee_action" type="object" required>
  The pool fee to withdraw inside the private transaction: `{ type: 'withdraw', recipient, token, amount }` (hex amounts)
</ResponseField>

<ResponseField name="fee" type="object">
  Fee estimate: `gas_token_price_in_strk`, `estimated_fee_in_strk`, `estimated_fee_in_gas_token`, `suggested_max_fee_in_strk`, `suggested_max_fee_in_gas_token` (hex)
</ResponseField>

<ResponseField name="parameters" type="object">
  Echoes the execution parameters
</ResponseField>

<ResponseField name="typed_data" type="object">
  Only for `invoke_and_apply_action`: the SNIP-12 typed data the user must sign
</ResponseField>

## Errors

| Code | Name                                 | When                                                           |
| ---- | ------------------------------------ | -------------------------------------------------------------- |
| 151  | `TOKEN_NOT_SUPPORTED`                | `pool_fee_token` is not supported                              |
| 156  | `TRANSACTION_EXECUTION_ERROR`        | Execution failure (including a non-whitelisted `pool_address`) |
| 163  | `UNKNOWN_ERROR`                      | Invalid API key, service unavailable, or blacklisted call      |
| 168  | `SPONSORED_PRIVATE_REQUIRES_PRIVACY` | `sponsored_private` used with a non-private transaction type   |

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://starknet.paymaster.avnu.fi" \
    -H "Content-Type: application/json" \
    -H "x-paymaster-api-key: $PAYMASTER_API_KEY" \
    -d '{
      "jsonrpc": "2.0",
      "id": 1,
      "method": "paymaster_buildTransaction",
      "params": {
        "transaction": {
          "type": "apply_action",
          "apply_action": { "pool_address": "0x04c9...pool" }
        },
        "parameters": {
          "version": "0x1",
          "fee_mode": {
            "mode": "sponsored_private",
            "pool_fee_token": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
            "tip": "normal"
          }
        }
      }
    }'
  ```

  ```typescript TypeScript (SDK) theme={null}
  import { buildPrivateSwapFee, PRIVACY_POOL_ADDRESS } from '@avnu/avnu-sdk';

  const fee = await buildPrivateSwapFee({
    poolAddress: PRIVACY_POOL_ADDRESS,
    feeMode: { poolFeeToken: STRK, tip: 'normal' },
    paymasterApiKey: PAYMASTER_API_KEY,
  });
  // { token, recipient, amount } — withdraw this inside the private transaction
  ```
</RequestExample>

<ResponseExample>
  ```json Success theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "type": "apply_action",
      "parameters": {
        "version": "0x1",
        "fee_mode": { "mode": "sponsored_private", "pool_fee_token": "0x04718...938d", "tip": "normal" }
      },
      "fee": {
        "gas_token_price_in_strk": "0xde0b6b3a7640000",
        "estimated_fee_in_strk": "0x2386f26fc10000",
        "estimated_fee_in_gas_token": "0x2386f26fc10000",
        "suggested_max_fee_in_strk": "0x354a6ba7a18000",
        "suggested_max_fee_in_gas_token": "0x354a6ba7a18000"
      },
      "fee_action": {
        "type": "withdraw",
        "recipient": "0x05f4...fee",
        "token": "0x04718...938d",
        "amount": "0x2386f26fc10000"
      }
    }
  }
  ```
</ResponseExample>
