Documentation Index
Fetch the complete documentation index at: https://developers.circle.com/llms.txt
Use this file to discover all available pages before exploring further.
Walk through the full onboarding flow: create a business client, complete KYB
verification, upload documents, submit the application, and retrieve your active
stablecoin account.
The Digital Asset Accounts API base URL is https://api-sandbox.circle.com for
sandbox and https://api.circle.com for production. Set your API key in the
Authorization header using the format Bearer YOUR_API_KEY. See
Sandbox environment and
Going to production
for environment details.
Prerequisites
Before you begin this quickstart, ensure you’ve:
- Requested and received Digital Asset Accounts sandbox access from your Circle
representative. See
Sandbox environment
for details.
- Obtained an API key for Digital Asset Accounts from your Circle
representative.
- (Recommended) Configured a
webhook subscription
for tracking asynchronous events.
Step 1: Create a business client
Create a new business client using the Partner Onboarding API. Each client
represents a business entity that goes through KYB verification.
curl --request POST \
--url https://api-sandbox.circle.com/v1/partner/clients \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"clientName": "My Company ABC1",
"country": "US",
"clientType": "business",
"businessDetails": {
"natureOfBusiness": "paymentProcessorPlatform",
"institutionType": "privateCo"
}
}'
Replace YOUR_API_KEY with your Bearer token. Use a unique clientName for
each new client, because the API rejects duplicate names.
Keep your API keys safe. Never share your API key or record it in a publicly
accessible medium such as client-side code or public repositories.
Save the clientEntityId and applicationId from the response. You need both
values for the remaining steps.
{
"data": {
"clientEntityId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"applicationId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
Fill out the required business information sections. Replace {applicationId}
with the value from step 1 in all of the following requests.
2.1. Basic business info
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/basicBusinessInfo \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"businessWebsite": "https://mycompany.example.com",
"businessWebsiteProvided": true,
"businessModelDescription": "Digital payments platform for stablecoin transfers",
"customerTypesDescription": "Small businesses and individual consumers in the US",
"productsAndServicesDescription": "USDC payments, deposits, and withdrawals"
}'
2.2. Business address
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/physicalBusinessAddress \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"physicalAddressLine1": "1 Main St",
"physicalAddressCity": "New York",
"physicalAddressState": "NY",
"physicalAddressPostalCode": "10001",
"physicalAddressCountry": "US",
"businessAddressRemote": false,
"physicalAddressProofOfAddress": []
}'
2.3. Business registration
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/businessRegistrationDetails \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"businessName": "My Company ABC1",
"businessNameDifferent": false,
"registrationNumber": "00-0000000",
"taxId": "00-0000000",
"countryOfFormation": "US",
"businessStateOfRegistrationOfFormation": "NY",
"dateOfFormation": "2010-01-01"
}'
The businessName value must match the clientName you used in step 1.
Step 3: Complete the remaining KYB sections
Six more sections need data before you can submit the application. The following
calls use placeholder data that is valid for sandbox testing.
3.1. Entity operations
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/entityOperations \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"entityServesCustomers": true,
"countriesWithMostCustomers": ["US"],
"countriesWithPhysicalPresence": ["US"],
"businessAcceptsPrivacyCoin": false,
"customerBaseByType": { "individuals": "70", "businesses": "30" }
}'
3.2. Compliance details
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/financialCrimesComplianceDetails \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"complianceOfficerDetailsProvided": false,
"noComplianceOfficerDetailsReason": "Outsourced to external compliance firm",
"lastYearAmlProgramProvided": false,
"noLastYearAmlProgramReason": "Entity less than 1 year old",
"amlTestingReportProvided": false,
"noAmlTestingReportReason": "Entity less than 1 year old"
}'
3.3. Licensing
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/licensingAndRegistration \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"licenseAndRegistrationRequired": false,
"noLicenseAndRegistrationRequiredReason": "Not required in jurisdiction"
}'
3.4. Beneficial owners
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/beneficialOwnersDetails \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"beneficialOwnersExist": false,
"beneficialOwnershipExempted": true,
"beneficialOwnershipExemptionReason": "Single owner private company"
}'
3.5. Intended use of account
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/intendedUseOfAccount \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"accountPurpose": ["paymentProcessingPlatform"],
"accountPurposeDescription": "USDC payments and transfers",
"expectedMonthlyFiatActivity": "from0to100k",
"expectedMonthlyCryptoActivity": "from0to100k",
"expectedProductsForUsage": ["circleMint"],
"sourceOfFunds": ["businessOperatingFunds"],
"sourceOfFundsDescription": "Revenue from platform services",
"financialDocumentsProvided": false,
"noFinancialDocumentReason": "New entity",
"assetsUnderManagement": "from0to10m",
"bankBrokerageCryptoStatement": []
}'
3.6. Control person
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/individualWithSignificantControlPersons \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '[{
"controllerFirstName": "Jane",
"controllerLastName": "Smith",
"controllerDob": "1985-06-15",
"controllerCitizenship": ["US"],
"controllerIdentificationNumber": "000-00-0000",
"controllerJobTitle": "Director",
"controllerLine1": "1 Main St",
"controllerCity": "New York",
"controllerState": "NY",
"controllerPostalCode": "10001",
"controllerCountry": "US"
}]'
Step 4: Upload documents
Upload six PDF documents required for KYB verification. For sandbox testing,
create a minimal dummy PDF:
printf '%%PDF-1.0\n1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 3 3]>>endobj\nxref\n0 4\n0000000000 65535 f \n0000000009 00000 n \n0000000058 00000 n \n0000000115 00000 n \ntrailer<</Size 4/Root 1 0 R>>\nstartxref\n190\n%%%%EOF' > /tmp/dummy.pdf
Upload each document. Save the documentId from each response because you need
them to link documents back to their sections.
# Business formation document
curl --request POST \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/documents \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header "X-Idempotency-Key: $(uuidgen)" \
-F fileContent=@/tmp/dummy.pdf -F fileName=formation.pdf \
-F datumName=businessFormationDocuments -F issuedCountry=US
# Financial statements
curl --request POST \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/documents \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header "X-Idempotency-Key: $(uuidgen)" \
-F fileContent=@/tmp/dummy.pdf -F fileName=financials.pdf \
-F datumName=financialStatements -F issuedCountry=US
# Proof of address
curl --request POST \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/documents \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header "X-Idempotency-Key: $(uuidgen)" \
-F fileContent=@/tmp/dummy.pdf -F fileName=address.pdf \
-F datumName=physicalAddressProofOfAddress -F issuedCountry=US
# Bank statement
curl --request POST \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/documents \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header "X-Idempotency-Key: $(uuidgen)" \
-F fileContent=@/tmp/dummy.pdf -F fileName=bank.pdf \
-F datumName=bankBrokerageCryptoStatement -F issuedCountry=US
# Ownership chart
curl --request POST \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/documents \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header "X-Idempotency-Key: $(uuidgen)" \
-F fileContent=@/tmp/dummy.pdf -F fileName=ownership.pdf \
-F datumName=ownershipChart -F issuedCountry=US
4.1. Upload the control person’s government ID
The control person’s government ID requires a refId and documentType. First,
retrieve the refId:
curl --request GET \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/individualWithSignificantControlPersons \
--header 'Authorization: Bearer YOUR_API_KEY'
Find the refId value in data.data[0].refId, then upload the document:
curl --request POST \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/documents \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header "X-Idempotency-Key: $(uuidgen)" \
-F fileContent=@/tmp/dummy.pdf -F fileName=govid.pdf \
-F datumName=controllerGovernmentId -F issuedCountry=US \
-F refId={refId} -F documentType=passport
4.2. Re-save sections with document references
After uploading, link the documents back to their sections by re-saving the
section with the documentId values. For example, re-save
businessRegistrationDetails with the formation document:
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/sections/businessRegistrationDetails \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"businessName": "My Company ABC1",
"businessNameDifferent": false,
"registrationNumber": "00-0000000",
"taxId": "00-0000000",
"countryOfFormation": "US",
"businessStateOfRegistrationOfFormation": "NY",
"dateOfFormation": "2010-01-01",
"businessFormationDocuments": [{ "documentId": "YOUR_DOC_ID" }]
}'
Repeat for these sections, adding the relevant documentId arrays:
physicalBusinessAddress: add physicalAddressProofOfAddress
intendedUseOfAccount: add bankBrokerageCryptoStatement and
financialStatements
beneficialOwnersDetails: add ownershipChart
Step 5: Submit the application
Verify that all sections show a complete status:
curl --request GET \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId} \
--header 'Authorization: Bearer YOUR_API_KEY'
When all sections are complete, submit the application:
curl --request POST \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/{applicationId}/submit \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--header "X-Idempotency-Key: $(uuidgen)" \
--data '{
"endUserIpAddress": "203.0.113.1",
"endUserAgreesToTermsOfService": true
}'
In sandbox, the application is auto-approved almost immediately. In production,
KYB verification takes time and may result in rejection.
Step 6: Retrieve your account
After the application is approved, retrieve the account using the
clientEntityId from step 1:
curl --request GET \
--url "https://api-sandbox.circle.com/v1/accounts?clientEntityId={clientEntityId}" \
--header 'Authorization: Bearer YOUR_API_KEY'
The response includes your active stablecoin account:
{
"data": [
{
"accountId": "1017407114",
"clientEntityId": "992063fe-d52f-3b1e-ab2d-637dd0b0f36e",
"type": "client",
"status": "active",
"description": "Digital Asset Account External Entity Wallet",
"balances": []
}
]
}
Your accountId is now ready for deposits, withdrawals, and transfers. See
Wire deposits and withdrawals
to fund your account.
Common issues
| Problem | Solution |
|---|
500 when creating client | The company name was already used. Use a different clientName. |
422 on intended use of account | Verify that enum values are exact matches. |
Section stuck on incomplete | Confirm that taxId is set in businessRegistrationDetails. |
400 on submit | A section is not complete, or the X-Idempotency-Key header is missing. |
422 on government ID upload | Add documentType=passport to the upload request. |