Open an Account
Create a customer account, submit required agreement details, and track account activation status.
Create an account so a customer can hold, receive, and move funds on the platform. An account is either a Deposit Account (customer-owned) or a Clearing (FBO) Account (platform-controlled). Every account is created under a customer, so create the customer first and keep its id or externalId. For the full field list, jump to the Request reference.
Common use cases
- Open a deposit account a customer controls to hold funds, send and receive payments, and enable cards.
- Open a clearing (FBO) account to aggregate funds and orchestrate splits, pay-ins, and payouts.
- Set an account
purpose(for example operating, settlement, or fee) for cleaner reconciliation. - Capture a customer's acceptance of the Passport Account Agreement (SPAA) on a customer-owned account.
Scenarios
Every account creation follows the same flow: submit, validate customer info, verify compliance, activate. The activation path differs by ownership model, so pick the scenario that matches your account type.
sequenceDiagram
participant App as Your application
participant PCE as PCE
participant Compliance as KYC/CIP/OFAC
App->>PCE: POST /account (type, isCustomerOwned, linkedDocument)
PCE->>PCE: Validate customer details
PCE-->>App: 201 Created — account id in url header (status INACTIVE)
alt isCustomerOwned = false (FBO / clearing)
PCE->>Compliance: OFAC screening
Compliance-->>PCE: OFAC result
alt OFAC passed
PCE-->>App: account.update webhook — status ACTIVE
else OFAC rejected
PCE-->>App: account.update webhook — status BLOCKED
end
else isCustomerOwned = true (customer-owned deposit)
Note over PCE: Stays INACTIVE until SPAA is submitted
PCE->>Compliance: SPAA + OFAC + CIP checks
Compliance-->>PCE: Verification result
alt All checks passed
PCE-->>App: account.update webhook — status ACTIVE
else OFAC or CIP rejected
PCE-->>App: account.update webhook — status BLOCKED
end
end
Before you begin (all scenarios)
- The customer exists and has the required KYC information.
- You've stored the customer
idorexternalId. - For a customer-owned account, the account agreement (SPAA) and acceptance details are ready.
Scenario 1: Open a customer-owned deposit account
Use this when the customer owns and controls the account. The account owner must accept the Passport Account Agreement (SPAA); the account activates after the SPAA, OFAC, and CIP checks pass.
You'll also need: customer KYC details complete, and a signed agreement captured via CLICKWRAP, ESIGN, or WETSIGN.
Request
POST /v1/customer/id/48201/account
{
"externalId": "acct-operating-001",
"type": "CHECKING",
"isCustomerOwned": true,
"nickName": "Operating Account",
"purpose": "OPERATING",
"isPrimary": true,
"acceptanceMode": "CLICKWRAP",
"acceptanceDetails": [
{
"ipAddress": "192.168.1.100",
"acceptedOn": "07/09/2026",
"acceptedBy": {
"entity": "BENEFICIAL_OWNER",
"id": "72114"
}
}
],
"linkedDocument": [
{
"purpose": "AUTHORIZATION",
"document": {
"type": "SPAA",
"name": "spaa-signed.pdf",
"base64encodedContent": "Q3Jvc3Nyb2FkcyBGaW4..."
}
}
]
}Response
Returns 201 Created with the account id in the url response header (no body). Retrieve the account to read its status; while compliance is in progress it is INACTIVE:
{
"resourceName": "account",
"url": "v1/customer/id/48201/account/id/88712",
"id": 88712,
"externalId": "acct-operating-001",
"accountNumber": "8125000200002212",
"status": "INACTIVE",
"statusReason": "PENDING_VERIFICATION",
"statusDate": "07/09/2026 10:15:02",
"balance": {
"amount": "0.00",
"asOn": "07/09/2026 10:15:02"
},
"availableBalance": {
"amount": "0.00",
"asOn": "07/09/2026 10:15:02"
},
"purpose": "OPERATING",
"linkedDocument": [
{
"id": 22585,
"purpose": "AUTHORIZATION",
"status": "PENDING_VERIFICATION",
"document": {
"resourceName": "document",
"url": "/v1/document/id/4020651",
"id": 4020651,
"type": "SPAA",
"name": "spaa-signed.pdf"
},
"linkedOn": "07/09/2026 10:15:02",
"linkedBy": {
"userType": "API_USER",
"username": "[email protected]",
"status": "ACTIVE"
}
}
],
"createdOn": "07/09/2026 10:15:02",
"createdBy": {
"userType": "API_USER",
"username": "[email protected]",
"status": "ACTIVE"
},
"lastUpdatedBy": {
"userType": "API_USER",
"username": "[email protected]",
"status": "ACTIVE"
},
"lastUpdatedOn": "07/09/2026 10:15:02",
"type": "CHECKING",
"isCustomerOwned": true,
"nickName": "Operating Account",
"isPrimary": true
}It moves to ACTIVE once the SPAA, OFAC, and CIP checks complete. Track the change with the account.update webhook.
Scenario 2: Open a platform-controlled FBO account
Use this for a clearing account your platform manages on behalf of the customer. The account owner must still acknowledge the Passport Account Agreement and, for payment services, the applicable Payment Services Terms & Conditions (see Account Types). The account activates after OFAC screening, with no linked SPAA document and no CIP step.
You'll also need: the account owner's acknowledgment of the applicable agreements.
Request
POST /v1/customer/id/48201/account
{
"externalId": "acct-settlement-001",
"type": "CHECKING",
"isCustomerOwned": false,
"nickName": "Settlement Account",
"purpose": "SETTLEMENT"
}Response
Returns 201 Created with the account id in the url header. FBO accounts activate once the customer's OFAC screening passes. Retrieving the account returns:
{
"resourceName": "account",
"url": "v1/customer/id/48201/account/id/88713",
"id": 88713,
"externalId": "acct-settlement-001",
"accountNumber": "8125000200008547",
"status": "ACTIVE",
"statusReason": "ACTIVATED_BY_SYSTEM",
"statusDate": "07/09/2026 06:06:20",
"balance": {
"amount": "0.00",
"asOn": "07/09/2026 06:06:20"
},
"availableBalance": {
"amount": "0.00",
"asOn": "07/09/2026 06:06:20"
},
"actualBalance": {
"amount": "0.00",
"asOn": "07/09/2026 06:06:20"
},
"holdBalance": {
"amount": "0.00",
"asOn": "07/09/2026 06:06:20"
},
"purpose": "SETTLEMENT",
"routableAccount": {
"accountNumber": "76650000013869",
"routingNumber": "053101561",
"wireRoutingNumber": "122287251",
"wireAccountNumber": "200100165584",
"wireMemo": "Settlement Account 13976650000013869",
"memo": "Settlement Account 76650000013869"
},
"createdOn": "07/09/2026 06:06:17",
"createdBy": {
"userType": "API_USER",
"username": "[email protected]",
"status": "ACTIVE"
},
"lastUpdatedBy": {
"userType": "SYSTEM",
"username": "SYSTEM",
"status": "ACTIVE"
},
"lastUpdatedOn": "07/09/2026 06:06:20",
"type": "CHECKING",
"isCustomerOwned": false,
"nickName": "Settlement Account",
"activationDate": "07/09/2026 06:06:20",
"isPrimary": false,
"totalCredit": {
"amount": "0.00",
"asOn": "07/09/2026 06:06:20"
},
"totalDebit": {
"amount": "0.00",
"asOn": "07/09/2026 06:06:20"
}
}FBO accounts typically activate faster than deposit accounts because the create request doesn't carry a linked SPAA document for individual verification.
Track the account
Subscribe to webhooks or retrieve the account to follow it to activation. Because compliance checks can be asynchronous, watch for the status change rather than assuming success on create.
- Retrieve:
GET/v1/customer/id/{id}/account/id/{accountId}to read the accountstatusandstatusReason. - Webhooks: subscribe to
account.create(creation) andaccount.update(status changes such asINACTIVE→ACTIVEorBLOCKED).
For status definitions and lifecycle behavior, see Account Lifecycle.
Request reference
The complete set of fields for the create-account request. Scenarios above use subsets of these. Send the request to /v1/customer/id/{id}/account or /v1/customer/externalId/{external-id}/account. A successful create returns 201 Created with the new account id in the url response header (no body).
UseexternalIdfor safe retriesFor Treasury, PCE treats the
externalIdin the request body as the idempotency key; there's no separate header. Send a uniqueexternalIdper account, and retrying with the same value creates it only once.
Core parameters
| Parameter | Required | Description |
|---|---|---|
isCustomerOwned | Recommended | Ownership model. true for a customer-owned deposit account; false (default) for a clearing (FBO) account managed by the platform/ISV. |
type | Optional | Account type. Defaults to CHECKING. Allowed values: CHECKING, CASH_BUILDER_PLUS. |
purpose | Optional | Intended purpose of the account, for example SETTLEMENT, FEE, OPERATING, PAYROLL, or RESERVE. Purpose values are configured during program setup; an unconfigured value is rejected with a validation error (EC-BL-0632). Contact the Account Management team to confirm the values enabled for your program. |
externalId | Optional | Your external reference ID for the account. Once assigned it cannot be updated and must be unique across all accounts. |
nickName | Optional | A nickname to easily recognise the account. |
isPrimary | Optional | Sets one of the customer's accounts as primary. The customer's first account is primary by default. Possible values: true or false. |
Agreement and acceptance
Required for a customer-owned account (isCustomerOwned = true) to activate. If omitted, the account is created INACTIVE until an SPAA is submitted (via the Update Account API). Not used for FBO accounts.
| Parameter | Required | Description |
|---|---|---|
linkedDocument | Conditional | An array of documents linked to the account (the account agreement). |
linkedDocument[].purpose | Conditional | Purpose of the linked document. Allowed value: AUTHORIZATION. |
linkedDocument[].document.type | Conditional | Agreement type. Use SPAA for a customer-owned CHECKING deposit account; use PASSPORT_CASH_BUILDER_PLUS_ACCOUNT_AGREEMENT for a CASH_BUILDER_PLUS account. |
linkedDocument[].document.name | Conditional | File name of the document being linked. |
linkedDocument[].document.base64encodedContent | Conditional | Base64-encoded file of the signed document (for WETSIGN), or of the agreement accepted via ESIGN or CLICKWRAP. |
acceptanceMode | Recommended | How the customer accepted the agreement: CLICKWRAP (clicks an acceptance control), ESIGN (electronic signature flow), or WETSIGN (signs offline and the document is uploaded). |
acceptanceDetails | Recommended | An array of acceptance records. For CLICKWRAP and ESIGN, passing these supports faster review and approval. |
acceptanceDetails[].ipAddress | Recommended | IP address of the device accepting the agreement. |
acceptanceDetails[].acceptedOn | Recommended | Date the agreement was accepted. Format: mm/dd/yyyy. |
acceptanceDetails[].acceptedBy (entity, id) | Recommended | Who accepted the agreement. entity is CUSTOMER (individual customer) or BENEFICIAL_OWNER (business customer); id is the identifier of that entity. |
Validation
The prerequisites above are the validations, and PCE enforces them when you submit. A submission is checked synchronously; if a check fails, the request returns an error and no account is created. Correct the issue and resubmit. For error codes, see the HTTP Response Codes and Account Error codes.
When isCustomerOwned is true, these customer-level details must be present:
- Individual:
firstName,lastName,ssn,dob,mailingAddresswithisPrimary=true,mobilePhone,email. - Business:
legalName,ein,stateOfIncorporation,dateOfIncorporation,doingBusinessAs,phone,email,businessCategory, andbeneficialOwnerdetails. For abeneficialOwnerwithactAsAuthorizedSignatory=true,emailandmobilePhoneare mandatory.
Update customer information with a POST to /v1/customer/id/{id} or /v1/customer/externalId/{external-id}.
An account is created in INACTIVE status and becomes ACTIVE only after the required checks pass (OFAC for FBO accounts; SPAA + OFAC + CIP for customer-owned accounts). Activation can require manual verification and take additional time; while under review the account stays INACTIVE with statusReason PENDING_VERIFICATION. The account is not ready to transact until its status is ACTIVE.
Statuses
Open an Account uses the shared account lifecycle. See Account Lifecycle for every status (INACTIVE, ACTIVE, BLOCKED, CLOSURE_INITIATED, CLOSED) and what each one allows.
If activation doesn't complete
An account stays INACTIVE while KYC/compliance is pending or the SPAA hasn't been submitted, and moves to BLOCKED when OFAC or CIP fails. Identify the failing check from the customer's verification status, resolve it, and (for a missing SPAA) submit the document via the Update Account API. For specific codes, see Account Error codes.
Sandbox testing
Use the sandbox to test activation outcomes before going live. Status updates may be asynchronous, so retrieve the account after the recommended wait time to confirm the final status, using GET /v1/customer/id/{id}/account/id/{accountId}.
| Scenario | Customer test data | Account test data | Expected result | Wait time |
|---|---|---|---|---|
| OFAC failure | Business customer: business.legalName = block | Create an account for the customer | status: BLOCKED, statusReason: Customer OFAC Rejected | ~5 minutes |
| Successful activation | Business customer: business.legalName = William | isCustomerOwned: true | status: ACTIVE, statusReason: VERIFIED | ~30 minutes |
For individual customers, use firstName = block and lastName = block to test OFAC failure, and any other name to test successful activation. Sandbox transitions may take several minutes; don't assume the account is ready to transact until the retrieved status is ACTIVE.
Go live
The shared pre-production checklist (production credentials, webhook subscription and signature validation, idempotency, and sandbox testing) is in Getting Started. Specific to opening accounts, also confirm:
- For customer-owned accounts, you capture and link the SPAA and record acceptance (
CLICKWRAP,ESIGN, orWETSIGN). - The required customer KYC fields are present before you create a customer-owned account.
- You subscribe to the
account.updatewebhook to track activation toACTIVE.
Best practices
| Practice | Description |
|---|---|
| Store the account identifiers | Persist the returned id and your externalId for retrieval and reconciliation. |
Use externalId for idempotency | Send a unique externalId per account so retries don't create duplicates. |
Wait for ACTIVE | Don't attempt transactions until the account status is ACTIVE. |
| Capture acceptance details | For CLICKWRAP and ESIGN, pass acceptanceDetails to speed up review and approval. |
Next steps
See also
- Account Types: account models, ownership, and agreements
- Account Lifecycle: every status and how to resolve it
- Funding instructions: share your details to receive funds into an active account
- Account Error codes: resolve a failed account creation
Updated 1 day ago