Airwallex logo

Step 2b: Create and connect a connected account for individuals

Using the Scale API you can create Airwallex accounts for the users of your platform or marketplace. Below explains how you can onboard your users if they are individuals without a registered company entity.

There are three main steps to successfully onboard the individuals to Airwallex:

  1. Determining and collecting the information/ data required
  2. Creating the account
  3. Submitting the account for activation

Additionally you need to consider cases where the activation requires additional measures:

  1. Handling additional requirements during account activation

1. Determining and collecting the information/ data required

To determine the the information you need to collect from your users, please check the API documentation with the dynamic schema: https://www.airwallex.com/docs/api#/Scale/Accounts/_api_v1_accounts_create/post

All required fields have to be filled before activating the account. Filling in optional fields before activating the account will increase the success rate of account activation. You may collect the required fields from users using your user interface, or use information previously collected or determined from your own data (e.g., monthly transaction volumes).

2. Creating the account

You can create accounts for your users with the accounts API. The accounts created will be automatically linked to your platform account and you will have authorization to transact on behalf of the connected accounts using Airwallex's Scale APIs.

There are two ways to create accounts with the Scale API endpoints:

  1. Create an account with all required information at once
  2. Create an empty account and update required information step-by-step

2.1 Create an account with all required information at once

Creating an account with all required information at once is useful if you are storing a copy of the information on your servers or if the users fill in the information all at once. With this, you’ll limit the number of API calls you have to make to get going.

If you have collected any image or document from the user in step 1 (e.g., a copy of their identity document), then you’ll first need to upload the document to the Airwallex server using the file service API <POST /api/v1/files/upload>.The response of the file service API endpoint will include a file_id, which you should save so that you can reference it in the next step. Once all images/ documents have been successfully uploaded, you can proceed.

// POST /api/v1/files/upload
curl -X POST \
  'https://files-demo.airwallex.com/api/v1/files/upload?notes=string' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0b20iLCJyb2xlcyI6WyJ1c2VyIl0sImlhdCI6MTQ4ODQxNTI1NywiZXhwIjoxNDg4NDE1MjY3fQ.UHqau03y5kEk5lFbTp7J4a-U6LXsfxIVNEsux85hj-Q' \
  -H 'Content-Type: multipart/form-data' \
  -F [email protected]/Users/johnsmith/Documents/passport.pdf

// example response
{
  "created": 1597914782,
  "file_id": "NWRiYjUzMTItNWY2MC00MDNiLWE4ZmUtOTllYjRjZGZhZmU4LHwsc2hlbnpoZW4sfCw0LjLvvIlHTFDkuJrliqHpnIDmsYIgJiBBV1jlr7nmjqXmlrnmoYggMTIuMjAueGxzeA",
  "filename": "string",
  "notes": "string",
  "object_type": "string",
  "size": 0
}

Next, you can create an account via <POST /api/v1/accounts/create>. You can include in the request body all required information collected in step 1. For any images/ documents (e.g., copy of identity document), you need to include the file_id that you saved. In the response of the create account endpoint, you’ll receive an account ID, with which you can access the account later on.

// POST /api/v1/accounts/create
curl --request POST \
--url 'https://api-demo.airwallex.com/api/v1/accounts/create' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0b20iLCJyb2xlcyI6WyJ1c2VyIl0sImlhdCI6MTQ4ODQxNTI1NywiZXhwIjoxNDg4NDE1MjY3fQ.UHqau03y5kEk5lFbTp7J4a-U6LXsfxIVNEsux85hj-Q' \
--data '{
    "account_details": {
        "legal_entity_type": "INDIVIDUAL",// Optional, defaults to BUSINESS
        "individual_details": {
            "address": {
                "address_line1": "200 Collins Street",
                "address_line2": "200 Collins Street",
                "country_code": "AU",
                "postcode": "3000",
                "state": "VIC",
                "suburb": "Melbourne"
            },
            "addressEnglish": {
                "address_line1": "200 Collins Street",
                "address_line2": "200 Collins Street",
                "country_code": "AU",
                "postcode": "3000",
                "state": "VIC",
                "suburb": "Melbourne"
            },
            "date_of_birth": "1986-01-16",
            "first_name": "John",
            "last_name": "Smith",
            "primary_identification": { // one of `driver_licence`, `passport`, `personal_id` or `medicare_card`
                "identification_type": "DRIVERS_LICENSE", //  PERSONAL_ID, PASSPORT, DRIVERS_LICENSE, MEDICARE_CARD
                "issuing_country_code": "AU", // country code
                "drivers_license": {
                    "license_number": "AB123456",
                    "expire_at": "2023-02-18", // date
                    "issuing_state": "VIC"
                }
            },
            "user_id_on_platform": "john.smith" // User/shop ID on Platform
        }
    },
    "account_usage": {  //  Newly added, optional
        "expected_monthly_transaction_volume": {
            "amount": "5000" // in USD
        },
        "collection_from": [ // self top up, payment gateway, marketplaces, etc
            "SELF_TOP_UP",
            "CONNECTED_AWX_ACCOUNT"
        ],
        "collection_country_codes": [
            "AU",
            "US"
        ],
        "payout_to": [
            "OWN_BANK_ACCOUNT",
            "CONNECTED_AWX_ACCOUNT"
        ],
        "payout_country_codes": [
            "AU",
            "UK"
        ],
        "card_usage": [ // business expenses, personal spending
            "NONE"
        ]
    },
    "customer_agreements": {
        "agreed_to_data_usage": true,
        "agreed_to_terms_and_conditions": true,
        "opt_in_for_marketing": false
    },
    "primary_contact": {
        "email": "[email protected]"
    }
}'

2.2 Create an empty account and update required information step-by-step

Creating an empty account and updating the required information step-by-step is useful if you do not store a copy of the information on your server and you’ll want to enable the user to provide information in stages.

You can start out with creating an empty account via <POST /api/v1/accounts/create>, for which you only need to provide three pieces of information:

  • Primary contact of the user (either email or mobile phone number)
  • Agreement to data sharing
  • Agreement to terms and conditions

You’ll receive an account ID, with which you can access the account later on.

// POST /api/v1/accounts/create
curl --request POST \
--url 'https://api-demo.airwallex.com/api/v1/accounts/create' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0b20iLCJyb2xlcyI6WyJ1c2VyIl0sImlhdCI6MTQ4ODQxNTI1NywiZXhwIjoxNDg4NDE1MjY3fQ.UHqau03y5kEk5lFbTp7J4a-U6LXsfxIVNEsux85hj-Q' \
--data '{
   "account_details": {
     "legal_entity_type": "INDIVIDUAL"
 },
  "customer_agreements": {
      "agreed_to_data_usage": true,
      "agreed_to_terms_and_conditions": true
  },
  "primary_contact": {
    "email": "[email protected]"   
  }
}'

An example response:

{
  "id": "acct_44ymLf86OR2pMWjCRLGWSw", // open id
  "status": "CREATED",
  "requirements":{  },
  "account_details": {
    "legal_entity_type": "INDIVIDUAL",
    "individual_details": {
      "first_name": "Rob",
      "last_name": "Stark"
    }
  },
  "customer_agreements": {
      "agreed_to_data_usage": true,
      "agreed_to_terms_and_conditions": true,
      "opt_in_for_marketing": false
  },
  "primary_contact": {
    "email": "[email protected]",
    "mobile": "12345678901"
  }
}

Afterwards you can add any information collected from the user with the update account endpoint <POST /api/v1/accounts/{account_id}/upload>. You can replace {account_id} with the account id received when creating the empty account, to identify the account to which you want to add or change information.

If you are collecting any image or document from the user (e.g., a copy of their identity document), then you’ll need to upload the document to the Airwallex server using the file service API <POST /api/v1/files/upload>.The response of the file service API endpoint will include a file_id. This file_id can then be used to add the image/ document to the account with the update account endpoint.

You can call the update account endpoint as many times as you wish until all the information required has been added. You can also use the update account endpoint to overwrite information previously added.

// POST /api/v1/files/upload
curl -X POST \
  'https://files-demo.airwallex.com/api/v1/files/upload?notes=string' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0b20iLCJyb2xlcyI6WyJ1c2VyIl0sImlhdCI6MTQ4ODQxNTI1NywiZXhwIjoxNDg4NDE1MjY3fQ.UHqau03y5kEk5lFbTp7J4a-U6LXsfxIVNEsux85hj-Q' \
  -H 'Content-Type: multipart/form-data' \
  -F [email protected]/Users/johnsmith/Documents/passport.pdf

// example response
{
  "created": 1597914782,
  "file_id": "NWRiYjUzMTItNWY2MC00MDNiLWE4ZmUtOTllYjRjZGZhZmU4LHwsc2hlbnpoZW4sfCw0LjLvvIlHTFDkuJrliqHpnIDmsYIgJiBBV1jlr7nmjqXmlrnmoYggMTIuMjAueGxzeA",
  "filename": "string",
  "notes": "string",
  "object_type": "string",
  "size": 0
}
// POST /api/v1/accounts/{account_id}/update
curl --request POST \
--url 'https://api-demo.airwallex.com/api/v1/accounts/acct_44ymLf86OR2pMWjCRLGWSw/update' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0b20iLCJyb2xlcyI6WyJ1c2VyIl0sImlhdCI6MTQ4ODQxNTI1NywiZXhwIjoxNDg4NDE1MjY3fQ.UHqau03y5kEk5lFbTp7J4a-U6LXsfxIVNEsux85hj-Q' \
--data '{
  "account_details": {
    "legal_entity_type": "INDIVIDUAL",
    "individual_details": {
      "nationality": "Westeros",
      "date_of_birth": "1980-10-10",
      "address": {
        "address_line1": "200 Collins Street",
        "address_line2": "200 Collins Street",
        "country_code": "AU",
        "postcode": "3000",
        "state": "VIC",
        "suburb": "Melbourne"
      },
      "primary_identification": {.
        "identification_type": "PASSPORT",
        "issuing_country_code": "AU",     // country code
        "passport": {
          "front_file_id": "NWRiYjUzMTItNWY2MC00MDNiLWE4ZmUtOTllYjRjZGZhZmU4LHwsc2hlbnpoZW4sfCw0LjLvvIlHTFDkuJrliqHpnIDmsYIgJiBBV1jlr7nmjqXmlrnmoYggMTIuMjAueGxzeA", // file_id from file service
          "passport_number": "",
          "expire_at": "",
          "effective_at": "",
          "mrz_line1": "",
          "mrz_line2": "",
        }
      }
  }
}'

3. Submit the account for activation

Once all the required information has been collected, you can submit the account for activation using <POST /api/v1/accounts/{account_id}/submit>. If the information provided fulfills the requirements determined in step 1, the account status will be updated to SUBMITTED.

// POST /api/v1/accounts/{account_id}/submit
curl -X POST \
http://api-demo.airwallex.com/api/v1/accounts/acct_44ymLf86OR2pMWjCRLGWSw/submit \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwZGE4YjVlMi0xZWNhLTRmN2EtODY4Ni1mNTYzOGUzZmFkZmQiLCJzdWIiOiIwZGZlMTgyNS05ODUxLTRjNDctOTNiMy1mMzViNTQzMDJiOTAiLCJpYXQiOjE1NDcwMDQyNjYsImV4cCI6MTU0NzAxNjI2Nn0.PPIM2Ve2VwCzPS2swa6L7JGzDC_i26Guls02YDzI668' \

You can subscribe to account update webhooks to be notified once the activation has been completed. For individuals, most accounts will be activated within a minute. However, if further review is required, the activation may take 24 hours or longer. Alternatively, you can query the status of the account using <GET /api/v1/accounts/{account_id}> and look at the <status> field at any time.

  // GET /api/v1/accounts/{account_id}

import axios from 'axios';

curl --request GET \
--url 'https://api-demo.airwallex.com/api/v1/accounts/acct_44ymLf86OR2pMWjCRLGWSw \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0b20iLCJyb2xlcyI6WyJ1c2VyIl0sImlhdCI6MTQ4ODQxNTI1NywiZXhwIjoxNDg4NDE1MjY3fQ.UHqau03y5kEk5lFbTp7J4a-U6LXsfxIVNEsux85hj-Q'

If the information you have provided is not sufficient based on the requirements determined in the first step, the call <POST /api/v1/accounts/{account_id}/submit> will respond with the error code below: 400 Possible errors: field_required, invalid_argument

Example response:

  {
  "code": "invalid_argument",
  "message": "ensure identification type is one of [DRIVERS_LICENSE, PASSPORT, PERSONAL_ID, MEDICARE_CARD]",
  "source": "account_details.individual_details.primary_identification.identification_type"
}

4. Handling additional requirements during account activation

Sometimes more steps are required to successfully complete the account activation, even if the information you submitted in step 2 was initially deemed sufficient. There are generally two reasons this might happen:

  • Failed identity verification: During KYC we have to verify the identity of the individual. If we are unable to verify the identity, you’ll need to ask the individual to submit a second form of identification, or retry after correcting any errors in the previously submitted data.
  • Additional information requests: During KYC, we have to assess the risk of each individual, in order to decide whether the account can be activated or not. In some instances, more information will be required to make that decision.

Currently additional information requests will be handled manually via email. We’ll reach out to you if more information on an individual is required. Later on you’ll be able to subscribe to a webhook to be informed of additional information requests, and will be able to submit the information directly through the API endpoints.