Skip to main content
Walk through the full application lifecycle: create a client, populate its sections, upload a document, and submit for review.
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.

Prerequisites

Before you begin this quickstart, ensure you’ve:
  • Obtained an API key for the Partner Onboarding API from the Circle Mint Console (Developer > API Keys). Use this key to obtain a Bearer token through the Circle key exchange.
  • (Recommended) Set up a webhook subscription for application status changes in the Console (Developer > Subscriptions) to receive real-time updates instead of polling.

Step 1: Create a client and initialize the application

Create a client and start 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"
    }
  }'
For the full request schema, see Create Partner Client. 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 steps.
Using the same clientName and country combination returns a 409 Conflict error. Use a different clientName to create another client in the same country.

Step 2: Discover the schema

The sections and fields in an application aren’t fixed. They’re defined by a JSON Schema (draft 2020-12) specific to the business type you set with natureOfBusiness and institutionType. Read the schema before you save data so you know which sections and fields apply. Don’t assume field names. Retrieve the schema for your application:
curl --request GET \
  --url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID}/schema \
  --header "Authorization: Bearer ${YOUR_API_KEY}"
Top-level properties map to section names, and each section lists its fields, types, and validation rules. To list sections with their completion status instead, call GET /v1/onboarding/partner/applications/${APPLICATION_ID}/sections. For schema discovery, conditional fields, and bulk save, see Create and populate applications.

Step 3: Save section data

Using the field names from the schema, populate a section. This example saves the basicBusinessInfo section for the trust application created in Step 1. The sections and fields for your application depend on its own schema:
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
  }'
Section and field names vary by business type. Saving a field that isn’t in the section’s schema returns a 422 error with per-field details. Use the schema from Step 2 to see the fields for your application.
The response confirms the section status changed to complete:
{
  "data": {
    "data": {
      "businessWebsite": "https://example.com",
      "businessWebsiteProvided": true
    },
    "sections": [
      { "sectionName": "basicBusinessInfo", "status": "complete" },
      { "sectionName": "physicalBusinessAddress", "status": "not_started" }
    ],
    "sectionsChanged": false
  }
}
Repeat for each remaining section. See Create and populate applications for details on the schema, bulk save, and conditional sections.

Step 4: Upload a document

Upload a supporting document and link it to a schema field:
curl --request POST \
  --url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID}/documents \
  --header "Authorization: Bearer ${YOUR_API_KEY}" \
  --header 'X-Idempotency-Key: ${IDEMPOTENCY_KEY}' \
  --form 'fileContent=@passport.pdf' \
  --form 'fileName=passport.pdf' \
  --form 'datumName=passport_document' \
  --form 'issuedCountry=US'
The response returns the new document ID:
{
  "data": {
    "documentId": "550e8400-e29b-41d4-a716-446655440002"
  }
}
See Upload documents for details on required fields and linking documents to array entities.

Step 5: Submit the application

After all sections are complete and required documents are uploaded, submit the application:
curl --request POST \
  --url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID}/submit \
  --header "Authorization: Bearer ${YOUR_API_KEY}" \
  --header 'Content-Type: application/json' \
  --header 'X-Idempotency-Key: ${IDEMPOTENCY_KEY}' \
  --data '{
    "endUserIpAddress": "203.0.113.42",
    "endUserAgreesToTermsOfService": true
  }'
The application moves to SUBMITTED:
{
  "data": {
    "applicationId": "550e8400-e29b-41d4-a716-446655440000",
    "status": "SUBMITTED"
  }
}

Step 6: Check application status

Poll for the current status or use webhook notifications (if you set up a subscription in the prerequisites) for real-time updates:
curl --request GET \
  --url https://api-sandbox.circle.com/v1/onboarding/partner/applications/${APPLICATION_ID} \
  --header "Authorization: Bearer ${YOUR_API_KEY}"
The application progresses through IN_REVIEW and reaches a terminal status of APPROVED or DENIED. If the compliance team needs more information, the status changes to PENDING_CUSTOMER_INFORMATION. See Application states for the full lifecycle and Submit and track applications for the submission workflow and Handle requests for information if the compliance team needs more data.