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

# Broadcast Transactions

> Submit a signed transaction to the blockchain through StarkFi's payment infrastructure. Never broadcast directly from the user's wallet.

<ParamField header="x-api-key" type="string" required placeholder="your-api-key">
  Your StarkFi API key. You can find it in your [dashboard](https://app.starkfi.io).
</ParamField>

<Warning>
  You must **always** use this endpoint for all on-chain operations. Never send transactions via your own broadcast or directly through the user's wallet (e.g. using `sendTransaction`). The user should only **sign** the transaction — after signing, your backend must forward it here. This ensures all required steps for payment processing and order confirmation are properly executed.
</Warning>

<ParamField body="executor_id" type="string" required>
  Transaction executor type. Use `api_transaction` when the request comes via API.
</ParamField>

<ParamField body="payment_id" type="string" required>
  Unique payment identifier generated in the [Create Transaction](/create-transaction) step.
</ParamField>

<ParamField body="signed_transaction" type="string" required>
  Signed transaction hex string generated by the user's wallet after signing the `crypto_tx` received from the create transaction endpoint.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.starkfi.io/payment/execute/on-chain \
    --header 'Content-Type: application/json' \
    --header 'x-api-key: <api_key>' \
    --data '{
      "executor_id": "api_transaction",
      "payment_id": "cmoejr9eh000401nyffxgmxtj",
      "signed_transaction": "0x02f8b282a4ec..."
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.starkfi.io/payment/execute/on-chain",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": "<api_key>",
      },
      body: JSON.stringify({
        executor_id: "api_transaction",
        payment_id: "cmoejr9eh000401nyffxgmxtj",
        signed_transaction: "0x02f8b282a4ec...",
      }),
    }
  );

  const data = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.starkfi.io/payment/execute/on-chain",
      headers={
          "Content-Type": "application/json",
          "x-api-key": "<api_key>",
      },
      json={
          "executor_id": "api_transaction",
          "payment_id": "cmoejr9eh000401nyffxgmxtj",
          "signed_transaction": "0x02f8b282a4ec...",
      },
  )

  data = response.json()
  ```
</RequestExample>

<ResponseExample>
  ```json 200 - Payment confirmed (broadcast completed) theme={null}
  {
    "statusCode": 200,
    "success": true,
    "status": "payment_confirmed",
    "message": "Payment confirmed",
    "data": {
      "id": "cmoejr9eh000401nyffxgmxtj",
      "tid_hash": "0xabc123...def456"
    }
  }
  ```

  ```json 200 - Payment received (awaiting bridge) theme={null}
  {
    "statusCode": 200,
    "success": true,
    "status": "payment_received",
    "message": "Payment received...waiting for worker to send transaction to blockchain.",
    "data": {
      "id": "cmoejr9eh000401nyffxgmxtj",
      "tx_hash": "0xabc123...def456"
    }
  }
  ```

  ```json 409 - Invalid payment status theme={null}
  {
    "statusCode": 409,
    "success": false,
    "status": "invalid_payment_status",
    "message": "Order is not in a valid status for execution."
  }
  ```

  ```json 400 - Invalid signed transaction theme={null}
  {
    "statusCode": 400,
    "success": false,
    "status": "invalid_signed_transaction",
    "message": "Invalid signature or mismatch with the unsigned transaction."
  }
  ```

  ```json 500 - Payment failed (reverted on-chain) theme={null}
  {
    "statusCode": 500,
    "success": false,
    "status": "payment_failed",
    "message": "Receipt received but transaction was reverted on-chain."
  }
  ```
</ResponseExample>

### Response

<ResponseField name="statusCode" type="number" required>
  HTTP status code. Returns `200` on success.
</ResponseField>

<ResponseField name="success" type="boolean" required>
  Whether the request succeeded.
</ResponseField>

<ResponseField name="status" type="enum<string>" required>
  Broadcast result status. Available options: `payment_confirmed`, `payment_received`

  * `payment_confirmed` — broadcast accepted and transaction receipt confirmed on-chain. Order status updated to `success`.
  * `payment_received` — transaction confirmed on source chain. Worker (`FinalizerTransferWorker`) takes over to monitor the bridge via LiFi. Order status updated to `received`.
</ResponseField>

<ResponseField name="message" type="string" required>
  Human-readable response message.
</ResponseField>

<ResponseField name="data" type="object" required>
  Broadcast result data.

  <Expandable title="data">
    <ResponseField name="id" type="string" required>
      Internal order ID in StarkFi.
    </ResponseField>

    <ResponseField name="tid_hash" type="string">
      Confirmed transaction hash on the blockchain. Present on `payment_confirmed`.
    </ResponseField>

    <ResponseField name="tx_hash" type="string">
      Transaction hash on the source chain. Present on `payment_received`. The final destination is processed by the worker.
    </ResponseField>
  </Expandable>
</ResponseField>

***

## Errors

### Before broadcast

These occur during payload or order validation, **before** any transaction is sent to the network.

| HTTP  | `status`                       | When it occurs                                     |
| ----- | ------------------------------ | -------------------------------------------------- |
| `400` | `invalid_parameters`           | Invalid payload — schema validation failed         |
| `400` | `invalid_chain`                | Order's chain is not enabled or not supported      |
| `404` | `payment_not_found`            | `payment_id` does not exist                        |
| `409` | `invalid_payment_status`       | Order is not in `registered` or `retry` status     |
| `409` | `missing_unsigned_transaction` | Unsigned tx was not generated before execute       |
| `400` | `invalid_signed_transaction`   | Invalid signature or mismatch with the unsigned tx |
| `400` | `stale_transaction_nonce`      | Transaction nonce is out of sync                   |

### During broadcast

These occur after validation, during or after the broadcast to the network.

| HTTP  | `status`                                  | When it occurs                                                   |
| ----- | ----------------------------------------- | ---------------------------------------------------------------- |
| `500` | `payment_failed`                          | Receipt received but transaction was reverted on-chain           |
| `500` | `finalizer_payment_order_on_chain_failed` | Unexpected exception inside the finalizer                        |
| `500` | `blockchain_transaction_failed`           | Exception caught by the controller before reaching the finalizer |

***

## Order status lifecycle

Once broadcast is submitted, the order moves through the following states:

```
registered / retry
  → processing          (execute started)
  → processing          (signed_tx saved)
  → success             (FinalizerTransferOnChain: broadcast confirmed)
  → received            (FinalizerBridgeSwapOnChain: waiting for worker)
  → success             (worker completes the bridge)
  → error               (any failure along the way)
```

<Tip>
  Use the [Check Payment Info](/starkpay) endpoint to poll the order status after broadcasting and confirm when it reaches `success`.
</Tip>
