Wallets and Self-Directed Investing
Overview
Use this quick start guide to get up and running with DriveWealth’s REST API. This guide covers three “Hello, World!” examples that demonstrate how to make a stock purchase on behalf of a user:
- Generate an Authentication Token
- Create a Self-directed DriveWealth Brokerage Account
- Make a Trade
Prerequisites
Before you begin, ensure you have your DriveWealth client app key (dw-client-app-key
).
Idempotency-Key Header
Many of DriveWealth's APIs can take in an optional Idempotency-Key
header. This is a unique ID that you create (e.g. using a GUID generation tool) to uniquely identify a request.
Should the request fail or be interrupted, you can retry the request with the same Idempotency-Key
header value for up to four days.
Requests should never be unconditionally retried, as failing to receive a response does not necessarily mean that DriveWealth is not receiving and responding. We recommend an exponential backoff, or similar patten of retries, before switching to failover procedures such as:
Issue request at time T.
Retry 1: T + 1 second
Retry 2: T + 3 seconds
Retry 3: T + 10 seconds
Retry 4: T + 30 seconds
For more information see Idempotent Requests.
Generate an Authentication Token
An authentication token is required for your client app to make requests with our API on behalf of the end user. Once generated, this token must be included when invoking each subsequent DriveWealth REST endpoint in your app.
Auth Request
Follow the steps below to generate an authentication token:
- (Optional) Generate or create a unique Idempotency-Key value.
- Invoke POST
/back-office/auth
and pass in the following:- For the header:
- Idempotency key as the Idempotency-Key (optional)
- Client app ID as the `dw-client-app-key
- For the body:
- User's name as the username field
- User’s password as the password field
- Set
appTypeID
to 4.
- For the header:
curl --request POST \
--url https://bo-api.drivewealth.io/back-office/auth/tokens \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--header 'dw-client-app-key: 69204e73-561d-4...' \
--data '{"clientID": "0oa5rc70..","clientSecret": "fr2k5wntp..."}'
Auth Response
The authToken
field in the response contains the generated authentication token:
{
"token_type": "Bearer",
"expires_in": "3600",
"access_token": "eyJraWQiOiJjY1lyLVRDUTZBR0w5OWl3TTFyMjAwWlNSdnI0dVBCZ3QxZU42eDhyRVVrIiwiYWxnIjoiUlMyNTYifQ.eyJ2ZXIiOjEsImp0aSI6IkFULmkwRmJtbzJkdU5Ya3EzREtyU3NkVTN4M3V3MnljSjhTdkctel9hMFM0VWMiLCJpc3MiOiJodHRwczovL2FwMS1kcml2ZXdlYWx0aC5va3RhcHJldmlldy5jb20vb2F1dGgyL2F1czJ6bWJsNnBOcE4zelZEMWQ3IiwiYXVkIjoiRFdBdXRoU2VydmVyREVWIiwiaWF0IjoxNjY0OTA4OTA2LCJleHAiOjE2NjQ5MTI1MDYsImNpZCI6IjBvYTVubnk0bzlCZU1zQVlRMWQ3Iiwic2NwIjpbImFsbF90cmFkZXIiXSwic3ViIjoiMG9hNW5ueTRvOUJlTXNBWVExZDciLCJwcm9maWxlIjp7InBlcm1pc3Npb25JRCI6IjY5NTQ3OWFhLTVmN2ItNDRhOC1hMTE4LWFhOWU2N2M3YmUyZSIsInJvbGUiOiJBTExfVFJBREVSIiwicGFydG5lcklEIjoiMThkNTk3NjctNzNiOC00YTM0LWE1NDItMWNjZDIyYmEzNjAyIiwidXNlcklEIjoiNzA1YzFiMDMtM2Y2YS00MmFhLTgwN2EtMWY0NGMwNjc0ZDhmIn19.p3fspVtifQ_Gr4K3pi5fTorCBrcuVkRxk-yNLANgiKvl3t0BKraMT7_Y8c8opsKmNUwLS2K3YlBA0vrskzxeacWtEDx_JGtz_zKS_GXWTPDNNd77Zy0P6vfNfDjc_Hbzpp90dAICrTwvrcihNbyLeL3Zq7LisGpDkYtdxwB73AHtU6qIQvPY-iYaWBLfJ9IZrTTNWd5Qqy8ICJNunrS5riD2O3o4idyzMoUnFimUAoiAwgqtSOh4Loe57kPQsCgNRoba0zbnXKNd0eyMHCCdM0BXW_uhyJIfdGUXVzCcg9k_G80sWnefTeitwdX0S657vKHTjyLsGJSc06ZggGdlag",
"scope": "all_trader"
}
You will use the generated authToken
in the sections below to make requests on behalf of the user in your client app.
Create a Self-directed DriveWealth Brokerage Account
This section describes how to:
- Create a User
Create a DriveWealth Brokerage Account
- Create a User
The next step is to create a User entity in DriveWealth that represents the user you authenticated in the previous section.
User Request
Follow the steps below to prepare the request:
- (Optional) Generate or create a unique Idempotency-Key value.
- Invoke POST
/back-office/users
and pass in the following:- For the header:
- Authentication token (generated in the previous section)
- Idempotency key (optional)
- Client app ID
- The user's information in the body of the request.
- For the header:
curl --location --request POST 'https://bo-api.drivewealth.io/back-office/users' \
--header 'Authorization: Bearer :authToken' \
--header 'dw-client-app-key: f988...' \
--header 'Idempotency-Key: 2a5c0...' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
"userType":"INDIVIDUAL_TRADER",
"wlpID":"DWTT",
"documents": [
{
"type": "BASIC_INFO",
"data": {
"firstName": "Daryl",
"lastName": "Hall",
"username": "DHall",
"country": "USA",
"phone": "291...",
"emailAddress": "[email protected]",
"language": "en_US"
}
},
{
"type": "IDENTIFICATION_INFO",
"data": {
"value": "123456789",
"type": "SSN",
"citizenship": "USA"
}
},
{
"type": "PERSONAL_INFO",
"data": {
"birthDay": 3,
"birthMonth": 12,
"birthYear": 1990,
"politicallyExposedNames": null
}
},
{
"type": "ADDRESS_INFO",
"data": {
"street1": "123 Main St",
"city": "Chatham",
"province": "NJ",
"postalCode": "09812"
}
},
{
"type": "EMPLOYMENT_INFO",
"data": {
"status": "Employed",
"broker": false,
"type": "PROFESSIONAL",
"position": "Police"
}
},
{
"type": "INVESTOR_PROFILE_INFO",
"data": {
"investmentObjectives": "Active_DAIly",
"investmentExperience": "None",
"annualIncome": 75000,
"networthLiquid": 58932,
"networthTotal": 485003,
"riskTolerance": "Low"
}
},
{
"type": "DISCLOSURES",
"data": {
"termsOfUse": true,
"customerAgreement": true,
"marketDataAgreement": true,
"rule14b": true,
"findersFee": false,
"privacyPolicy": true,
"dataSharing": true,
"signedBy": "Chris Turkelton"
}
}
],
"parentIBID":"acb33c..."
}'
User Response
The id
field in the response contains the ID for the newly-created user:
{
"id": "6d454...",
"userType": {
"name": "INDIVIDUAL_TRADER",
"description": "Individual Trader"
},
"status": {
"name": "APPROVED",
"description": "User approved."
},
"parentIB": {
"id": "acb33c...",
"name": "DriveWealth"
},
"documents": [
{
"type": "ADDRESS_INFO",
"data": {
"street1": "123 Main St",
"city": "Chatham",
"province": "NJ",
"postalCode": "09812",
"country": "USA"
},
"description": "Physical address information"
},
...
],
"wlpID": "DWTT",
"referralCode": "CEB...",
"createdWhen": "2022-04-20T21:49:34.452Z",
"updatedWhen": "2022-04-20T21:49:34.452Z"
}
The ID generated for the user will be used in subsequent requests below to perform actions on behalf of the user.
Create a DriveWealth Brokerage Account
Now that the user has been registered with DriveWealth, the next step is to set up a DriveWealth brokerage account for that user.
Account Request
This example creates a simple self-directed account:
- Invoke POST
/back-office/accounts
and pass in the following:- For the header:
- Authentication token
- Idempotency key (optional)
- Client app ID
- For the body:
id
(generated in the previous section) via the userID field- Account setup information for the remaining body of the request
- For the header:
curl --location --request POST 'https://bo-api.drivewealth.io/back-office/accounts' \
--header 'Authorization: Bearer :authToken' \
--header 'dw-client-app-key: f988bb5f-2176-45d5-b417-57ce8e54e6b1' \
--header 'Idempotency-Key: e5c6f18a-d073-4e12-9954-c3a7b4d3e777' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
"userID":"6d4547ab-9ae3-4b1f-9899-5f21536258d7",
"accountType": "LIVE",
"accountManagementType": "SELF",
"tradingType": "CASH"
}'
Note: The account setup information required will vary depending on how the account is being configured. For more information, see Create Account.
Account Response
Theid
field in the response contains the ID of the newly-created account:
{
"id": "6d4547...",
"accountNo": "ZBG...",
"accountType": {
"name": "LIVE",
"description": "Live Account"
},
"accountMgmtType": {
"name": "SELF",
"description": "Self Directed Account"
},
"status": {
"name": "OPEN",
"description": "Open"
},
"tradingType": {
"name": "CASH",
"description": "Cash account"
},
"leverage": 1.00,
"nickname": "Daryl's Self Directed Account",
"parentIB": {
"id": "acb33c...",
"name": "DriveWealth"
},
"commissionID": "16497...",
"beneficiaries": false,
"userID": "6d45...",
"restricted": false,
"goodFaithViolations": 0,
"patternDayTrades": 0,
"freeTradeBalance": 0,
"gfvPdtExempt": false,
"buyingPowerOverride": true,
"bod": {},
"sweepInd": true,
"interestFree": false,
"openedWhen": "2022-04-20T22:01:30Z",
"ignoreMarketHoursForTest": false,
"flaggedForACATS": false
}
Note: Funding is specific to DIY accounts. It doesn't apply to wallet accounts since it is on a net-settlement basis.
For the purposes of quickly making a trade using the sandbox, this quickstart intentionally skips this step. In practice, you would normally:
Link an External Bank Account
In order to fund trades, the user's external bank account needs to be linked to their DriveWealth account.
- Invoke POST /back-office/bank-accounts and pass the user's ID via the userID body field along with the external bank account information.
- Check if the status field in the response indicates if the bank account was successfully linked (i.e. is set to ACTIVE).\
For Individually Funded Accounts
- Fund the Account where you will use an endpoint to instantly fund the user's DriveWealth brokerage account.
Fund the Account
For this quickstart, use POST /back-office/funding/deposits to instantly fund the user's DriveWealth brokerage account.
Individual Funding Request
- Invoke POST
/back-office/accounts
and pass in the following:- For the header:
- Authentication token
- Idempotency key (optional)
- Client app ID
- For the body:
- accountNo of the user's DriveWealth brokerage account
- Funding details including amount, currency, and type
- For the header:
curl --location --request POST 'https://bo-api.drivewealth.io/back-office/funding/deposits' \
--header 'Authorization: Bearer :authToken' \
--header 'dw-client-app-key: f988...' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
"accountNo": "ZBG...",
"amount": 500,
"currency": "USD",
"type": "INSTANT_FUNDING",
"note": "Some money for funding"
}'
Individual Funding Response
Theid
field in the response identifies the funding request:
{
"id": "ZBCB000...",
"accountNo": "ZBC...",
"category": "DEPOSIT",
"currency": "USD",
"amount": 500,
"status": {
"id": 1,
"message": "Pending",
"updated": "2022-04-26T17:56:25.295Z"
},
"source": {
"id": "INSTANT_FUNDING",
"brand": "Instant funding",
"meta_info": "Some money for funding"
},
"created": "2022-04-26T17:56:25.295Z",
"accountID": "261fb...",
"userID": "261fb...",
"transactionCode": "JOURNAL",
"wlpFinTranTypeID": "f197...",
"batch": true,
"account_number": "ZBG..."
}
Make a Trade
Everything is now set up and your client app can now make a trade on behalf of the user. The following subsections show how to:
- Purchase a Stock
- Verify the Trade Order
- The POST /back-office/orders endpoint is used to buy and sell stocks.
Trade Request
- Invoke POST
/back-office/accounts
and pass in the following:- Values generated from Create a DriveWealth Brokerage Account:
- The user's linked bank account number in the bankAccountNumber body field.
- DriveWealth account number in the accountNo body field.
- The remaining body fields to specify the order details.
- Values generated from Create a DriveWealth Brokerage Account:
curl --location --request POST 'https://bo-api.drivewealth.io/back-office/orders' \
--header 'Authorization: Bearer :authToken' \
--header 'dw-client-app-key: f988...' \
--header 'Idempotency-Key: 175bf...' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
"bankAccountNumber":"12345",
"accountNo":"yyy",
"orderType":"MARKET",
"symbol":"VTI",
"side":"BUY",
"quantity":"10"
}'
Trade Response
The orderID field uniquely identifies the order and can be used in subsequent requests (e.g. to Verify the Trade Order). The orderNo field is a user-friendly order identifier that you can display to the user:
{
"orderID": "EF.418a55...",
"orderNo": "EFXM000103"
}
Verify Trade Request
Invoke GET /back-office/orders/{order-id} to check the status of stock purchase.
Pass the orderID generated in the previous section in the {order-id} path parameter:
curl --location --request GET 'https://bo-api.drivewealth.io/back-office/orders/EF.418a55...' \
--header 'Authorization: Bearer :authToken' \
--header 'dw-client-app-key: f988...' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Verify Trade Response
The status field in the response provides the current state of the order. In this example the value is FILLED, indicating that the stock has been successfully purchased:
{
"id": "GB.703...",
"orderNo": "EFXM000103",
"type": "MARKET",
"side": "BUY",
"status": "FILLED",
"symbol": "VTI",
"averagePrice": 16.07,
"totalOrderAmount": 10,
"cumulativeQuantity": 0.92304,
"quantity": 0.92304,
"amountCash": 1500,
"fees": 0.01,
"createdBy": "cc07f9...",
"userID": "3bfdb8...",
"accountID": "cc07f91...",
"accountNo": "DWRW000001",
"created": "2019-02-14T18:56:07.411Z"
Updated over 1 year ago