> ## 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.

# initiateKyc

> Starts hosted Noah KYC onboarding and returns a hosted URL.

## Function Signature

```swift theme={null}
public func initiateKyc(request: NoahInitiateKycRequest) async throws -> NoahInitiateKycResponse
```

## Description

Starts a Noah KYC session for the current customer and returns a hosted onboarding URL. Open the URL in the system browser after validating its scheme and hostname.

This endpoint is **idempotent**. If a Noah customer record already exists for the client, the previously stored `hostedUrl` is returned regardless of KYC status (`Pending`, `Submitted`, `Approved`, `Declined`). Calling it again does not restart onboarding and does not mint a fresh URL.

The KYC outcome is delivered asynchronously through Noah `Customer` webhooks, not through this response.

## Parameters

| Parameter              | Type                    | Required | Description                                                                                   |
| ---------------------- | ----------------------- | -------- | --------------------------------------------------------------------------------------------- |
| `request.returnUrl`    | `String`                | Yes      | HTTPS URL where Noah returns the user after onboarding. Custom app schemes are not supported. |
| `request.fiatOptions`  | `[NoahFiatOption]?`     | No       | Fiat currencies to present during onboarding.                                                 |
| `request.customerType` | `NoahCustomerType?`     | No       | Onboarding flow variant — `.individual` or `.business`.                                       |
| `request.metadata`     | `[String: AnyCodable]?` | No       | Opaque metadata forwarded per API rules.                                                      |
| `request.form`         | `[String: AnyCodable]?` | No       | Optional prefill payload for hosted forms.                                                    |

## Returns

**`NoahInitiateKycResponse`** — an envelope containing:

| Property   | Type                    | Description                                          |
| ---------- | ----------------------- | ---------------------------------------------------- |
| `data`     | `NoahInitiateKycData`   | The response payload.                                |
| `metadata` | `NoahResponseMetadata?` | Freeform response metadata (`[String: AnyCodable]`). |

`NoahInitiateKycData`:

| Property    | Type     | Description                                               |
| ----------- | -------- | --------------------------------------------------------- |
| `hostedUrl` | `String` | Hosted Noah onboarding URL to open in the system browser. |

## Example

```swift theme={null}
import PortalSwift
import UIKit

let allowedHosts: Set<String> = [
  "checkout.noah.com",
  "checkout.sandbox.noah.com",
  "staging-checkout.noah.com",
]

do {
  let response = try await portal.ramps.noah.initiateKyc(
    request: NoahInitiateKycRequest(
      returnUrl: "https://yourapp.example/noah/return",
      fiatOptions: [NoahFiatOption(fiatCurrencyCode: "USD")],
      customerType: .individual
    )
  )

  if let url = URL(string: response.data.hostedUrl),
     url.scheme == "https",
     let host = url.host,
     allowedHosts.contains(host) {
    await UIApplication.shared.open(url)
  } else {
    // Handle this however your app prefers — surface it, log it, or fail the flow.
    print("Noah returned an unexpected KYC URL: \(response.data.hostedUrl)")
  }
} catch {
  print("initiateKyc failed: \(error)")
}
```

## Errors

| Error                                           | Description                                                                                                   |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `PortalRequestsError.unauthorized`              | Authentication failed (401). Verify your Portal client API key and that Noah is enabled for your environment. |
| `PortalRequestsError.clientError`               | Client error (4xx). The request was invalid or malformed.                                                     |
| `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)
* [Noah KYC workflow](/integrations/On-Off-Ramp/noah-kyc)
* [Noah webhooks](/integrations/On-Off-Ramp/noah-webhooks)
