The Partner Onboarding API base URL is https://api-sandbox.circle.com for
sandbox and https://api.circle.com for production. All requests require a
Bearer token obtained via Circle key exchange in the Authorization header. All
POST requests require an X-Idempotency-Key header with a client-generated
UUID v4.
Populate an onboarding application by creating a client, reading the schema,
listing sections, and saving field data — individually or in bulk — and cancel
draft applications you no longer need.
Prerequisites
Before you begin:
- You have an API key for the Partner Onboarding API from the
Circle Mint Console.
- You can create a client and initialize an application using
POST /v1/partner/clients (covered in Step 1).
Steps
Step 1. Create a client and initialize the application
Create a client record and initialize an onboarding application in one request:
curl --request POST \
--url https://api-sandbox.circle.com/v1/partner/clients \
--header "Authorization: Bearer ${YOUR_API_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"clientName": "Acme Trust Co.",
"country": "US",
"clientType": "business",
"businessDetails": {
"natureOfBusiness": "trust",
"institutionType": "trust"
}
}'
| Field | Type | Required | Description |
|---|
clientName | string | Yes | Display name for the client entity. |
country | string | Yes | ISO 3166-1 alpha-2 country code. |
clientType | string | Yes | Type of client. Currently business is the only supported value. |
businessDetails | object | Yes (for business) | Business-specific details. Required when clientType is business. |
businessDetails.natureOfBusiness | string | Yes (for business) | Industry classification (for example, trust, cryptoExchange). Determines which sections and fields appear in the application. |
businessDetails.institutionType | string | Yes (for business) | Legal entity type. Must be one of: publicCo, privateCo, trust, foundation, partnership, soleTrader, associationOrConsortium, coop, governmentBody. |
Example response:
{
"data": {
"clientEntityId": "880e8400-e29b-41d4-a716-446655440099",
"applicationId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Save the applicationId. You’ll use it in all subsequent
/v1/onboarding/partner/applications/... calls.
Using the same clientName and country combination returns a 409 Conflict
error. Use a different clientName to create another client in the same
country.
Retrieve the newly created application to inspect its sections and statuses:
curl --request GET \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID} \
--header "Authorization: Bearer ${YOUR_API_KEY}"
Example response:
{
"data": {
"applicationId": "550e8400-e29b-41d4-a716-446655440000",
"status": "DRAFT",
"sections": [
{ "sectionName": "basicBusinessInfo", "status": "not_started" },
{ "sectionName": "physicalBusinessAddress", "status": "not_started" },
{ "sectionName": "beneficial_owners", "status": "not_started" }
],
"pendingRfis": []
}
}
Step 2. Discover the schema
Retrieve the JSON Schema (draft 2020-12) for your application. It defines every
required field:
curl --request GET \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID}/schema \
--header "Authorization: Bearer ${YOUR_API_KEY}"
The schema is a single JSON document. Top-level properties map to section
names. Each section lists its fields, types, and validation rules such as
minLength, maxLength, pattern, enum, and format.
Use this schema to:
- Enumerate all sections and their fields.
- Drive client-side form rendering and validation.
- Understand which fields are conditional. See
Conditional logic for
details.
Pass ?resolved=true to receive a schema pruned against the application’s
current saved data. Conditional branches that have not been activated are
removed, so you only see the fields relevant to the current application state.
Step 3. List all sections
List all sections with their current completion status:
curl --request GET \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID}/sections \
--header "Authorization: Bearer ${YOUR_API_KEY}"
Each section has a status: not_started, incomplete, complete, or
action_required.
Example response:
{
"data": {
"sections": [
{ "sectionName": "basicBusinessInfo", "status": "not_started" },
{ "sectionName": "physicalBusinessAddress", "status": "not_started" },
{ "sectionName": "beneficial_owners", "status": "not_started" }
]
}
}
To include each section’s current field data in the same response, add
?includeData=true.
Step 4. Save section data
Save data for a single section:
curl --request PUT \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID}/sections/basicBusinessInfo \
--header "Authorization: Bearer ${YOUR_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{
"businessWebsite": "https://example.com",
"businessWebsiteProvided": true
}'
The server validates the payload against the JSON Schema before saving. If
validation fails, the API returns a 422 response with per-field errors. Each
error includes a dot-notation path, error code, and message.
Example 422 error response:
{
"errors": [
{
"path": "businessWebsite",
"code": "format",
"message": "must be a valid URL"
}
]
}
Saving a section may change other sections’ statuses. For example, a conditional
section may become required. The response includes a sectionsChanged flag.
Check this flag and re-fetch sections as needed.The response also includes a fieldsChanged flag. When true, the server
modified one or more field values during save — for example, clearing a field
that is no longer applicable after a conditional change. Re-fetch the section
data if you need to display the current saved state.
Example response:
{
"data": {
"data": {
"businessWebsite": "https://example.com",
"businessWebsiteProvided": true
},
"sections": [
{ "sectionName": "basicBusinessInfo", "status": "complete" },
{ "sectionName": "physicalBusinessAddress", "status": "not_started" },
{ "sectionName": "beneficial_owners", "status": "not_started" }
],
"sectionsChanged": false,
"fieldsChanged": false
}
}
Step 5. Bulk save (optional)
If your backend already has all the data, use the bulk save endpoint. It fills
multiple sections in one request:
curl --request PATCH \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID}/data \
--header "Authorization: Bearer ${YOUR_API_KEY}" \
--header 'Content-Type: application/json' \
--data '{
"basicBusinessInfo": {
"businessWebsite": "https://example.com",
"businessWebsiteProvided": true
},
"physicalBusinessAddress": {
"physicalAddressLine1": "123 Main St",
"physicalAddressCity": "San Francisco",
"physicalAddressCountry": "US",
"physicalAddressPostalCode": "94102"
}
}'
Validation is atomic. The API checks all sections against the JSON Schema before
saving. If any section fails, no data is written. The response lists errors
across all sections.
After validation passes, sections save one at a time. Saving a section may
activate other conditional sections. If a failure occurs mid-save, earlier
sections may already be persisted.
When to use bulk vs. per-section
| Use case | Recommended endpoint |
|---|
| Interactive form-based UI (one section at a time) | PUT /sections/{sectionName} |
| Programmatic integration with all data available | PATCH /data |
| RFI response updating multiple affected sections | PATCH /data |
| Reading saved data or deleting individual entities | GET/DELETE /sections/... |
Step 6. Read all saved data
To retrieve the complete current state of an application in one request, use the
bulk read endpoint:
curl --request GET \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID}/data \
--header "Authorization: Bearer ${YOUR_API_KEY}"
The response data field is an object keyed by section name — the same
structure as the PATCH /data request body, making it straightforward to
pre-fill a UI or sync application state to your backend. The sections array
lists each visible section with its current status. For full parameter and
response details, see the
Get all application data API
reference.
Example response:
{
"data": {
"data": {
"basicBusinessInfo": {
"businessWebsite": "https://example.com",
"businessWebsiteProvided": true
},
"physicalBusinessAddress": {
"physicalAddressLine1": "123 Main St",
"physicalAddressCity": "San Francisco",
"physicalAddressCountry": "US",
"physicalAddressPostalCode": "94102"
}
},
"sections": [
{ "sectionName": "basicBusinessInfo", "status": "complete" },
{ "sectionName": "physicalBusinessAddress", "status": "complete" }
]
}
}
Cancel an application
Cancel a DRAFT application that is no longer needed:
curl --request DELETE \
--url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID} \
--header "Authorization: Bearer ${YOUR_API_KEY}"
You can only cancel applications in DRAFT status. Other statuses return a
409 error.
See also