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

# Diameter API Quickstart: Your First API Call in 15 Minutes

> Learn how to authenticate, onboard your first end user, and initiate a domestic wire payment using the Diameter API in under 15 minutes.

This guide walks you through everything you need to make your first successful Diameter API call: obtaining credentials, authenticating, verifying your tenant, creating an end user, and sending a domestic wire payment. You will be up and running in under 15 minutes.

## Environments

Use the sandbox environment for all development and testing. Switch to production only when you are ready to go live.

| Environment | Base URL |
| - | - |
| **Sandbox** | `https://api.sandbox.diameterpay.com` |
| **Production** | `https://api.prod.diameterpay.com` |

**1. Get Your Credentials**

Before you can make any API calls, you need a **Client ID** and **Client Secret** for your Tenant.

Send an email to [support@diameterpay.com](mailto:support@diameterpay.com) requesting sandbox access. Include:

* Your company name and website
* A brief description of your use case
* The partner bank(s) you intend to use (Portage Bank or Slovak Savings Bank)

The Diameter team will provision your Tenant, configure an initial Product, and reply with your `client_id` and `client_secret`. Store these values securely — treat them like passwords. Never commit them to source control or expose them in client-side code.

> [!WARNING]
>
> Your `client_secret` is shown only once during provisioning. If you lose it, contact support to rotate your credentials.

**2. Obtain an Access Token**

Diameter uses the **OAuth 2.0 Client Credentials** flow. Exchange your `client_id` and `client_secret` for a short-lived Bearer token by posting to the token endpoint. Tokens are valid for **600 seconds (10 minutes)**.

```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=com.diameterpay.api/end-users.write com.diameterpay.api/payments.write"
```

```python Python theme={null}
import requests

response = requests.post(
    "https://auth.sandbox.diameterpay.com/oauth2/token",
    data={
        "grant_type": "client_credentials",
        "client_id": "YOUR_CLIENT_ID",
        "client_secret": "YOUR_CLIENT_SECRET",
        "scope": "com.diameterpay.api/end-users.write com.diameterpay.api/payments.write",
    },
)
token = response.json()["access_token"]
```

```javascript Node.js theme={null}
const params = new URLSearchParams();
params.append("grant_type", "client_credentials");
params.append("client_id", "YOUR_CLIENT_ID");
params.append("client_secret", "YOUR_CLIENT_SECRET");
params.append(
  "scope",
  "com.diameterpay.api/end-users.write com.diameterpay.api/payments.write"
);

const res = await fetch(
  "https://auth.sandbox.diameterpay.com/oauth2/token",
  { method: "POST", body: params }
);
const { access_token } = await res.json();
```

A successful response looks like:

```json theme={null}
{
  "access_token": "eyJraWQiOiJzYW5kYm94LTIwMjQiLCJhbGciOiJSUzI1NiJ9...",
  "token_type": "bearer",
  "expires_in": 600
}
```

Copy the `access_token` value — you will use it as a Bearer token in every subsequent request.

> [!TIP]
>
> Request only the scopes your workflow needs. For a full list of available scopes, see the [Authentication](https://diameterpay.mintlify.site/authentication.md#scopes) page.

**3. Verify Your Tenant**

Before building further, confirm your credentials and network connectivity by fetching your Tenant record.

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

```python Python theme={null}
import requests

headers = {"Authorization": f"Bearer {token}"}
resp = requests.get(
    "https://api.sandbox.diameterpay.com/v1/tenants/self",
    headers=headers,
)
print(resp.json())
```

The response returns your Tenant's ID, name, configured Products, and feature flags. If you receive a `200 OK`, your credentials are working correctly.

```json theme={null}
{
  "id": "ten_01hx4kz2v3e8r9bf0cydq7mp6n",
  "name": "Acme Fintech Inc.",
  "status": "active",
  "products": [
    {
      "id": "prd_01hx4kz2v3e8portage001",
      "bankName": "Portage Bank",
      "type": "proprietary",
      "currency": "USD"
    }
  ]
}
```

Note the `products[].id` value — you will need it in the next step.

**4. Create an Individual End User**

Onboard your first end user by posting their identity and compliance data. The `productId` field links the user to the bank product you verified in the previous step.

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/end-users/individuals \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-idempotency-key: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11" \
  -d '{
    "productId": "prd_01hx4kz2v3e8portage001",
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane.doe@example.com",
    "mobilePhone": "+14155550192",
    "dateOfBirth": "1990-06-15",
    "nationality": "US",
    "idType": "PASSPORT",
    "idNumber": "US1234567",
    "idCountry": "US",
    "pepStatus": "NOT_PEP",
    "primaryAddress": {
      "street1": "123 Market Street",
      "street2": "Apt 4B",
      "city": "San Francisco",
      "state": "CA",
      "postalCode": "94105",
      "country": "US"
    },
    "onboardInBanks": ["PORTAGE"]
  }'
```

```python Python theme={null}
import requests, uuid

headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json",
    "x-idempotency-key": str(uuid.uuid4()),
}

payload = {
    "productId": "prd_01hx4kz2v3e8portage001",
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane.doe@example.com",
    "mobilePhone": "+14155550192",
    "dateOfBirth": "1990-06-15",
    "nationality": "US",
    "idType": "PASSPORT",
    "idNumber": "US1234567",
    "idCountry": "US",
    "pepStatus": "NOT_PEP",
    "primaryAddress": {
        "street1": "123 Market Street",
        "street2": "Apt 4B",
        "city": "San Francisco",
        "state": "CA",
        "postalCode": "94105",
        "country": "US",
    },
    "onboardInBanks": ["PORTAGE"],
}

resp = requests.post(
    "https://api.sandbox.diameterpay.com/v1/end-users/individuals",
    headers=headers,
    json=payload,
)
end_user = resp.json()
print(end_user["id"])
```

A `201 Created` response returns the new end user record including the Diameter-assigned `id` and the bank-assigned account details (once bank onboarding processing completes).

```json theme={null}
{
  "id": "usr_01hx4mq9r7f3a2bc5dn0ep8vkj",
  "status": "pending_bank_onboarding",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "productId": "prd_01hx4kz2v3e8portage001",
  "createdAt": "2024-11-01T10:23:45Z"
}
```

The `status` moves from `pending_bank_onboarding` → `active` asynchronously. Subscribe to webhooks to receive real-time status updates, or poll `GET /v1/end-users/individuals/{id}` until status is `active`.

**5. Initiate a Domestic Wire Payment**

Once your end user is `active` and has a funded virtual account, you can initiate a domestic wire. Supply the `debtorAccountId` (the source account), creditor details, amount, and a unique `endToEndId` for payment tracking.

```bash cURL theme={null}
curl -X POST https://api.sandbox.diameterpay.com/v1/payments/wire/domestic \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-idempotency-key: b2d05e00-7d2b-4a19-8c6e-3f1f2a4c5b7d" \
  -d '{
    "debtorAccountId": "acc_01hx4nr5t8g2b3cd6eo1fq9wlm",
    "creditorId": "cpt_01hx4nr5t8g2b3cd6eo1fq9abc",
    "amount": "250.00",
    "currency": "USD",
    "description": "Invoice #1042 payment",
    "endToEndId": "E2E-INV1042-20241101"
  }'
```

```python Python theme={null}
import requests, uuid

headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json",
    "x-idempotency-key": str(uuid.uuid4()),
}

payload = {
    "debtorAccountId": "acc_01hx4nr5t8g2b3cd6eo1fq9wlm",
    "creditorId": "cpt_01hx4nr5t8g2b3cd6eo1fq9abc",
    "amount": "250.00",
    "currency": "USD",
    "description": "Invoice #1042 payment",
    "endToEndId": "E2E-INV1042-20241101",
}

resp = requests.post(
    "https://api.sandbox.diameterpay.com/v1/payments/wire/domestic",
    headers=headers,
    json=payload,
)
print(resp.json())
```

Instead of referencing a saved `creditorId`, you can also pass inline creditor details:

```json theme={null}
{
  "debtorAccountId": "acc_01hx4nr5t8g2b3cd6eo1fq9wlm",
  "creditor": {
    "name": "Acme Supplies LLC",
    "accountNumber": "000123456789",
    "routingNumber": "021000021",
    "bankName": "JP Morgan Chase"
  },
  "amount": "250.00",
  "currency": "USD",
  "description": "Invoice #1042 payment",
  "endToEndId": "E2E-INV1042-20241101"
}
```

A `202 Accepted` response confirms the payment has been queued for processing:

```json theme={null}
{
  "id": "pmt_01hx4ps6u9h3c4de7fp2gr0xnq",
  "status": "SCREENING_REQUESTED",
  "amount": "250.00",
  "currency": "USD",
  "endToEndId": "E2E-INV1042-20241101",
  "createdAt": "2024-11-01T10:31:00Z"
}
```

Track the payment by polling `GET /v1/payments/{id}` or by listening for `payment.completed` and `payment.failed` webhook events.

## Idempotency

> [!NOTE]
>
> All write requests (`POST`, `PATCH`, `PUT`) require an **`x-idempotency-key`** header. Use a unique value per logical operation — a UUID v4 is a good choice. If you retry a request with the same idempotency key, Diameter returns the original response instead of creating a duplicate record. Idempotency keys are scoped to your Tenant and expire after 24 hours.

## Next Steps

> [card] [Authentication](https://diameterpay.mintlify.site/authentication.md)
>
> Learn how tokens work, which scopes to request, and how to handle expiry gracefully.

> [card] [Core Concepts](https://diameterpay.mintlify.site/concepts/tenants-and-products.md)
>
> Deep-dive into Tenants, Products, End Users, Accounts, and the payment lifecycle.

> [card] [Webhooks](https://diameterpay.mintlify.site/guides/webhooks.md)
>
> Subscribe to real-time events so you never have to poll for status changes.


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