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

# Signing Up a Customer · Overview

> Covers the two-step registration flow for end users under the DeCard-Managed model: request a verification code (SMS or email) first, then register with the OTP to obtain an externalUserId. Includes the code-sending and registration endpoints, their fields, encrypted transmission, and error handling and resends.

## 📄 Guide

Under the DeCard-Managed model, **the user comes before the card**: an end user must register first to obtain an `externalUserId`, which then identifies that user across every subsequent endpoint — KYC, card issuance, top-ups, spending, balance queries, and so on. As a licensed issuer with its own BINs, DCS creates a dedicated account for each cardholder, and registration is completed with a phone number or email address plus a one-time passcode (OTP).

Registration is a **two-step flow**: request the verification code, then register with it.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-signup-flow-light.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=a58fb0ea2e8c7820b2e05dcde785f96a" alt="Customer sign-up and OTP verification flow" width="496" height="344" data-path="imgs/en/diagrams/va-signup-flow-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/dcs-0bf7a937/oUoeUKtwWWK2o-Li/imgs/en/diagrams/va-signup-flow-dark.svg?fit=max&auto=format&n=oUoeUKtwWWK2o-Li&q=85&s=b57fe8c5bd96e36500aa2c3a8acbcc25" alt="Customer sign-up and OTP verification flow" width="496" height="344" data-path="imgs/en/diagrams/va-signup-flow-dark.svg" />
</Frame>

> `behavioral=REGISTER` marks this code request as a registration scenario (see step 1 for the field description).
>
> DCS creates a **dedicated account** for each cardholder, with its own available and frozen balances. For account status and asset management, see [Managing Users](../managing-users/overview); this is the entry point to the DeCard-Managed, dedicated-account model.

## Prerequisites

* Your Enterprise account is active and you hold your `ApiKey` / `SecretKey`. If you do not have them yet, see [First Steps](../../getting-started/first-steps) and the [authentication guide](../../integration-resources/overview).
* Every request must carry the signature headers described in the authentication guide. The examples on this page omit those headers and show business fields only.

## Step 1 · Send the verification code

Call one of the two code-sending endpoints, depending on the registration method. For both endpoints the **only required field is `behavioral`**, and for registration it is always `REGISTER`.

| Registration method | Endpoint                            |
| ------------------- | ----------------------------------- |
| Phone number        | `POST /captcha/v1/send-mobile-code` |
| Email address       | `POST /captcha/v1/send-email-code`  |

### Sending an SMS code

```
POST /captcha/v1/send-mobile-code
```

```json theme={null}
{
  "mobileCode": "SG",
  "mobile": "91234567",
  "behavioral": "REGISTER"
}
```

| Field            | Type   | Required  | Description                                                                                                                                                                                                                                   |
| ---------------- | ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `behavioral`     | string | **Yes**   | Scenario enum: `REGISTER` (registration) / `CARD_UNFROZEN` (unfreeze a card) / `WITHDRAW` (withdrawal). Pass `REGISTER` for registration                                                                                                      |
| `mobileCode`     | string | Either/or | Phone country code as an ISO letter code, such as `CN`, `US`, `SG`                                                                                                                                                                            |
| `mobile`         | string | Either/or | Phone number without the country code; **can be sent AES-encrypted or in plaintext** (see the encryption section below)                                                                                                                       |
| `externalUserId` | string | Either/or | User ID. A user being registered has no `externalUserId` yet, so leave it out and send `mobileCode` + `mobile` instead; for other scenarios on an existing user (unfreezing a card, withdrawing funds), you may send `externalUserId` instead |

### Sending an email code

```
POST /captcha/v1/send-email-code
```

```json theme={null}
{
  "email": "user@example.com",
  "behavioral": "REGISTER"
}
```

| Field            | Type   | Required  | Description                                                                                                                              |
| ---------------- | ------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `behavioral`     | string | **Yes**   | Scenario enum: `REGISTER` (registration) / `CARD_UNFROZEN` (unfreeze a card) / `WITHDRAW` (withdrawal). Pass `REGISTER` for registration |
| `email`          | string | Either/or | Email address; **can be sent AES-encrypted or in plaintext**                                                                             |
| `externalUserId` | string | Either/or | User ID. Leave it out when registering and send `email` instead; for an existing user you may send `externalUserId` instead              |

A successful response from a code-sending endpoint (the envelope is the site-wide `{code, message, messageDetail, data}`, with no `success` boolean; the success code is `code = SYS_SUCCESS`):

```json theme={null}
{
  "code": "SYS_SUCCESS",
  "message": null,
  "messageDetail": null,
  "data": ""
}
```

> `messageDetail` is a display-oriented structure (`message`/`title`/`type`/`icon`/`action`/`linkTitle`/`linkUrl`) and is usually `null`. The envelope is documented in full in the [authentication guide](../../integration-resources/overview).

## Step 2 · Register the user

Call the registration endpoint with the verification code received in step 1. Note that the `register` endpoint **does not take `behavioral`** — that field belongs to the code-sending endpoints only, so do not mix them.

```
POST /account/v1/register
```

Registering with a phone number:

```json theme={null}
{
  "mobileCode": "SG",
  "mobile": "91234567",
  "smsCode": "<SMS verification code>"
}
```

Registering with an email address:

```json theme={null}
{
  "email": "user@example.com",
  "emailCode": "<email verification code>"
}
```

| Field        | Type   | Required when        | Description                                                       |
| ------------ | ------ | -------------------- | ----------------------------------------------------------------- |
| `mobileCode` | string | Registering by phone | Phone country code, such as `CN`, `US`, `SG`                      |
| `mobile`     | string | Registering by phone | Phone number without the country code; AES-encrypted or plaintext |
| `smsCode`    | string | Registering by phone | SMS verification code                                             |
| `email`      | string | Registering by email | Email address; AES-encrypted or plaintext                         |
| `emailCode`  | string | Registering by email | Email verification code                                           |

> **Either/or rule**: phone registration uses `mobileCode + mobile + smsCode`; email registration uses `email + emailCode`. Send either `smsCode` or `emailCode`, matching the registration method you chose.

The `data` field of a successful response is the **`externalUserId` generated by the system**, which identifies the user in every subsequent endpoint:

```json theme={null}
{
  "code": "SYS_SUCCESS",
  "message": null,
  "messageDetail": null,
  "data": "usr_4dc3e854-xxxx-xxxx-xxxx-91a98b3d832c"
}
```

## Encrypting the phone number or email address (optional)

The `mobile` and `email` fields **can be sent AES-encrypted or in plaintext**; choose whichever suits your integration. To send them encrypted:

1. Encrypt the **plaintext** phone number or email address with AES (symmetric encryption) to get the encrypted byte array.
2. **Base64-encode** the result into a string.
3. Put that Base64 string in the `mobile` or `email` field of the request.

Here is a Java example (the key is a placeholder; replace it with the key you agreed with DCS):

```java theme={null}
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;

public class AES {
    private static final String SECRET = "YOUR_AES_SECRET_KEY"; // placeholder, never commit a real key

    public static void main(String[] args) {
        String mobile = "91234567";
        String encryptedMobile = SecureUtil.aes(Base64.decode(SECRET)).encryptBase64(mobile);

        String email = "user@example.com";
        String encryptedEmail = SecureUtil.aes(Base64.decode(SECRET)).encryptBase64(email);
    }
}
```

> The phone number, email address and key in the example are placeholders or masked values. **Never put real end-user PII or real keys into requests or logs.**

## Error handling and resends

* **Judging success**: use `code == SYS_SUCCESS` in the response envelope to decide whether the request was accepted; for any other value, read `message` and `messageDetail` to find out why.
* **Typical error response**: on failure, `code` carries the **specific business error code** for that failure (there is no generic failure code), and the specific reason appears in `message`. When the verification code has expired or was entered incorrectly, the response looks roughly like this (the envelope is unchanged):
  ```json theme={null}
  {
    "code": "<business-error-code>",
    "message": "verification code expired or invalid",
    "messageDetail": null,
    "data": ""
  }
  ```
  > The `code` and `message` above are illustrative placeholders; the actual values returned by the endpoint take precedence. The envelope is always `{code, message, messageDetail, data}`, with the error text in `message`.
* **Expired or mistyped code**: verification codes are time-limited, and an expired or wrong code makes `register` fail. Call the matching code-sending endpoint again (`behavioral=REGISTER`) for a fresh code, then retry.
* **Consistent method**: the registration method must match the way the code was sent. A code sent by SMS can only be used for phone registration (`smsCode`), and the same applies to email (`emailCode`).
* **Idempotency**: registering the same phone number or email address twice fails. If you are unsure whether a user already exists, query their status from [Managing Users](../managing-users/overview).

## Next steps

* Once registration returns an `externalUserId`, the usual next step is completing KYC for that user; see [Compliance · Overview](../../basic-concepts/compliance-kyc-flow).
* To manage account status and review a user's assets, see [Managing Users](../managing-users/overview).
* To walk the shortest path from registration to card issuance, funding and spending in one pass, see [Quickstart](../../getting-started/quickstart).
