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

# initiatePayout

> Initiates a Noah payout from a previously quoted payout.

## Function Signature

```swift theme={null}
public func initiatePayout(request: NoahInitiatePayoutRequest) async throws -> NoahInitiatePayoutResponse
```

## Description

Executes a payout that was previously quoted with [`getPayoutQuote`](./noahgetpayoutquote). Returns the destination address and the on-chain deposit conditions your transfer must satisfy.

The payout must be authorized by a trigger. Either supply one explicitly through `trigger`, or rely on a saved payment method attached to the quote via `paymentMethodId` — when `trigger` is omitted and the saved method is a single on-chain deposit source, a default trigger is synthesised from the `sourceAddress`, `expiry`, and `nonce` you passed.

Completion and failures are reported asynchronously through Noah `Transaction` webhooks.

## Parameters

| Parameter               | Type                               | Required | Description                                                                                                                    |
| ----------------------- | ---------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `request.payoutId`      | `String`                           | Yes      | Identifier from `getPayoutQuote`.                                                                                              |
| `request.sourceAddress` | `String`                           | Yes      | Address funding the crypto leg.                                                                                                |
| `request.expiry`        | `String`                           | Yes      | ISO-8601 expiry for the deposit authorization.                                                                                 |
| `request.nonce`         | `String`                           | Yes      | Stable nonce for this payout attempt. **Reuse it on retry** so repeated calls stay idempotent. Must be 36 characters or fewer. |
| `request.network`       | `String`                           | Yes      | CAIP-2 network for the deposit leg. Use a `NoahNetwork` constant.                                                              |
| `request.trigger`       | `NoahOnchainDepositSourceTrigger?` | No       | Explicit on-chain deposit trigger. See below.                                                                                  |
| `request.businessFee`   | `NoahBusinessFee?`                 | No       | Business fee override. Forwarded to Noah as `BusinessFee`.                                                                     |

### Deposit source triggers

`NoahOnchainDepositSourceTrigger` is an enum with three cases. The wire format is discriminated by a `Type` field, so the enum encodes its wrapped value transparently — no extra nesting is added to the JSON. Each trigger input defaults its `type` property to the correct discriminator.

| Case         | Payload                                         | Use it for                                                                                                              |
| ------------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `.single`    | `NoahSingleOnchainDepositSourceTriggerInput`    | One payout matching specific amount conditions on a network.                                                            |
| `.permanent` | `NoahPermanentOnchainDepositSourceTriggerInput` | A source that stays active across multiple deposits until expiry. Set `networkAgnostic` to match any supported network. |
| `.quoted`    | `NoahQuotedOnchainDepositSourceTriggerInput`    | A rate-locked payout. Requires the `signedQuote` from a `getPayoutQuote` call made with `quoted: true`.                 |

Trigger inputs serialize their fields in PascalCase (`Type`, `Conditions`, `SourceAddress`, `Expiry`, `Nonce`) to match the Noah API wire format.

## Returns

**`NoahInitiatePayoutResponse`** — an envelope containing:

| Property   | Type                     | Description                 |
| ---------- | ------------------------ | --------------------------- |
| `data`     | `NoahInitiatePayoutData` | The response payload.       |
| `metadata` | `NoahResponseMetadata?`  | Freeform response metadata. |

`NoahInitiatePayoutData`:

| Property             | Type                                   | Description                                                                                                                        |
| -------------------- | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `destinationAddress` | `String?`                              | Address to send the crypto leg to. Derived from `conditions[0].destinationAddress`; `nil` when that shape is missing.              |
| `conditions`         | `[NoahDepositSourceTriggerCondition]?` | Conditions the on-chain transfer must satisfy. Each has `amountConditions`, `cryptoCurrency`, `network`, and `destinationAddress`. |
| `ruleId`             | `String?`                              | Identifier of the Noah rule created for permanent and quoted triggers.                                                             |

## Example

```swift theme={null}
import PortalSwift

let formatter = ISO8601DateFormatter()
let expiry = formatter.string(from: Date().addingTimeInterval(24 * 60 * 60))

// Use a stable nonce per payout attempt and reuse it on retries
let nonce = String(UUID().uuidString.prefix(36))

do {
  let response = try await portal.ramps.noah.initiatePayout(
    request: NoahInitiatePayoutRequest(
      payoutId: quote.data.payoutId,
      sourceAddress: "SoLAddr1111111111111111111111111111111111111",
      expiry: expiry,
      nonce: nonce,
      network: NoahNetwork.solanaDevnet
    )
  )

  if let destination = response.data.destinationAddress {
    print("Send funds to: \(destination)")
  } else {
    // Handle this however your app prefers — surface it, log it, or fail the flow.
    print("Noah did not return a destination address for this payout")
  }
} catch {
  print("initiatePayout failed: \(error)")
}
```

With an explicit `.single` trigger:

```swift theme={null}
let trigger = NoahOnchainDepositSourceTrigger.single(
  NoahSingleOnchainDepositSourceTriggerInput(
    conditions: [
      NoahSingleOnchainDepositSourceTriggerCondition(
        amountConditions: [
          NoahSingleOnchainDepositSourceTriggerAmountCondition(
            comparisonOperator: .eq,
            value: quote.data.cryptoAuthorizedAmount
          )
        ],
        network: NoahNetwork.solanaDevnet
      )
    ],
    sourceAddress: "SoLAddr1111111111111111111111111111111111111",
    expiry: expiry,
    nonce: nonce
  )
)

let response = try await portal.ramps.noah.initiatePayout(
  request: NoahInitiatePayoutRequest(
    payoutId: quote.data.payoutId,
    sourceAddress: "SoLAddr1111111111111111111111111111111111111",
    expiry: expiry,
    nonce: nonce,
    network: NoahNetwork.solanaDevnet,
    trigger: trigger
  )
)
```

## Errors

| Error                                           | Description                                                                                                                      |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `PortalRequestsError.unauthorized`              | Authentication failed (401).                                                                                                     |
| `PortalRequestsError.clientError`               | Client error (4xx). No trigger supplied and no saved payment method on the quote, an expired quote, or an unsupported `network`. |
| `PortalRequestsError.internalServerError`       | Server error (5xx).                                                                                                              |
| `PortalRequestsError.couldNotParseHttpResponse` | The response could not be parsed.                                                                                                |
| `URLError.badURL`                               | The request URL could not be built.                                                                                              |

## Related

* [Noah virtual accounts and payouts](../guide/noah)
* [getPayoutQuote](./noahgetpayoutquote)
* [Send tokens](../guide/send-tokens) — satisfy the returned deposit conditions with `portal.sendAsset(...)`
* [Noah payouts workflow](/integrations/On-Off-Ramp/noah-payouts)
* [Noah webhooks](/integrations/On-Off-Ramp/noah-webhooks)
