Skip to main content

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"
  }
}

Step 2: Complete business information

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

ProblemSolution
500 when creating clientThe company name was already used. Use a different clientName.
422 on intended use of accountVerify that enum values are exact matches.
Section stuck on incompleteConfirm that taxId is set in businessRegistrationDetails.
400 on submitA section is not complete, or the X-Idempotency-Key header is missing.
422 on government ID uploadAdd documentType=passport to the upload request.