---
updatedAt: 2026-08-31T12:24:21.000Z
agentTools:
  projectIndex: https://docs.cybrid.xyz/llms.txt
---

# Creating Customer Accounts on the Platform

```python Python
#
# Constants
#

CUSTOMER_TYPE_INDIVIDUAL = "individual"
CUSTOMER_TYPE_BUSINESS = "business"

IDENTITY_VERIFICATION_TYPE_KYC = "kyc"
IDENTITY_VERIFICATION_TYPE_BANK_ACCOUNT = "bank_account"

IDENTITY_VERIFICATION_METHOD_ID_AND_SELFIE = "id_and_selfie"
IDENTITY_VERIFICATION_METHOD_ACCOUNT_OWNERSHIP = "account_ownership"

IDENTITY_VERIFICATION_EXPECTED_BEHAVIOUR_PASSED_IMMEDIATELY = "passed_immediately"

STATE_CREATED = "created"
STATE_PENDING = "pending"
STATE_COMPLETED = "completed"
STATE_SETTLING = "settling"
STATE_WAITING = "waiting"
STATE_UNVERIFIED = "unverified"
STATE_VERIFIED = "verified"

OUTCOME_PASSED = "passed"
OUTCOME_FAILED = "failed"

ASSET_CODE_USD = "USD"
ASSET_CODE_USDC = "USDC"

ACCOUNT_TYPE_FIAT = "fiat"
ACCOUNT_TYPE_TRADING = "trading"

DEPOSIT_BANK_ACCOUNT_TYPE_MAIN = "main"

#
# Helpers
#

logger = logging.getLogger()

def create_account(
    api_client: cybrid_api_bank.ApiClient,
    owner: Bank | Customer,
    account_type: str,
    asset: str,
) -> Account:
    logger.info(
        f"Creating {account_type} account for asset {asset} and owner: {owner.guid}"
    )

    kwargs = {}
    if isinstance(owner, Customer):
        kwargs["customer_guid"] = owner.guid

    api_instance = AccountsBankApi(api_client)
    post_account = PostAccount(
        type=account_type,
        asset=asset,
        name=f"{asset} account for {owner.guid}",
        **kwargs,
    )

    try:
        # https://docs.cybrid.xyz/reference/createaccount
        account = api_instance.create_account(post_account)
        logger.info(f"Created {account_type} account: {account.guid}")
        return account
    except cybrid_api_bank.OpenApiException as e:
        logger.error(f"An API error occurred when creating account: {e}")
        raise e
        
def get_account(
    api_client: cybrid_api_bank.ApiClient, guid: str, include_balances: bool = False
) -> Account:
    logger.info("Getting account: %s", guid)

    api_instance = AccountsBankApi(api_client)

    try:
        # https://docs.cybrid.xyz/reference/getaccount
        # This recipe reads account state only, so it omits balances for a lighter response.
        account = api_instance.get_account(guid, include_balances=include_balances)
        logger.info("Got account: %s", account.guid)
        return account
    except cybrid_api_bank.OpenApiException as e:
        logger.error(f"An API error occurred when getting account: {e}")
        raise e


def wait_for_account(
    api_client: cybrid_api_bank.ApiClient, account: Account, expected_states: list[str]
) -> None:
    sleep_count = 0
    account_state = account.state
    final_states = expected_states
    while account_state not in final_states and sleep_count < Config.TIMEOUT:
        time.sleep(1)
        sleep_count += 1
        account = get_account(api_client, account.guid)
        account_state = account.state
    if account_state not in final_states:
        raise BadResultError(f"Account has invalid state: {account_state}")

    logger.info(f"Account successfully created with state {account_state}")


def create_deposit_address(
    api_client: cybrid_api_bank.ApiClient, account: Account
) -> DepositAddress:
    logger.info(f"Creating deposit address for account: {account.guid}")

    api_instance = DepositAddressesBankApi(api_client)
    post_account = PostDepositAddress(account_guid=account.guid)

    try:
        # https://docs.cybrid.xyz/reference/createdepositaddress
        address = api_instance.create_deposit_address(post_account)
        logger.info(f"Created address: {address.guid}")
        return address
    except cybrid_api_bank.OpenApiException as e:
        logger.error(f"An API error occurred when creating account: {e}")
        raise e


def get_deposit_address(
    api_client: cybrid_api_bank.ApiClient, guid: str
) -> DepositAddress:
    logger.info("Getting deposit address: %s", guid)

    api_instance = DepositAddressesBankApi(api_client)

    try:
        # https://docs.cybrid.xyz/reference/getdepositaddress
        address = api_instance.get_deposit_address(guid)
        logger.info("Got deposit address: %s", address.guid)
        return address
    except cybrid_api_bank.OpenApiException as e:
        logger.error(f"An API error occurred when getting deposit address: {e}")
        raise e


def wait_for_deposit_address(
    api_client: cybrid_api_bank.ApiClient,
    address: DepositAddress,
    expected_states: list[str],
) -> None:
    sleep_count = 0
    address_state = address.state
    final_states = expected_states
    while address_state not in final_states and sleep_count < Config.TIMEOUT:
        time.sleep(1)
        sleep_count += 1
        address = get_deposit_address(api_client, address.guid)
        address_state = address.state
    if address_state not in final_states:
        raise BadResultError(f"Deposit address has invalid state: {address_state}")

    logger.info(f"Deposit address successfully created with state {address_state}")


def create_deposit_bank_account(
    api_client: cybrid_api_bank.ApiClient, account: Account, account_type: str,
) -> DepositBankAccount:
    logger.info(f"Creating deposit bank account for account: {account.guid}")

    api_instance = DepositBankAccountsBankApi(api_client)
    post_account = PostDepositBankAccount(type=account_type, account_guid=account.guid)

    try:
        # https://docs.cybrid.xyz/reference/createdepositbankaccount
        account = api_instance.create_deposit_bank_account(post_account)
        logger.info(f"Created bank account: {account.guid}")
        return account
    except cybrid_api_bank.OpenApiException as e:
        logger.error(f"An API error occurred when creating account: {e}")
        raise e


def get_deposit_bank_account(
    api_client: cybrid_api_bank.ApiClient, guid: str
) -> DepositBankAccount:
    logger.info("Getting bank account: %s", guid)

    api_instance = DepositBankAccountsBankApi(api_client)

    try:
        # https://docs.cybrid.xyz/reference/getdepositbankaccount
        account = api_instance.get_deposit_bank_account(guid)
        logger.info("Got account: %s", account.guid)
        return account
    except cybrid_api_bank.OpenApiException as e:
        logger.error(f"An API error occurred when getting account: {e}")
        raise e


def wait_for_deposit_bank_account(
    api_client: cybrid_api_bank.ApiClient,
    account: DepositBankAccount,
    expected_states: list[str],
) -> None:
    sleep_count = 0
    account_state = account.state
    final_states = expected_states
    while account_state not in final_states and sleep_count < Config.TIMEOUT:
        time.sleep(1)
        sleep_count += 1
        account = get_deposit_bank_account(api_client, account.guid)
        account_state = account.state
    if account_state not in final_states:
        raise BadResultError(f"Deposit account has invalid state: {account_state}")

    logger.info(f"Deposit account successfully created with state {account_state}")
    
#
# Create a fiat account
#
# This will create a new USD fiat account for the customer.
#
# The account will initially be in the `storing` state. Before proceeding,
# wait for the account to be in the `created` state.
#

fiat_account = create_account(
    api_client, owner=customer, account_type=ACCOUNT_TYPE_FIAT, asset=fiat_asset
)
wait_for_account(api_client, fiat_account, expected_states=[STATE_CREATED])

#
# Create a trading account
#
# This will create a new USDC trading account for the customer.
#
# The account will initially be in the `storing` state. Before proceeding,
# wait for the account to be in the `created` state.
#

trading_account = create_account(
    api_client,
    owner=customer,
    account_type=ACCOUNT_TYPE_TRADING,
    asset=crypto_asset,
)
wait_for_account(api_client, trading_account, expected_states=[STATE_CREATED])

#
# Create a deposit address
#
# This will create a new USDC wallet address to receive USDC on the Ethereum chain.
#
# The account will initially be in the `storing` state. Before proceeding,
# wait for the address to be in the `created` state.
#

deposit_address = create_deposit_address(api_client, trading_account)
wait_for_deposit_address(
    api_client, deposit_address, expected_states=[STATE_CREATED]
)

#
# Display the USDC wallet address
#

deposit_address = get_deposit_address(api_client, deposit_address.guid)
logger.info(f"Deposit address: {deposit_address.address}")

#
# Create a deposit bank account
#
# This will open a bank account in the customer's name because `type` is
# set to `main`. There are costs associated with creating and maintaining `main`
# deposit bank accounts. Please consult our guide on Deposit Bank Accounts,
# https://docs.cybrid.xyz/docs/creating-deposit-accounts.
#
# The account will initially be in the `storing` state. Before proceeding,
# wait for the address to be in the `created` state.
#

deposit_bank_account = create_deposit_bank_account(
    api_client,
    fiat_account,
    account_type=DEPOSIT_BANK_ACCOUNT_TYPE_MAIN,
)
wait_for_deposit_bank_account(
    api_client, deposit_bank_account, expected_states=[STATE_CREATED]
)

#
# Display the bank account deposit information
#

deposit_bank_account = get_deposit_bank_account(
    api_client, deposit_bank_account.guid
)
logger.info("Bank account deposit information:")
logger.info("\tRouting details:")
logger.info("\t\tRouting number type: %s", deposit_bank_account.routing_details[0].routing_number_type)
logger.info("\t\tRouting number: %s", deposit_bank_account.routing_details[0].routing_number)
logger.info("\tAccount details:")
logger.info("\t\tAccount number: %s", deposit_bank_account.account_details[0].account_number)
logger.info("\tBeneficiary name: %s", deposit_bank_account.counterparty_name)
logger.info("\tBeneficiary address:")
logger.info("\t\tStreet 1: %s", deposit_bank_account.counterparty_address.street)
if deposit_bank_account.counterparty_address.street2 is not None:
    logger.info("\t\tStreet 2: %s", deposit_bank_account.counterparty_address.street2)
logger.info("\t\tCity: %s", deposit_bank_account.counterparty_address.city)
logger.info(
    "\t\tSubdivision: %s", deposit_bank_account.counterparty_address.subdivision
)
logger.info(
    "\t\tPostal code: %s", deposit_bank_account.counterparty_address.postal_code
)
logger.info(
    "\t\tCountry code: %s", deposit_bank_account.counterparty_address.country_code
)
logger.info("\tMemo: %s", deposit_bank_account.unique_memo_id)

return Accounts(
    fiat_account=fiat_account,
    trading_account=trading_account,
    deposit_address=deposit_address,
    deposit_bank_account=deposit_bank_account,
)
```

# Create a USD fiat account

<!-- python@211-223 -->

Create a new `fiat` type account for the customer and wait for the account to settle in the `created` state.

# Create a USDC trading account

<!-- python@225-240 -->

Create a new `trading` type account for the customer and wait for the account to settle in the `created` state.

# Create an on-chain USDC deposit address

<!-- python@242-254 -->

Create an on-chain USDC address on the Ethereum blockchain and wait for the address to settle in the `created` state.

# Display the on-chain USDC address

<!-- python@256-261 -->

Once the deposit address is `created`, display the on-chain address of the wallet to the user.

USDC sent to this wallet address will automatically show up in the associated trading account's balance once it has been confirmed on the Ethereum blockchain.

# Create a bank account

<!-- python@263-282 -->

Open a new bank account for the customer and wait for the account to settle in the `created` state.

# Display the bank account's deposit information

<!-- python@284-319 -->

Display the bank account's deposit information to the user.

USD deposited into this bank account will automatically show up in the associated fiat account's balance.