User Onboarding
Before a customer can fund, trade, or withdraw on a payments-core account, they need a user (end customer), an account linked to that user, a submitted identity, and confirmed agreements. Then poll until the account is open.
Step 1: Create User
Register the end customer under your organization.
POST /user- Optional
externalId: your own customer key (unique per org, write-once; generated if omitted) - Optional
name: display name - Store the returned
userId
{
"externalId": "customer-123",
"name": "Jane Doe"
}
Duplicate externalId within your org returns 409. To look up an existing customer, use GET /user?externalId=... or GET /user/{id}.
See Core Concepts: User.
Step 2: Create Account
Register a payments-core account for the customer with provider: "BITGO" and the userId from Step 1.
POST /account- Body:
{ "provider": "BITGO", "userId": "<userId>", "async": false } - Store the returned
accountId
{
"provider": "BITGO",
"userId": "<userId>",
"async": false
}
async: false while integratingSynchronous create fails the request if provider provisioning fails immediately, which is easier to debug. Use async: true only when you intentionally want background reconciliation.
Step 3: Submit Identity
Submit KYC data for the account.
POST /identity- Tie the identity to the account with
accountId - Use
identityType: "natural_person"for individuals (companies use a company identity type) async: falseprovisions the identity inline when possible
Example natural-person payload:
{
"accountId": "<accountId>",
"accountRoles": "owner",
"identityType": "natural_person",
"firstName": "Jane",
"lastName": "Doe",
"primaryAddress": "123 Main St",
"primaryCity": "San Francisco",
"primaryPhoneNumber": "+15555551234",
"primaryPostalCode": "94102",
"dateOfBirth": "1998-02-11",
"occupation": "Other",
"politicallyExposedPerson": false,
"taxCountry": "US",
"taxIdNumber": "123456789",
"taxState": "CA",
"sex": "male",
"async": false
}
KYC can leave the account pending (with a statusReason such as pending identity) until the identity is approved. Do not assume create-identity alone opens the account.
Step 4: Confirm Agreements
List seeded agreements, then agree to each required row.
GET /agreement: find rows for thisaccountIdPUT /agreement/{id}/agree: body can be{}for payments-core agree
For accounts with provider: "BITGO", expect at least:
MAGFI_AGREEMENT_TERMS_OF_SERVICE(TOS)BITGO_AGREEMENT_CSA(CSA)BITGO_AGREEMENT_MPA(MPA) when present
confirmed before openAgreeing submits the signature. For CSA/MPA, status becomes confirmed only after the provider accepts it. The account will not open while required agreements are still outstanding.
Step 5: Poll Until Open
GET /account/{id}- Wait for
status: "open"before funding or trading
Common pending reasons include identity still in review or agreements not yet confirmed. Treat status as the gate; use statusReason for diagnostics.
Putting It Together
Next Steps
- Funding: ACH deposit or crypto contribution
- Conversions: Place trade orders