# Customer Deposit Accounts

> Give each customer reusable crypto addresses and a bank account to fund their balance.

Section: Build with AI
Source: https://coincircuit.io/docs/guides/customer-deposit-accounts/
Interactive version: https://coincircuit.io/api-reference?tab=guides&guide=customer-deposit-accounts

Tags: Deposits, Webhooks, Customers

Paste this prompt into Claude, ChatGPT, or any AI tool. It works best with the CoinCircuit MCP server connected: https://mcp.coincircuit.io

---

You are helping me add CoinCircuit deposit accounts to my existing application, so each of my customers gets reusable pay-in details that fund my balance. I have the CoinCircuit MCP server connected.

**If you have access to the CoinCircuit MCP server, call these tools for the most accurate and detailed schema outputs:**
- Call `get_api_overview` in the CoinCircuit MCP for base URLs, auth method, and available features.
- Call `search_api` with feature `Deposits` to list every deposit endpoint.
- Call `get_endpoint` with method `post` and path `/api/v1/deposits/accounts` for the account creation schema.
- Call `get_endpoint` with method `post` and path `/api/v1/deposits/accounts/{id}/identities` for the identity (crypto address / virtual account) schema.
- Call `get_endpoint` with method `get` and path `/api/v1/deposits` for the deposits list schema.
- Call `get_schema` with name `DepositDto` for the deposit object used by `GET /api/v1/deposits/{id}` and the deposit webhooks.

Use the live MCP data as your source of truth. The details below are a guide, but if the MCP returns something different, trust the MCP.

## API Basics

- **Base URL (production):** `https://api.coincircuit.io`
- **Base URL (sandbox):** `https://sandbox-api.coincircuit.io`
- **Auth:** Pass your API key in the `x-api-key` header on every request.

## Project Context

I want each of my customers to have a fixed place to send me funds: a permanent crypto address on each blockchain, and a Nigerian bank account number for fiat transfers. The customer reuses the same details for every deposit, and CoinCircuit detects each one, attributes it to that customer, and credits it to my balance.

The flow:

1. Create a deposit account for a customer.
2. Issue one or more pay-in identities on it (a crypto address on a blockchain, or an NGN virtual account).
3. Show the address or account number to the customer.
4. Listen for deposit webhooks and credit the customer in my own system.

## What I Need You to Implement

### 1. Create a deposit account

**Endpoint:** `POST /api/v1/deposits/accounts`
*(Call `get_endpoint` with method `post`, path `/api/v1/deposits/accounts` in the CoinCircuit MCP for the full request/response schema.)*

- `customerId` (string, optional) - the customer this account belongs to. Omit it to create a deposit account for your own (parent) balance.

**Response (201):** Returns the deposit account with an `id`. Use that `id` to issue identities in the next step.

### 2. Issue a pay-in identity

**Endpoint:** `POST /api/v1/deposits/accounts/{id}/identities`
*(Call `get_endpoint` with method `post`, path `/api/v1/deposits/accounts/{id}/identities` in the CoinCircuit MCP for the exact request body.)*

There are two identity types:

- **Static crypto address:** `{ "type": "static_deposit_address", "chain": "bsc" }`. `chain` is one of `bitcoin`, `ethereum`, `solana`, `bsc`, `tron`, `base`, `arbitrum`. Returns a permanent address on that blockchain.
- **NGN virtual account:** `{ "type": "ngn_virtual_account", "bvn": "12345678901", "currency": "NGN" }`. Returns a bank account number the customer can transfer to. `bvn` is your 11-digit merchant BVN.

Issue both on the same account so a customer can fund by crypto or by bank transfer.

### 3. Show the details to your customer

Display the crypto address (with its blockchain and a QR code) or the bank account number. The customer reuses the same details every time; do not issue a new identity per deposit.

### 4. Handle deposit webhooks

*(Call `get_schema` with name `DepositDto` in the CoinCircuit MCP for every field in the deposit payload.)*

The deposit webhook payload is `{ event, data }`, where `data` is the deposit object:

- `data.id` - the deposit id
- `data.type` - `"crypto"` or `"fiat"` (one of `data.crypto` / `data.fiat` is populated, the other is null)
- `data.currency`, `data.amount`, `data.fee` - decimal strings
- `data.depositAccountId` and `data.customerId` - which account and customer the deposit belongs to (`customerId` is null for your parent account)
- `data.status` and `data.completedAt`

**Deposit events:**

- `deposit.processing` - a deposit was detected and is being processed.
- `deposit.completed` - the deposit cleared and was credited to your balance. **Credit your customer in your own system here.**
- `deposit.failed` - the deposit was rejected by a compliance check.

**Webhook security:** verify the HMAC-SHA256 signature in the `x-coincircuit-signature` header, and use `x-coincircuit-delivery-id` for idempotency.

### 5. List and reconcile deposits

- List deposits with `GET /api/v1/deposits`.
- Get one with `GET /api/v1/deposits/{id}`.
- List a customer's accounts with `GET /api/v1/deposits/accounts/customer/{customerId}`, or your own with `GET /api/v1/deposits/accounts/parent`.

## Constraints

- A crypto address and a bank account number are permanent per customer. Reuse them; never issue a new identity per deposit.
- Match a deposit to a customer with `data.customerId`. A null `customerId` means it landed in your own parent account.
- NGN virtual accounts require your merchant BVN and settle in NGN.
- Credit your customer on `deposit.completed`, not `deposit.processing`.
- Amounts and fees are decimal strings.
