# Contact accounts

These methods work with [contact accounts](https://support.watbot.org/chatbots/contacts/accounts-referrals#accounts) — an internal balance in the bot: bonuses, points, a deposit. These are the same accounts that the [Top up a contact's account](https://support.watbot.org/chatbots/blocks/contact-data/top-up-balance) and [Debit a contact's account](https://support.watbot.org/chatbots/blocks/contact-data/debit-balance) blocks work with and that are shown on the "Accounts" tab of the contact card. For example, a payment system can credit bonuses to the contact after a purchase on your website, and the bot can show the balance with the `getBalance` function.

A contact has a separate account for each currency. API operations appear in the account journal as "Deposit via API" and "Debit via API".

> [!WARNING]
> Contact accounts are the bot's internal balances (bonuses, points, deposit), not bank accounts: the platform doesn't transfer money through them and isn't a payment service. Keep a record of the operations you send through the API in your own system — you can use it to reconcile balances.

> [!IMPORTANT]
> Amounts are sent and returned **in the currency's minor units** — cents — as an integer. `15000` on a `USD` account means $150. For currencies without a fractional part, such as `JPY`, the unit is the whole yen. A single top-up or debit is at most 10¹⁴ minor units (a trillion dollars for USD); more returns `422`.

## getContactAccounts

Returns all accounts of a contact.

```endpoint
GET POST https://watbot.org/api/v1/getContactAccounts
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `contact_id` | integer | yes | Contact ID |

```bash title="Request"
curl -G "https://watbot.org/api/v1/getContactAccounts" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  --data-urlencode "contact_id=678"
```
```json title="Response 200"
{
  "data": [
    {
      "id": 4521,
      "currency": "USD",
      "amount": 15000,
      "amount_note": "150 USD",
      "created_at": "2026-09-14T10:22:05+00:00",
      "updated_at": "2026-10-01T18:40:12+00:00",
      "blocked_at": null
    }
  ]
}
```

| Field | Description |
|---|---|
| `id` | Account ID — pass it to the other methods as `account_id` |
| `currency` | ISO 4217 currency code |
| `amount` | Balance in the currency's minor units |
| `amount_note` | Balance in major units with the currency code, for display |
| `created_at`, `updated_at` | When the account was opened and last changed |
| `blocked_at` | When the account was blocked; `null` — not blocked. A blocked account cannot be debited |

Accounts are listed in the order they were opened.

## addContactAccount

Opens an account in a currency for the contact. The same method is also available as `createContactAccount`.

```endpoint
POST https://watbot.org/api/v1/addContactAccount
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `contact_id` | integer | yes | Contact ID |
| `currency` | string | yes | ISO 4217 currency code in capital letters: `USD`, `EUR`, `GBP` |

```bash title="Request"
curl -X POST "https://watbot.org/api/v1/addContactAccount" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"contact_id": 678, "currency": "USD"}'
```
```json title="Response 201"
{
  "data": {
    "id": 4521,
    "currency": "USD",
    "amount": 0,
    "amount_note": "0 USD",
    "created_at": "2026-10-03T12:00:00+00:00",
    "updated_at": "2026-10-03T12:00:00+00:00",
    "blocked_at": null
  }
}
```
```json title="Response 422"
{
  "message": "Account with the currency already exists",
  "code": "currency_exists",
  "errors": {
    "currency": [
      "Account with the currency already exists"
    ]
  }
}
```

Details:

- If the contact already has an account in this currency — `422` with an error in the `currency` field.
- Scenario blocks do not need the account in advance: the Top up a contact's account block opens it itself. The API top-up methods do need it, since they work by `account_id`.

## deleteContactAccount

Deletes a contact's account.

```endpoint
POST https://watbot.org/api/v1/deleteContactAccount
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `account_id` | integer | yes | Account ID |

```bash title="Request"
curl -X POST "https://watbot.org/api/v1/deleteContactAccount" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"account_id": 4521}'
```
```json title="Response 422"
{
  "message": "You can not delete the account with a balance of 150 USD",
  "code": "account_not_empty",
  "errors": {
    "account_id": [
      "You can not delete the account with a balance of 150 USD"
    ]
  }
}
```

The response is status `204` with no body.

Only an empty account can be deleted. If there is money on it — `422` with an error in the `account_id` field; debit the remaining balance first.

## addFundsToContactAccount

Tops up an account.

```endpoint
POST https://watbot.org/api/v1/addFundsToContactAccount
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `account_id` | integer | yes | Account ID |
| `amount` | integer | yes | Amount in the currency's minor units, from 1 to 100,000,000,000,000 (10¹⁴) |
| `description` | string | yes | What the deposit is for, up to 255 characters. Goes into the account journal |

```bash title="Request"
curl -X POST "https://watbot.org/api/v1/addFundsToContactAccount" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"account_id": 4521, "amount": 15000, "description": "Bonus for order A-1024"}'
```
```json title="Response 200"
{
  "data": {
    "id": 4521,
    "currency": "USD",
    "amount": 15000,
    "amount_note": "150 USD",
    "created_at": "2026-10-03T12:00:00+00:00",
    "updated_at": "2026-10-03T12:05:41+00:00",
    "blocked_at": null
  }
}
```

A blocked account can still be topped up.

## withdrawFundsFromContactAccount

Debits an account.

```endpoint
POST https://watbot.org/api/v1/withdrawFundsFromContactAccount
```

| Parameter | Type | Required | Description |
|---|---|---|---|
| `account_id` | integer | yes | Account ID |
| `amount` | integer | yes | Amount in the currency's minor units, from 1 to 100,000,000,000,000 (10¹⁴) |
| `description` | string | yes | What the debit is for, up to 255 characters. Goes into the account journal |

```bash title="Request"
curl -X POST "https://watbot.org/api/v1/withdrawFundsFromContactAccount" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"account_id": 4521, "amount": 5000, "description": "Delivery fee"}'
```
```json title="Response 200"
{
  "data": {
    "id": 4521,
    "currency": "USD",
    "amount": 10000,
    "amount_note": "100 USD",
    "created_at": "2026-10-03T12:00:00+00:00",
    "updated_at": "2026-10-03T12:07:15+00:00",
    "blocked_at": null
  }
}
```
```json title="Response 422"
{
  "message": "Insufficient funds. Current balance 100 USD",
  "code": "insufficient_funds",
  "errors": {
    "account_id": [
      "Insufficient funds. Current balance 100 USD"
    ]
  }
}
```

A debit never takes the account below zero, even with simultaneous requests. If the debit is not possible, the method changes nothing and responds with `422` and an error in the `account_id` field:

| `code` | Reason |
|---|---|
| `account_blocked` | The account is blocked — unblock it on the contact card |
| `insufficient_funds` | The account holds less than `amount`; the text shows the current balance |

The block is checked first, then the balance.

## Account errors

- No contact or account with that ID, the contact is deleted, or its bot is deleted — `404`.
- Contact or account from someone else's bot — `403`.
- Errors specific to these methods are `422` with `message`, `code` and `errors` fields. The error text is in the request language (the `Accept-Language` header), so check `code` in your code:

| `code` | Method | Reason |
|---|---|---|
| `currency_exists` | `addContactAccount` | An account in this currency already exists |
| `account_not_empty` | `deleteContactAccount` | There is money left on the account |
| `account_blocked` | `withdrawFundsFromContactAccount` | The account is blocked |
| `insufficient_funds` | `withdrawFundsFromContactAccount` | Not enough money on the account |

General API errors are described under [Errors](https://support.watbot.org/api#errors).
