Skip to main content
Once a user has an approved ACH relationship, they can move money between their external bank account and their Buildmarkets brokerage account. Buildmarkets exposes two endpoints for this:
  • Deposits (POST .../funding/deposits) — pull funds from the bank into the brokerage account
  • Withdrawals (POST .../funding/withdrawals) — push settled cash from the brokerage account back to the bank
Both transfer types are ACH-based and subject to standard ACH settlement timelines. All amounts must be expressed as strings with exactly two decimal places (e.g., "1000.00").

Transfer lifecycle

All deposits and withdrawals progress through the same status states. You can track these via the Funding Activity endpoints or by listening to webhook events.
      POST deposit/withdrawal

      ┌──────▼──────┐
      │             │
      │   PENDING   │  ◄─── Transfer submitted to ACH network
      │             │
      └──────┬──────┘
             │  ACH initiated
      ┌──────▼──────┐
      │             │
      │  QUEUED /   │  ◄─── Sent to clearing; awaiting settlement
      │  SENT       │
      │             │
      └──────┬──────┘

        ┌────┴────┐
        │         │
    ┌───▼───┐ ┌──▼──────┐
    │       │ │         │
    │SETTLED│ │RETURNED │  ◄─── NSF, closed account, or bank rejection
    │       │ │         │
    └───────┘ └─────────┘
StatusDescription
PENDINGTransfer has been submitted and is awaiting ACH initiation
QUEUEDTransfer has been queued for the next ACH batch
SENTTransfer has been sent to the ACH network and is in transit
SETTLEDFunds have successfully moved; transfer is complete
RETURNEDThe ACH transfer was returned by the bank (e.g., NSF, closed account)
CANCELLEDTransfer was cancelled before clearing
Settlement timing: “Standard ACH deposits typically settle in 1–3 business days. Buildmarkets may apply instant buying power for deposits up to a configured limit, allowing users to trade before funds fully settle.”

Endpoints

MethodPathDescription
POST/v1/accounts/{accountId}/funding/depositsInitiate an ACH deposit into the brokerage account
POST/v1/accounts/{accountId}/funding/withdrawalsInitiate an ACH withdrawal from the brokerage account

Initiate a deposit

Pulls funds from the user’s external bank account into their Buildmarkets brokerage account. The specified ACH relationship must be in APPROVED status.

POST /v1/accounts/{accountId}/funding/deposits

Path parameters

ParameterTypeRequiredDescription
accountIdstring (UUID)The Buildmarkets account to deposit funds into

Request body

FieldTypeRequiredDescription
ach_relationship_idstring (UUID)ID of an APPROVED ACH relationship to pull funds from
amountstringDollar amount to deposit. Must match pattern ^\d+\.\d{2}$ (e.g., "1000.00")
descriptionstringOptional memo visible in funding activity (e.g., "Initial deposit")

Response body (201 Created)

FieldTypeDescription
idstring (UUID)Unique identifier for this funding activity record
account_idstring (UUID)The Buildmarkets account receiving the funds
ach_relationship_idstring (UUID)The ACH relationship used for this transfer
typestringDEPOSIT
amountstringDollar amount transferred (e.g., "1000.00")
statusstringInitial status: PENDING
descriptionstring | nullMemo provided at creation
created_atstring (ISO 8601)Timestamp when the deposit was initiated
updated_atstring (ISO 8601)Timestamp of the last status change
settled_atstring (ISO 8601) | nullTimestamp when funds fully settled; null until SETTLED

Example request

curl -X POST https://api.tappengine.com/v1/accounts/b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f/funding/deposits \
  -H "Authorization: Bearer $BUILDMARKETS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ach_relationship_id": "e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b",
    "amount": "2500.00",
    "description": "Initial deposit"
  }'

Example response

{
  "id": "f1a2b3c4-d5e6-7f8a-9b0c-d1e2f3a4b5c6",
  "account_id": "b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f",
  "ach_relationship_id": "e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b",
  "type": "DEPOSIT",
  "amount": "2500.00",
  "status": "PENDING",
  "description": "Initial deposit",
  "created_at": "2026-03-15T11:00:00Z",
  "updated_at": "2026-03-15T11:00:00Z",
  "settled_at": null
}

Initiate a withdrawal

Pushes settled cash from the user’s Buildmarkets brokerage account back to their external bank account. Only settled cash can be withdrawn — unsettled funds from recent trades or pending deposits are not eligible.

POST /v1/accounts/{accountId}/funding/withdrawals

Path parameters

ParameterTypeRequiredDescription
accountIdstring (UUID)The Buildmarkets account to withdraw funds from

Request body

FieldTypeRequiredDescription
ach_relationship_idstring (UUID)ID of an APPROVED ACH relationship to push funds to
amountstringConditionalDollar amount to withdraw. Required unless withdraw_full_balance is true. Pattern: ^\d+\.\d{2}$
withdraw_full_balancebooleanIf true, withdraws the entire settled cash balance. Omit amount when using this flag
descriptionstringOptional memo (e.g., "Monthly withdrawal")
fee_amountstringOptional processing fee to deduct in addition to amount. Pattern: ^\d+\.\d{2}$

IRA-specific fields

For IRA accounts, additional fields are required to classify the distribution for tax reporting purposes.
FieldTypeRequired for IRADescription
ira_distribution_typestringClassification of the IRA distribution (e.g., "NORMAL", "PREMATURE")
ira_tax_codestringIRS tax code for the distribution
ira_yearintegerTax year to attribute the distribution to (e.g., 2026)
ira_federal_withholdingstringFederal income tax withholding amount. Pattern: ^\d+\.\d{2}$
ira_state_withholdingstringState income tax withholding amount. Pattern: ^\d+\.\d{2}$
ira_statestring2-letter state code for withholding (e.g., "TX"). Required if ira_state_withholding is set

Response body (201 Created)

FieldTypeDescription
idstring (UUID)Unique identifier for this funding activity record
account_idstring (UUID)The Buildmarkets account funds are being withdrawn from
ach_relationship_idstring (UUID)The ACH relationship receiving the funds
typestringWITHDRAWAL
amountstringDollar amount withdrawn (e.g., "500.00")
fee_amountstring | nullFee amount if provided
statusstringInitial status: PENDING
descriptionstring | nullMemo provided at creation
created_atstring (ISO 8601)Timestamp when the withdrawal was initiated
updated_atstring (ISO 8601)Timestamp of the last status change
settled_atstring (ISO 8601) | nullTimestamp when funds settled at the destination bank

Example request — standard withdrawal

curl -X POST https://api.tappengine.com/v1/accounts/b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f/funding/withdrawals \
  -H "Authorization: Bearer $BUILDMARKETS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ach_relationship_id": "e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b",
    "amount": "500.00",
    "description": "Monthly withdrawal"
  }'

Example response

{
  "id": "c4d5e6f7-a8b9-0c1d-2e3f-4a5b6c7d8e9f",
  "account_id": "b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f",
  "ach_relationship_id": "e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b",
  "type": "WITHDRAWAL",
  "amount": "500.00",
  "fee_amount": null,
  "status": "PENDING",
  "description": "Monthly withdrawal",
  "created_at": "2026-03-15T14:00:00Z",
  "updated_at": "2026-03-15T14:00:00Z",
  "settled_at": null
}

Example request — withdraw full balance

curl -X POST https://api.tappengine.com/v1/accounts/b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f/funding/withdrawals \
  -H "Authorization: Bearer $BUILDMARKETS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ach_relationship_id": "e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b",
    "withdraw_full_balance": true,
    "description": "Account liquidation"
  }'

Example request — IRA distribution

curl -X POST https://api.tappengine.com/v1/accounts/b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f/funding/withdrawals \
  -H "Authorization: Bearer $BUILDMARKETS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ach_relationship_id": "e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b",
    "amount": "1000.00",
    "ira_distribution_type": "NORMAL",
    "ira_tax_code": "7",
    "ira_year": 2026,
    "ira_federal_withholding": "100.00",
    "ira_state_withholding": "50.00",
    "ira_state": "CA"
  }'

Common errors

HTTP StatusErrorCause
400INVALID_AMOUNTAmount does not match the ^\d+\.\d{2}$ pattern, or is zero
400AMOUNT_REQUIREDNeither amount nor withdraw_full_balance was provided
400INVALID_IRA_FIELDSIRA distribution fields are incomplete or contain invalid values
404ACCOUNT_NOT_FOUNDThe accountId does not exist or is inaccessible
404ACH_RELATIONSHIP_NOT_FOUNDThe ach_relationship_id does not exist for this account
409ACH_RELATIONSHIP_NOT_APPROVEDThe referenced ACH relationship is not in APPROVED status
422INSUFFICIENT_FUNDSWithdrawal amount exceeds settled cash balance
422ACCOUNT_NOT_ACTIVEThe Buildmarkets account is not in ACTIVE status

Webhook events

Subscribe to these events to track transfer status in real time without polling.
EventFired when
funding.deposit.pendingDeposit has been accepted and is queued for ACH
funding.deposit.settledDeposit has fully cleared and funds are available
funding.deposit.returnedDeposit was returned by the bank
funding.withdrawal.pendingWithdrawal has been accepted and is queued for ACH
funding.withdrawal.settledWithdrawal has fully cleared at the destination bank
funding.withdrawal.returnedWithdrawal was returned by the bank
See Webhook Events Reference for full payload schemas.

Next steps

Updated 3 months ago

Funding Activity

The funding activity endpoints provide a comprehensive, auditable record of all ACH transfers on a brokerage account—including deposits, withdrawals, fees, and bank returns. These tools enable transaction history interfaces, account reconciliation, and transfer status investigation.

Available Endpoints

Two primary endpoints exist:
  1. List all funding activity: GET /v1/accounts/{accountId}/funding/activity
  2. Retrieve single record: GET /v1/accounts/{accountId}/funding/activity/{activityId}

Listing Funding Activity

The list endpoint returns paginated results ordered by most recent first. Required parameters include the account UUID. Optional query filters include:
  • status: Transfer state (PENDING, QUEUED, SENT, SETTLED, RETURNED, CANCELLED)
  • type: DEPOSIT or WITHDRAWAL
  • start_date and end_date: ISO 8601 date ranges
  • page and per_page: Pagination controls (default 25, max 100 per page)
Response objects contain transfer identification, amounts, status transitions, descriptions, and ACH return codes when applicable.

Single Record Retrieval

This endpoint accepts an account ID and activity ID, returning complete details about that specific transfer—particularly useful for checking current status or examining return codes for rejected transfers.

ACH Return Codes

The system uses standard NACHA codes when transfers are rejected. Common examples include:
  • “R01” (Insufficient Funds)
  • “R02” (Account Closed)
  • “R03” (No Account/Unable to Locate)
  • “R10” (Customer Claims Unauthorized)
Webhook events (funding.deposit.returned or funding.withdrawal.returned) notify applications when transfers fail, including both code and human-readable explanation.

Error Handling

Common HTTP 404 responses indicate either missing account or activity records inaccessible to the API key.