Accounts
Create and manage the Sub-Platforms of your client businesses and subsidiaries.
A primary platform can create Sub-Platforms for its client businesses (relation: customer) and its subsidiaries (relation: subsidiary). Subsidiaries replace the former managed business accounts. Each sub-platform has its own
secret key, its own KYB and its own data, and is managed from your platform. Its
connected_kind is sub_platform under a platform, and sub_fintech under a
network_partner or a financial_platform.
Capability: oc_platform.sub_tenants.manage (platforms, network partners and financial
platforms).
Create
POST /api/connect/sub-platforms
X-API-Key: oc_live_…
{
"name": "Acme Retail",
"sub_profile_type": "standard",
"balance_mode": "managed",
"relation": "customer",
"website_url": "https://retail.acme.example",
"country": "US",
"customer_link": { "mode": "both", "customer_id": "7c2e9a41-0b3d-4f8e-9a61-5d4c3b2a1f00" }
}| Field | Required | Notes |
|---|---|---|
name | Yes | 2 to 128 characters. |
sub_profile_type | Yes | standard (full dashboard) or custom (white label). express no longer exists. |
relation | No | customer (default, a client) or subsidiary (an entity of your group). |
balance_mode | Yes | managed (you hold the balance) or standalone. |
website_url, logo_url | No | |
country | No | ISO alpha-2. |
customer_link | No | { mode, customer_id }: ties the payments module to a customer of the fintech of record. mode is separate (default), both or replace; customer_id is required for both and replace. See Customer link. |
{
"sub_platform": { "id": "e41b7f20-6c9a-4e3d-8b15-0f2a9d7c3e66", "name": "Acme Retail", "…": "…" },
"api_keys": { "live": "oc_live_…" },
"connected_kind": "sub_platform"
}The response is 201. The key is returned once, here: deliver it to your client's backend only.
It reaches product endpoints once the sub-platform's own KYB is approved. A primary account, or a
platform attached to the Open Connect Foundation, can create sub-platforms (one nested level, see
Platform without a fintech); any other
caller gets 403, and a third level answers 400.
Manage
| Method | Path | Purpose |
|---|---|---|
| GET | /api/connect/sub-platforms?limit=50&offset=0 | List. Max limit 100. Returns { total, items }. |
| GET | /api/connect/sub-platforms/{id} | Read one. |
| POST | /api/connect/sub-platforms/{id}/provision | Provision it. Its connect status becomes active. |
| PATCH | /api/connect/sub-platforms/{id} | Change name, sub_profile_type, balance_mode, relation, logo_url. |
| POST | /api/connect/sub-platforms/{id}/api-keys/reveal | Reveal its key. Requires its KYB to be approved. |
| POST | /api/connect/sub-platforms/{id}/api-keys/rotate | Issue a new key. Shown once. The previous key stops working. Requires its KYB to be approved. |
| POST | /api/connect/sub-platforms/{id}/migrate | Promote it to a primary platform (target: fintech or platform). |
| GET | /api/connect/sub-platforms/{id}/customer-link | Read the customer link of its payments module. |
| PATCH | /api/connect/sub-platforms/{id}/customer-link | Change the mode (separate, both, replace). |
Each account manages only its own sub-platforms: a sub-platform that is not yours answers 404.
Customer link
Creating a sub-platform also creates its payments module (its business wallets and payments).
customer_link says which customer of the fintech of record holds that module. The fintech of
record is the first fintech up the parent chain: your fintech, or the Open Connect Foundation for a
platform without a fintech.
| Mode | What happens | Consequences |
|---|---|---|
separate (default) | A separate business customer is created for the module. | The person's retail customer is untouched. Two customers: one retail, one business. customer_id is ignored. |
both | The given customer holds the module and becomes customer_type: both. | One customer, two sides: the same person keeps their retail accounts and gets the business ones. |
replace | The given customer holds the module and becomes customer_type: business. | The retail side of that customer is turned off; the customer is business-only. |
Rules:
customer_idmust be a customer of the fintech of record (404otherwise) and is required forbothandreplace(400).- A customer holds one payments module at most: a customer already linked to another module
answers
409; a customer that is already business-only cannot be linked again (400).
GET /api/connect/sub-platforms/{id}/customer-link{
"sub_platform_id": "e41b7f20-6c9a-4e3d-8b15-0f2a9d7c3e66",
"payments_module_id": "3f0d1c52-7a8b-4e9c-b1d2-6e5f4a3b2c10",
"mode": "both",
"customer_id": "7c2e9a41-0b3d-4f8e-9a61-5d4c3b2a1f00",
"customer_type": "both"
}PATCH /api/connect/sub-platforms/{id}/customer-link
{ "mode": "replace", "customer_id": "7c2e9a41-0b3d-4f8e-9a61-5d4c3b2a1f00" }- To
bothorreplace: the module moves to the given customer (or stays on the same one:customer_idcan be left out when switching betweenbothandreplace). A previous linked customer goes back toretail. A former separate business customer stays in place with its wallets. - To
separate: the linked customer goes back toretailand a separate business customer is created for the module. - The response carries
previous_customer_idwhen the holder changed (also kept in the module'smetadata.previous_customer_id). Balances do not move between customers.
Transfers to managed sub-platforms
POST /api/connect/sub-platforms/{id}/transfer
{
"amount": 1200,
"currency": "USD",
"application_fee": 12,
"idempotency_key": "payout-2026-10-16-acme-retail",
"metadata": { "period": "2026-10" }
}- The sub-platform must be yours and in
managedbalance mode, otherwise400. idempotency_keyis required (8 to 128 characters). A retry with the same key returns the existing transfer.- The response is
201, withstatus: "pending".
Hosted onboarding
When your client should fill in their own details, create a Connect account and send them an onboarding link:
POST /api/connect/sub-platforms/onboarding/accounts
{ "name": "Acme Retail", "sub_profile_type": "custom", "balance_mode": "standalone" }POST /api/connect/sub-platforms/onboarding/account-links
{ "account_id": "e41b7f20-6c9a-4e3d-8b15-0f2a9d7c3e66", "expires_in_seconds": 86400, "redirect_uri": "https://app.example.com/clients" }{ "account_id": "e41b7f20-6c9a-4e3d-8b15-0f2a9d7c3e66", "onboard_url": "https://portal.openconnect.cc/connect/onboard?…", "expires_at": "2026-10-17T10:50:00.000Z", "connect_status": "pending_merchant" }onboard_url is signed and time-limited (5 minutes to 30 days, 7 days by default). Use it as
returned. GET /api/connect/sub-platforms/onboarding/accounts/{id} shows progress. Connect accounts require the capability
oc_platform.sub_tenants.manage. No key is returned at creation; reveal it later from the
sub-platform routes above.