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

# How to Onboard an End User with Diameter

> Step-by-step guide to creating individual or organization end users, tracking their onboarding status, and retrieving their virtual accounts.

The Diameter API lets you onboard individual consumers or business organizations as end users on behalf of your product. Once onboarded, each end user receives a virtual account at the partner bank you specify, which you can then fund and transact against. This guide walks you through every step — from creating the end user record to retrieving their account details.

### Confirm prerequisites

Before you create an end user, make sure you have the following ready:

* A valid OAuth2 access token with the **`end-users:write`** scope. Obtain one by posting your client credentials to the token endpoint:

```bash cURL theme={null}
curl -X POST https://auth.sandbox.diameterpay.com/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "scope=end-users:write"
```

* Your **`productId`** — a UUID that links the end user to your specific product configuration in Diameter. You can find this in the Diameter dashboard under **Products**.

> [!NOTE]
>
> If you want to reference the end user by your own internal identifier later, include an **`internalEndUserIdentifier`** field in the request body. Diameter stores it alongside the record and you can use it for lookups.

### Create an individual end user

Send a `POST` request to `/v1/end-users/individuals` with the user's personal and identity details. Include a unique `x-idempotency-key` header so that retries on network failures don't create duplicate records.

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/end-users/individuals \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "YOUR_PRODUCT_ID",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane.smith@example.com",
    "mobilePhone": "+12125551234",
    "dateOfBirth": "1990-05-15",
    "nationality": "US",
    "idType": "PASSPORT",
    "idNumber": "P987654321",
    "idCountry": "US",
    "pepStatus": "NO",
    "primaryAddress": {
      "addressType": "HOME",
      "country": "US",
      "postalCode": "10001",
      "townName": "New York",
      "streetName": "Broadway",
      "buildingNumber": "350",
      "countrySubdivision": "NY"
    },
    "onboardInBanks": ["PORTAGE"]
  }'
```

```json Response theme={null}
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "productId": "YOUR_PRODUCT_ID",
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane.smith@example.com",
  "onboardingStatus": "INACTIVE",
  "onboardedInBanks": [],
  "createdAt": "2024-01-15T10:00:00Z"
}
```

The response immediately returns an `id` for the new end user. Notice that `onboardingStatus` starts as **`INACTIVE`** and `onboardedInBanks` is empty — the partner bank's compliance checks run asynchronously in the background.

> [!NOTE]
>
> To onboard the same end user at a second bank after they are already `ACTIVE`, send a `PATCH` request to `/v1/end-users/{id}/onboard` with the body `{"bankPartner": "SLOVAK_SAVINGS_BANK"}`. You don't need to re-submit identity documents.

### Track onboarding status

Poll the individual end user endpoint to check whether onboarding has completed. In production, onboarding typically takes a few minutes; in the sandbox it completes within seconds.

```bash cURL theme={null}
curl -X GET https://api.sandbox.diameterpay.com/v1/end-users/individuals/END_USER_ID \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

```json Response (onboarding complete) theme={null}
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "onboardingStatus": "ACTIVE",
  "onboardedInBanks": ["PORTAGE"],
  "createdAt": "2024-01-15T10:00:00Z",
  "updatedAt": "2024-01-15T10:02:35Z"
}
```

When `onboardingStatus` is **`ACTIVE`** and the target bank appears in `onboardedInBanks`, the end user is fully onboarded and ready to transact.

### Wait for the `END_USER_UPDATED` webhook

Rather than polling, subscribe to the **`END_USER_UPDATED`** event so Diameter notifies your system the moment the status changes. See the [Webhooks guide](https://diameterpay.mintlify.site/guides/webhooks.md) for subscription setup and signature verification.

```json Webhook payload example theme={null}
{
  "eventId": "evt-7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "eventType": "END_USER_UPDATED",
  "contextId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "contextType": "END_USER",
  "data": {
    "onboardingStatus": "ACTIVE",
    "onboardedInBanks": ["PORTAGE"]
  },
  "timestamp": "2024-01-15T10:02:35Z"
}
```

> [!TIP]
>
> Use the `eventId` field to deduplicate webhook deliveries. Diameter may deliver the same event more than once during retry sequences.

### Retrieve the end user's virtual accounts

Once the end user is `ACTIVE`, fetch their virtual account details. You will need the `accountNumber` and wire instructions when simulating inbound payments or sharing funding details with the end user.

```bash cURL theme={null}
curl -X GET https://api.sandbox.diameterpay.com/v1/end-users/individuals/END_USER_ID/accounts \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

```json Response theme={null}
{
  "accounts": [
    {
      "id": "acct-3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "endUserId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "bankPartner": "PORTAGE",
      "currency": "USD",
      "accountNumber": "8881234567890",
      "routingNumber": "071004764",
      "wireInstructions": {
        "bankName": "Portage Bank",
        "accountNumber": "8881234567890",
        "routingNumber": "071004764",
        "accountType": "CHECKING"
      },
      "status": "ACTIVE"
    }
  ]
}
```

Store the `id` (account UUID) — you will reference it as `debtorAccountId` when initiating outbound payments.

***

## Onboarding organization end users

The flow for organizations is identical to individuals. The only difference is the endpoint and required fields. Send a `POST` to `/v1/end-users/organizations` with the following business-specific fields instead of personal identity fields:

| Field | Description |
| - | - |
| `fullName` | Legal business name |
| `doingBusinessAs` | Trading name, if different from legal name |
| `businessIndustry` | Industry classification code |
| `businessEntityType` | e.g. `LLC`, `CORPORATION`, `PARTNERSHIP` |
| `formationDate` | Date the entity was formed (ISO 8601) |
| `incorporationCountry` | Two-letter country code |
| `idType` | Business identifier type, e.g. `EIN` |
| `idNumber` | The actual identifier number |

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/end-users/organizations \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440001" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "YOUR_PRODUCT_ID",
    "fullName": "Acme Fintech LLC",
    "doingBusinessAs": "Acme Pay",
    "businessIndustry": "FINANCIAL_SERVICES",
    "businessEntityType": "LLC",
    "formationDate": "2018-03-20",
    "incorporationCountry": "US",
    "idType": "EIN",
    "idNumber": "12-3456789",
    "onboardInBanks": ["PORTAGE"]
  }'
```

Once submitted, track status and retrieve accounts exactly as described in the steps above — the `onboardingStatus` lifecycle and webhook events are the same for both end user types.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.