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

# Test Your Integration in the Diameter Sandbox

> The Diameter sandbox lets you simulate inbound wires, test end-to-end payment flows, and verify webhook handlers without real money.

The Diameter sandbox is a fully isolated test environment that mirrors the production API surface without moving real funds. Every API call hits `api.sandbox.diameterpay.com` and `auth.sandbox.diameterpay.com` instead of the production hostnames, and all data — end users, accounts, payments, counterparties — lives only in the sandbox. Use it to build and verify your integration before going live.

> [!NOTE]
>
> Sandbox credentials are separate from production credentials. Generate your sandbox `client_id` and `client_secret` from the **Sandbox** section of the Diameter dashboard.

***

## Simulate an inbound wire

The sandbox exposes a `/v1/simulation/payments` endpoint that lets you credit a virtual account with test funds as if an inbound wire had arrived from an external bank. This triggers the same webhook events and balance updates that a real inbound wire would, letting you test your full receive-and-respond flow.

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/simulation/payments \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440040" \
  -H "Content-Type: application/json" \
  -d '{
    "scenario": "WIRE_INBOUND",
    "bank": "PORTAGE",
    "accountNumber": "YOUR_ACCOUNT_NUMBER",
    "amount": "500.00",
    "type": "DOMESTIC",
    "description": "Sandbox inbound wire for QA"
  }'
```

```json Response theme={null}
{
  "success": true,
  "scenario": "WIRE_INBOUND",
  "bank": "PORTAGE",
  "referenceKind": "FILENAME",
  "referenceValue": "WIRE_2026_02_13_0001.txt"
}
```

A successful simulation:

1. Credits `YOUR_ACCOUNT_NUMBER` with the specified amount in sandbox USD
2. Updates the account balance immediately (verifiable via `GET /v1/accounts/{id}/balance`)
3. Fires a `PAYMENT_WIRE_INBOUND_POSTED` webhook event to any matching subscriptions

> [!WARNING]
>
> The `/v1/simulation/payments` endpoint is **only available in the sandbox**. Calling it against the production base URL returns `403 Forbidden`.

> [!TIP]
>
> To skip the compliance screening step for internal transfers that get stuck in `SCREENING_REQUESTED`, prefix the `description` field with `AUTO_APPROVE` — for example, `"description": "AUTO_APPROVE liquidity test"`. This sandbox shortcut lets you test the full happy path without waiting for manual review.

***

## End-to-end test scenario checklist

Run through this checklist in order to validate every part of your integration — from user onboarding to final payment confirmation.

### Create an individual end user and wait for ACTIVE status

Post to `/v1/end-users/individuals` with test data. Poll `GET /v1/end-users/individuals/{id}` or wait for the `END_USER_UPDATED` webhook until `onboardingStatus` is `ACTIVE`.

```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-446655440041" \
  -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"]
  }'
```

See the [Onboard End User guide](https://diameterpay.mintlify.site/guides/onboard-end-user.md) for full details on this step.

### Find the virtual account number

Retrieve the account provisioned for this end user. Copy the `accountNumber` — you'll use it in the next step.

```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"
```

The response contains `accountNumber` (for use with the simulation endpoint) and the account `id` (UUID, for use as `debtorAccountId` in payments).

### Simulate an inbound wire to fund the account

Use the simulation endpoint to credit the account with test funds:

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/simulation/payments \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440042" \
  -H "Content-Type: application/json" \
  -d '{
    "scenario": "WIRE_INBOUND",
    "bank": "PORTAGE",
    "accountNumber": "ACCOUNT_NUMBER_FROM_STEP_2",
    "amount": "1000.00",
    "type": "DOMESTIC",
    "description": "Sandbox funding"
  }'
```

### Verify the account balance

Confirm the simulated inbound wire credited the account correctly:

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

```json Response theme={null}
{
  "accountId": "acct-3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "availableBalance": "1000.00",
  "currentBalance": "1000.00",
  "currency": "USD"
}
```

### Create a counterparty

Register the recipient account that will receive the outbound wire:

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/counter-parties \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440043" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "ORGANIZATION",
    "fullName": "Test Vendor LLC",
    "endUserId": "END_USER_ID",
    "bankPartner": "PORTAGE",
    "wireInformation": {
      "bankName": "Chase Bank",
      "accountNumber": "000123456789",
      "routingNumberType": "ABA",
      "routingNumber": "021000021",
      "address": {
        "addressType": "BIZZ",
        "country": "US",
        "postalCode": "10017",
        "townName": "New York",
        "streetName": "Park Avenue",
        "countrySubdivision": "NY",
        "buildingNumber": "270"
      }
    }
  }'
```

Copy the counterparty `id` from the response.

### Initiate an outbound domestic wire

Send the outbound payment using the debtor account and counterparty from the previous steps:

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/payments/wire/domestic \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440044" \
  -H "Content-Type: application/json" \
  -d '{
    "endToEndId": "E2E-TEST-001",
    "debtorAccountId": "ACCOUNT_UUID_FROM_STEP_2",
    "creditorId": "COUNTERPARTY_ID_FROM_STEP_5",
    "amount": "250.00",
    "currency": "USD",
    "description": "Sandbox outbound wire test"
  }'
```

Note the returned payment `id` for the next step.

### Verify the PAYMENT\_WIRE\_OUTBOUND\_COMPLETED webhook fires

Check that your webhook endpoint received the completion event. Confirm the payload contains the correct `contextId` (matching your payment `id`) and that `eventType` is `PAYMENT_WIRE_OUTBOUND_COMPLETED`.

You can also query the payment directly to confirm the status:

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

Expect `"status": "COMPLETED"` in the response.

***

## Testing webhooks locally

To receive sandbox webhook deliveries on your development machine, expose your local server to the internet using a tunneling tool:

```bash ngrok theme={null}
# Install ngrok, then run:
ngrok http 3000
# Use the generated https://xxxx.ngrok.io URL as your webhook subscription URL
```

```bash webhook.site theme={null}
# Visit https://webhook.site to get a free HTTPS URL
# Use it as your subscription URL to inspect incoming payloads visually
```

> [!TIP]
>
> When using ngrok, make sure to use the `https://` URL (not `http://`) — Diameter rejects non-HTTPS webhook endpoints. Update your subscription URL every time you restart ngrok, since free-tier URLs change on each session.


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