onBehalfOf set to that customer.
There is no separate Connect resource or funds-flow toggle. The flow is three stages — onboard, issue accounts, transfer — each using existing API calls.
Who this is for
First-party (moving your own money) does not need Connect. Create accounts and transfers for your organization’s own customer record.
1. Onboard your customer
Create a customer under your organization, then verify them.The HTTP fragments below are illustrative. Use the API reference examples (Python, TypeScript, CLI, cURL) or your HTTP client with authentication to execute requests.
Create
POST /v1/customers/individuals when the end user is a person. See Customers.
Verify
Hosted link (recommended for platforms): send the customer Infinite’s hosted KYC / KYB UI.Idempotency-Key; reuse behavior depends on existing session state and can return 400 if a session is already pending. For associated individuals (UBOs), use generate a verification link for an associated entity.
API-driven: collect data in your UI, then save and submit verification on the customer. Full flow: Verification.
Wait until the customer is ACTIVE and the capabilities you need are READY before issuing payment accounts or creating transfers. ACTIVE is compliance approval only — individual rails can stay IN_REVIEW until their onboarding finishes. Subscribe to exact webhook event names such as customer.status_changed and customer.capability.updated (endpoint filterTypes match exact strings — wildcards like customer.* deliver nothing). For transfer and external-account events, use the same exact names as checklist step 6. Poll GET /v1/customers/{id} for customer status; do not use GET /v1/verification/customers/{id} for approval — it returns verification-session state (ACTIVE, SUBMITTED, …), not customer compliance status.
Full lifecycle: Customers.
2. Issue accounts
Once the customer isACTIVE and the relevant capabilities are READY, open the accounts that customer will hold and pay from.
Accounts always belong to a
cus_. Your org key creates them; the customer owns the balances.
External accounts emit external_account.in_review, external_account.approved, and external_account.rejected (subscribe with those exact names if you filter webhooks). Do not treat a destination as payable until it is ACTIVE.
3. Move money on their behalf
Every transfer takesonBehalfOf set to the end customer’s id. Your organization API key signs the request; the customer is the principal on the payment.
paymentRail: "BALANCE" when the source is a held USD balance account. Generate one high-entropy Idempotency-Key per logical transfer, persist it with your payout record, and send the same key on every retry (timeouts included). With confirm: true, a fresh key on retry can create a second submitted transfer. See Idempotency.
Monitor payouts with the same exact transfer webhook names as checklist step 6: transfer.completed, transfer.failed, transfer.updated, transfer.cancelled, and transfer.reversed. Cancellations emit transfer.cancelled, not transfer.updated.
Payees who are not the customer
When the destination is a third-party payee (not the customer’s own external account), create a counterparty (cp_), attach their external account with isThirdParty: true and that counterpartyId (both are required — omitting isThirdParty returns 400), wait until the account is ACTIVE, then pass counterpartyId on the transfer.
Counterparties are organization-scoped and can be linked to more than one customer through accounts. Screening still runs on the destination before it becomes payable.
Platform take-rate
Take your cut in the settlement path withdeveloperFeeFixed and developerFeePercent on transfers and fixed routes when the route supports fees. The API rejects fees on balance-account destinations and on some fiat deposit routes — confirm support for your corridor before relying on a take-rate. See Transfers — Developer fees, Agents — Bill, and Fixed routes.
Terms of service (API-driven onboarding)
When you collect verification data in your UI instead of a hosted verification link, record Terms of Service acceptance before verification submit. Recommended: persist verification inputs that affect which agreements apply (requested capabilities, industry, and related profile fields) before generating a link, or pass the primary customer’sverificationSessionId on generate — otherwise hosted-context can omit a required agreement block and submit returns 400 for incomplete ToS. Then call POST /v1/tos/generate with the customer’s id (and verificationSessionId for associated-person acceptance). Send the end user the returned acceptanceUrl so they complete every agreement Infinite requires for that customer. Poll GET /v1/tos/{id} until acceptedAt is set, then pass the id as metadata.infiniteTosAcceptanceId on verification submit. Do not call POST /v1/tos/{id}/accept on the user’s behalf.
Custom UI (advanced): call POST /v1/tos, then GET /v1/tos/{id}/hosted-context to learn which additional agreement blocks apply for that customer. On POST /v1/tos/{id}/accept, set infiniteAgreementsAccepted: true and set each matching agreement field to true when hosted-context shows that block is required — otherwise submit can return 400. Use the additional-agreement flags from hosted-context and the corresponding accept-body fields documented in the API reference (same names, different prefixes).
Shortcut: hasAgreedToTos: true on verification submit uses the API shortcut: Infinite’s core agreements are always recorded, and additional regional or rail agreements that onboarding routing can infer are pre-filled in the same step. When no agreement block still requires explicit end-user acceptance, the record is fully accepted. If any block still requires explicit acceptance, acceptedAt stays null until the customer completes hosted acceptance or a full accept call — use POST /v1/tos/generate or manual accept for those cases, and confirm with GET /v1/tos/{id} and GET /v1/customers/{id}/compliance before submit.
Customer create/update does not record ToS.
AI assistants (MCP)
Platforms can wire the Infinite MCP server into any MCP-capable assistant or IDE with an organization API key or Auth Kit sign-in.
Header rules (MCP):
- OAuth/Auth Kit sign-in:
X-Infinite-On-Behalf-Ofis forbidden. Bind withbind_session_customerusing thecontinuationTokenfromcreate_business_customer. - Delegation (in‑app assistant) sessions: header is allowed when it matches the pinned customer in the delegation token; without a pinned claim it is allowed only for customers owned by your organization.
- API keys: header is allowed only for customers owned by your organization.
create_business_customer, then bind_session_customer (or use continuationToken after disconnect). See Platform Connect transfers and Agents.
Child organizations (optional)
POST /v1/organizations/{organizationId}/children creates a separate organization under yours. That is a tenancy feature (separate keys, data, and config), capability-gated — not required for Connect or third-party funds flow.
Use child orgs when you need hard isolation between brands or environments. Use customers + onBehalfOf when you are one platform serving many end businesses.
Checklist
- Create
cus_under your org - Hosted or API verification → wait for
ACTIVEand required capabilitiesREADY - Issue balance / wallet / fixed-route / external accounts
- Screen payees (
cp_+ external accounts →ACTIVE) POST /v1/transferswithonBehalfOfand a persistedIdempotency-Keyreused on retries- Subscribe with exact event names (or omit
filterTypesfor all):customer.status_changed,customer.capability.updated,transfer.completed,transfer.failed,transfer.updated,transfer.cancelled,transfer.reversed,external_account.in_review,external_account.approved,external_account.rejected,counterparty.created— see Webhooks
Next steps
Customers
Customer lifecycle and status
Verification
Hosted links and API KYC / KYB
Accounts
Mailboxes, vaults, and external destinations
Transfers
Create and track payments
Webhooks
Lifecycle events
Agents
Same objects for agent-initiated pay
MCP
Hosted onboarding and platform Connect transfers from AI tools