# Start Hosted Onboarding

> Coming soon, upon request — this feature is turned on for your tenant by the Aurea team. [Contact us](https://www.aureahub.com/contact)

With the `hosted_oauth` strategy: get the link to the bank ramp's own pages, where the user signs up, completes their KYC and lets your tenant's application act for them.

## Overview

- **With the `hosted_oauth` strategy only**: the KYC off `403` `BANK_RAMP_FUNCTION_OFF`, another strategy `403` `BANK_RAMP_KYC_STRATEGY_OFF`. Your tenant's bank ramp must be set up for these pages: `503` `BANK_RAMP_NOT_CONFIGURED` otherwise.
- **`redirectUri`** is where the bank ramp sends the user back. It must be one registered for your tenant's bank ramp application — agree them with Aurea when it sets the pages up. An `https` URL, `http` only to `localhost`, `127.0.0.1` or `[::1]`, or your app's own scheme (a deep link); never a fragment (`#`), a user name or a script, data or file URL; at most 2000 characters. Otherwise `400` `BANK_RAMP_REDIRECT_URI_INVALID` with `details.reason`.
- `authMode` chooses the bank ramp's first screen: `signup` or `login`.
- `201`: send the user to `authorizationUrl` — a browser, or an in-app browser. `state` is in that URL too; it is signed by Aurea, names this user and request, works once and lasts a day (`expiresAt`). The PKCE verifier stays with Aurea.
- The bank ramp then sends the user to `redirectUri` with `code` and `state`: hand both to [Complete Hosted Onboarding](https://docs.aureahub.com/docs/bank-customer-authorize-complete.md).

## Endpoint

### `POST /v1/ramp/bank/customer/authorize`

Authentication: bearer token required.

Answers the link to the bank ramp's hosted onboarding for the user.

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `redirectUri` | string | yes | Where the bank ramp sends the user back, 1 to 2000 characters (above) |
| `authMode` | string | no | `signup` or `login` |
| `isTestnet` | boolean | no | `true` for the sandbox; `false` or omitted for production |

**Responses**

`201` Created

```json
{
  "environment": "sandbox",
  "authorizationUrl": "https://…/auth?client_id=…&code_challenge=…&code_challenge_method=S256&redirect_uri=myapp%3A%2F%2Fbank-ramp%2Fdone&state=eyJ0…&auth_mode=signup",
  "state": "eyJ0…",
  "expiresAt": "2026-10-15T09:00:00.000Z"
}
```

`400` Redirect URI refused

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "The redirect URI is not one the bank ramp can send the user back to: https, or http to this machine only.",
  "details": { "code": "BANK_RAMP_REDIRECT_URI_INVALID", "reason": "https, or http to this machine only" }
}
```

`503` Not set up

```json
{
  "statusCode": 503,
  "error": "BankRampProviderError",
  "message": "The bank ramp is not configured for this tenant in sandbox",
  "details": { "code": "BANK_RAMP_NOT_CONFIGURED" }
}
```

## Implementation

```javascript
// 1. Start: open the bank ramp's pages
const start = await fetch('https://api.aureahub.com/v1/ramp/bank/customer/authorize', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
  body: JSON.stringify({ isTestnet: true, redirectUri: 'myapp://bank-ramp/done', authMode: 'signup' })
}).then((r) => r.json());
openInAppBrowser(start.authorizationUrl);

// 2. Back at myapp://bank-ramp/done?code=…&state=… : finish it
async function onRedirect(url) {
  const params = new URL(url).searchParams;
  const res = await fetch('https://api.aureahub.com/v1/ramp/bank/customer/authorize/complete', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
    body: JSON.stringify({ state: params.get('state'), code: params.get('code') })
  });
  const data = await res.json();
  if (!res.ok) throw new Error(`${res.status} ${data.details?.code}`);
  return data.verification; // later: POST /v1/ramp/bank/customer/sync to read it again
}
```

---

Web version: https://docs.aureahub.com/#bank-customer-authorize
