> ## 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 Initiate Wire Payments with Diameter

> Learn how to initiate domestic wire, international wire, and internal transfers using the Diameter API, with idempotency and status tracking.

The Diameter API supports three payment types: domestic wires (US ACH/wire routing), international wires (SWIFT/BIC routing), and internal transfers between accounts held at the same partner bank. All payment requests are idempotent — you supply a unique `x-idempotency-key` per request so that retries on network failures never create duplicate transactions. This guide walks you through initiating each payment type and tracking it through to completion.

### Confirm prerequisites

Make sure you have the following before initiating any payment:

* An end user with `onboardingStatus: ACTIVE` and at least one virtual account. If you haven't onboarded an end user yet, follow the [Onboard End User guide](https://diameterpay.mintlify.site/guides/onboard-end-user.md) first.
* A valid OAuth2 access token with the **`payments:write`** scope:

```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=payments:write"
```

* A funded sandbox account. Use the [Sandbox Testing guide](https://diameterpay.mintlify.site/guides/sandbox-testing.md) to simulate an inbound wire before sending outbound payments.

### Retrieve the debtor's account ID

Every payment request requires a `debtorAccountId` — the UUID of the virtual account you want to debit. Fetch it using the accounts endpoint for the end user's type:

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

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

Copy the `id` field from the account you want to debit. Keep the `bankPartner` value handy — your counterparty must be onboarded to the same bank for domestic and international wires.

### Initiate a payment

Choose the payment type that matches your use case.

#### Option A — Domestic wire

Send a `POST` to `/v1/payments/wire/domestic` to push USD funds via the US wire network to a counterparty's bank account. The counterparty must already exist in Diameter (see [Manage Counterparties](https://diameterpay.mintlify.site/guides/manage-counterparties.md)) or you can pass inline creditor data in the request body.

```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-446655440010" \
  -H "Content-Type: application/json" \
  -d '{
    "endToEndId": "WIRE-2024-001",
    "debtorAccountId": "ACCOUNT_UUID",
    "creditorId": "COUNTERPARTY_UUID",
    "amount": "500.00",
    "currency": "USD",
    "description": "Payment for services rendered"
  }'
```

```json Response theme={null}
{
  "id": "pay-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "endToEndId": "WIRE-2024-001",
  "creditorId": "COUNTERPARTY_UUID",
  "debtorAccountId": "ACCOUNT_UUID",
  "amount": "500.00",
  "currency": "USD",
  "status": "SCREENING_REQUESTED",
  "createdAt": "2024-01-15T10:30:00Z"
}
```

#### Option B — International wire

International wires follow the same structure as domestic wires but route through SWIFT. Post to `/v1/payments/wire/international` instead. The counterparty must have BIC (SWIFT code) routing configured — see the [Counterparties guide](https://diameterpay.mintlify.site/guides/manage-counterparties.md) for details on setting `routingNumberType: BIC`.

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/payments/wire/international \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440011" \
  -H "Content-Type: application/json" \
  -d '{
    "endToEndId": "INTL-2024-001",
    "debtorAccountId": "ACCOUNT_UUID",
    "creditorId": "BIC_COUNTERPARTY_UUID",
    "amount": "1000.00",
    "currency": "USD",
    "description": "International supplier payment"
  }'
```

> [!NOTE]
>
> Diameter automatically resolves the intermediary routing number for BIC-routed counterparties. You do not need to supply it manually.

#### Option C — Internal transfer

Use internal transfers to move funds between two virtual accounts held at the same partner bank — for example, between two of your end users, or to a treasury account. Internal transfers settle immediately in the sandbox and do not go through external wire networks.

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/payments/internal \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440012" \
  -H "Content-Type: application/json" \
  -d '{
    "endToEndId": "INT-2024-001",
    "debtorAccountId": "DEBIT_ACCOUNT_UUID",
    "creditorAccountId": "CREDIT_ACCOUNT_UUID",
    "amount": "100.00",
    "currency": "USD",
    "description": "Internal liquidity movement"
  }'
```

```json Response theme={null}
{
  "id": "pay-4a7bc1e2-8f3d-41a9-b562-1e09c4fd8e72",
  "endToEndId": "INT-2024-001",
  "debtorAccountId": "DEBIT_ACCOUNT_UUID",
  "creditorAccountId": "CREDIT_ACCOUNT_UUID",
  "amount": "100.00",
  "currency": "USD",
  "status": "COMPLETED",
  "createdAt": "2024-01-15T10:35:00Z"
}
```

> [!WARNING]
>
> The `x-idempotency-key` must be a unique UUID for each distinct payment request. If you reuse the same key with a **different payload**, the API returns `409 Conflict`. If you reuse it with the **identical payload** (a safe retry), the API returns the original response without creating a duplicate payment.

### Track payment status

Poll the payment endpoint to check its current status. Status progresses through the following states for outbound wires:

| Status | Meaning |
| - | - |
| `SCREENING_REQUESTED` | Under compliance review |
| `SCREENING_PASSED` | Compliance approved, queued for settlement |
| `ROUTED` | Payment handed off to the banking network |
| `RECEIVED_BY_PARTNER` | Partner bank has accepted the payment |
| `COMPLETED` | Funds successfully delivered |
| `FAILED` | Payment could not be processed |

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

```json Response theme={null}
{
  "id": "pay-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "endToEndId": "WIRE-2024-001",
  "status": "COMPLETED",
  "amount": "500.00",
  "currency": "USD",
  "completedAt": "2024-01-15T10:31:45Z"
}
```

> [!TIP]
>
> To look up a payment by your own reference rather than Diameter's UUID, use the search endpoint: `POST /v1/payments/search` with the body `{"endToEndId": "WIRE-2024-001"}`. This is especially useful when reconciling payments from your internal ledger.

### Handle payment webhooks

Subscribe to payment events so your system reacts in real time rather than polling. See the [Webhooks guide](https://diameterpay.mintlify.site/guides/webhooks.md) for subscription setup and signature verification.

The key events for outbound wires are:

| Event | When it fires |
| - | - |
| `PAYMENT_WIRE_OUTBOUND_SCREENING_REQUESTED` | Compliance review has started |
| `PAYMENT_WIRE_OUTBOUND_SCREENING_PASSED` | Compliance approved the payment |
| `PAYMENT_WIRE_OUTBOUND_COMPLETED` | Payment settled successfully |
| `PAYMENT_WIRE_OUTBOUND_FAILED` | Payment could not be completed |

```json PAYMENT_WIRE_OUTBOUND_COMPLETED payload theme={null}
{
  "eventId": "evt-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "eventType": "PAYMENT_WIRE_OUTBOUND_COMPLETED",
  "contextId": "pay-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "contextType": "PAYMENT",
  "subscriptionId": "sub-uuid",
  "data": {
    "paymentId": "pay-9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
    "endToEndId": "WIRE-2024-001",
    "amount": "500.00",
    "currency": "USD"
  },
  "timestamp": "2024-01-15T10:31:45Z"
}
```

> [!NOTE]
>
> If a payment lands in `PAYMENT_WIRE_OUTBOUND_FAILED`, retrieve the full payment object via `GET /v1/payments/{id}` to read the `failureReason` field before retrying.


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