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

# Customers

> Hold and attribute money for your own end users.

A **customer** is one of your end users. You create them, you own the relationship, and StableMint
never contacts them. What StableMint does is hold and attribute their money: incoming payments are
reconciled to the right customer, and their deposits and withdrawals are tracked separately from
your own.

In the API they are simply `customers`. Internally you may see them called customers.

## Two ways to attribute an incoming payment

This is the first decision to make, and it has a cost attached.

<CardGroup cols={2}>
  <Card title="A virtual IBAN per customer" icon="id-badge">
    Provision each customer their own IBAN. Anything arriving at it is attributed to that customer
    automatically — no reference needed, nothing for the payer to get wrong.
  </Card>

  <Card title="A shared IBAN plus a reference" icon="hashtag">
    Customers pay into your account and quote a reference you generated. You call the deposit
    endpoint first to mint that reference, then reconcile on it.
  </Card>
</CardGroup>

<Warning>
  **Virtual IBANs are chargeable.** Each one carries a cost that StableMint passes through to you.
  A reference-based deposit does not. For a customer who pays once, the reference is usually right;
  for one who pays repeatedly, the dedicated IBAN pays for itself in reconciliation you no longer
  have to do.
</Warning>

You can mix both across your customer base, and a customer with a virtual IBAN can still be sent a
reference-based deposit.

## Create a customer

```bash theme={null}
curl -X POST https://api.stablemint.net/v1/customers \
  -H "ApiKey: $STABLEMINT_API_KEY" \
  -H "Timestamp: $TIMESTAMP" \
  -H "Nonce: $NONCE" \
  -H "Signature: $SIGNATURE" \
  -H "Content-Type: application/json" \
  -d '{
    "partnerCustomerIdentifier": "acct_88213",
    "email": "maria@example.com",
    "kyc": {
      "customerType": "Individual",
      "fullName": "Maria Silva",
      "residenceAddress": "Rua Augusta 12, 1100-048 Lisboa, Portugal",
      "citizenshipCountryCode": "PT",
      "dateOfBirth": "1988-04-02"
    }
  }'
```

`partnerCustomerIdentifier` is **your** identifier for this person. Pass the primary key you already
use and every StableMint record stays joinable to your own database. StableMint returns its own
`guid`, which is what the rest of the API takes.

| Field                                    | Required | Notes                                                         |
| ---------------------------------------- | -------- | ------------------------------------------------------------- |
| `partnerCustomerIdentifier`              | Yes      | Your id for the customer.                                     |
| `email`                                  | No       |                                                               |
| `kyc.customerType`                       | Yes      | `Individual` or `Business`.                                   |
| `kyc.fullName`                           | Yes      | Legal name for an individual, registered name for a business. |
| `kyc.residenceAddress`                   | Yes      |                                                               |
| `kyc.citizenshipCountryCode`             | Yes      | ISO 3166-1 alpha-2.                                           |
| `kyc.dateOfBirth`                        | No       | Individuals.                                                  |
| `kyc.mobilePhone`                        | No       |                                                               |
| `kyc.personalIdentificationNumber`       | No       |                                                               |
| `kyc.uboFirstName1–5` / `uboLastName1–5` | No       | Beneficial owners, for `Business` customers. Up to five.      |

<Note>
  Send only what you are asked for. Every additional identity field you pass is personal data
  StableMint then holds on your behalf, and it widens your obligations under GDPR without widening
  what the platform can do for you.
</Note>

## Provision a virtual IBAN

```bash theme={null}
curl -X POST https://api.stablemint.net/v1/customers/{id}/account \
  -H "ApiKey: $STABLEMINT_API_KEY" \
  -H "Timestamp: $TIMESTAMP" \
  -H "Nonce: $NONCE" \
  -H "Signature: $SIGNATURE"
```

The account is opened in the customer's name. The response carries an `iban` and `country`, plus an
`ibans` array — a customer may end up with more than one IBAN, in different countries, all feeding
the same underlying balance.

<Warning>
  **Get the identity right before you provision.** The virtual IBAN is opened using the customer's
  KYC details, so changing those details afterwards does not re-issue the account. Updating a
  customer who already holds a virtual IBAN is restricted for this reason — treat the identity as
  settled at the point you call this endpoint.
</Warning>

## Create a reference-based deposit

For customers without their own IBAN. You tell StableMint a payment is expected; it returns the
reference and the account to pay into.

```bash theme={null}
curl -X POST https://api.stablemint.net/v1/customers/{id}/deposit \
  -H "ApiKey: $STABLEMINT_API_KEY" \
  -H "Timestamp: $TIMESTAMP" \
  -H "Nonce: $NONCE" \
  -H "Signature: $SIGNATURE" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 2500.00, "currency": "EUR", "idempotencyKey": "dep-2026-09-14-001" }'
```

```json theme={null}
{
  "customerId": "8f2c...",
  "amount": 2500.00,
  "currency": "EUR",
  "reference": "SM-4K2P-9QX7",
  "publicReference": "SM-4K2P-9QX7",
  "status": "Pending",
  "expiresAt": "2026-09-21T23:59:59Z",
  "fundingInstructions": {
    "beneficiaryName": "Acme Payments Ltd",
    "bankName": "Example Bank",
    "iban": "MT00XXXX00000000000000000000",
    "bic": "XXXXMTMT"
  }
}
```

Show `fundingInstructions` and `publicReference` to your customer verbatim. A payment that arrives
without the reference, or after `expiresAt`, has nothing to match against and needs manual
reconciliation.

Always send an `idempotencyKey` — a retried call with the same key returns the original deposit
instead of creating a second one.

## Customer balances are not spendable balances

<Warning>
  The `customerActivity` figures on [`GET /v1/accounts`](/guides/accounts-and-balances) are
  **deposit, withdrawal and net figures** — not an authoritative balance, and they are aggregate
  across your customers rather than per customer.

  StableMint knows what came in and what went out. It does not know about anything that changed a
  customer's position without moving through the platform: winnings, losses, yield you pay, fees you
  charge. If your product does any of those, `customerBalance` is **not** what your customer can
  spend, and you must keep that figure yourself.
</Warning>

There is no per-customer balance endpoint. To reconstruct one customer's position, list their
transactions and sum them yourself — see [below](#listing-a-customers-transactions).

For a straightforward pass-through model — money in, money out, nothing else — net deposits and
the spendable balance are the same number, and you can use it directly. Confirm that describes your
product before you rely on it.

## Listing a customer's transactions

Use the transactions endpoint with a filter rather than a customer-scoped path:

```bash theme={null}
# every customer's completed transactions
curl "https://api.stablemint.net/v1/transactions?scope=Customer&status=Completed" \
  -H "ApiKey: $STABLEMINT_API_KEY" \
  -H "Timestamp: $TIMESTAMP" \
  -H "Nonce: $NONCE" \
  -H "Signature: $SIGNATURE"
```

For a single customer, add `partnerCustomerGuid`:

```bash theme={null}
curl "https://api.stablemint.net/v1/transactions?scope=Customer&partnerCustomerGuid=3f2a9c14-7b5e-4d21-9c6a-8e0f1d2b3c45" \
  -H "ApiKey: $STABLEMINT_API_KEY" \
  -H "Timestamp: $TIMESTAMP" \
  -H "Nonce: $NONCE" \
  -H "Signature: $SIGNATURE"
```

See [Transactions](/guides/transactions) for the full filter set.
