Skip to main content
Before a user can move money into or out of their brokerage account, you must establish a trusted link between their Buildmarkets account and an external bank account they own. That link is called an ACH relationship. It is the permanent, reusable funding rail that makes all subsequent deposits and withdrawals possible. An ACH relationship represents a verified connection to a specific external bank account — identified by routing number and account number. Once created and approved, the relationship can be used repeatedly for funding activity without re-entering bank credentials. A single Buildmarkets account can hold multiple ACH relationships (e.g., a checking account and a savings account), but only APPROVED relationships can be used to initiate transfers.

ACH relationship lifecycle

When a relationship is created, it passes through a short verification workflow before becoming active. Buildmarkets uses third-party instant verification in production — there are no micro-deposits.
                    ┌─────────────┐
         POST       │             │
  ──────────────►   │   PENDING   │
                    │             │
                    └──────┬──────┘
                           │  Third-party verification
              ┌────────────┴────────────┐
              │                         │
       ┌──────▼──────┐           ┌──────▼──────┐
       │             │           │             │
       │  APPROVED   │           │  REJECTED   │
       │             │           │             │
       └──────┬──────┘           └─────────────┘
              │                   Create a new relationship
              │  DELETE
       ┌──────▼──────┐
       │             │
       │  CANCELLED  │  ◄─── Permanent; cannot be reactivated
       │             │
       └─────────────┘
StatusDescription
PENDINGRelationship submitted; verification in progress
APPROVEDVerified and active — can be used for transfers
REJECTEDVerification failed; a new relationship must be created
CANCELLEDPermanently removed via DELETE; cannot be reactivated
Sandbox behavior: In the sandbox environment, relationships transition from PENDINGAPPROVED immediately upon creation. No third-party call is made.

Endpoints

MethodPathDescription
POST/v1/accounts/{accountId}/ach-relationshipsLink a new bank account
GET/v1/accounts/{accountId}/ach-relationshipsList all ACH relationships for an account
DELETE/v1/accounts/{accountId}/ach-relationships/{achId}Remove an ACH relationship

Create an ACH relationship

Links an external bank account to the specified Buildmarkets brokerage account. Buildmarkets automatically attempts instant verification via a third-party bank data provider. If verification succeeds, the relationship moves to APPROVED without any manual review. Only the last 4 digits of the bank account number are stored after creation. The full number is never returned in any subsequent API response.

POST /v1/accounts/{accountId}/ach-relationships

Path parameters

ParameterTypeRequiredDescription
accountIdstring (UUID)The Buildmarkets account ID to link the bank account to

Request body

FieldTypeRequiredDescription
bank_account_owner_namestringFull legal name of the account holder at the bank. Must match bank records
bank_account_typestringType of bank account. Enum: CHECKING, SAVINGS
bank_routing_numberstring9-digit ABA routing number. Exactly 9 characters
bank_account_numberstringBank account number. 4–17 characters. Only last 4 digits are stored
bank_namestringOptional name of the bank institution (e.g., "Chase")

Response body (201 Created)

FieldTypeDescription
idstring (UUID)Unique identifier for this ACH relationship
account_idstring (UUID)The Buildmarkets account this relationship is linked to
statusstringCurrent lifecycle status: PENDING, APPROVED, REJECTED, CANCELLED
bank_account_typestringCHECKING or SAVINGS
bank_account_numberstringMasked — last 4 digits only (e.g., ****9012)
bank_routing_numberstringFull 9-digit ABA routing number
bank_account_owner_namestringName on file at the bank
bank_namestring | nullBank name if provided at creation
created_atstring (ISO 8601)Timestamp when the relationship was created
updated_atstring (ISO 8601)Timestamp of the last status change

Example request

curl -X POST https://api.tappengine.com/v1/accounts/b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f/ach-relationships \
  -H "Authorization: Bearer $BUILDMARKETS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "bank_account_owner_name": "Jane Smith",
    "bank_account_type": "CHECKING",
    "bank_routing_number": "021000021",
    "bank_account_number": "123456789012",
    "bank_name": "Chase"
  }'

Example response

{
  "id": "e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b",
  "account_id": "b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f",
  "status": "APPROVED",
  "bank_account_type": "CHECKING",
  "bank_account_number": "****9012",
  "bank_routing_number": "021000021",
  "bank_account_owner_name": "Jane Smith",
  "bank_name": "Chase",
  "created_at": "2026-03-15T10:30:00Z",
  "updated_at": "2026-03-15T10:30:01Z"
}
Note: In production, status will initially be PENDING. The relationship transitions to APPROVED or REJECTED asynchronously. Listen for the ach_relationship.approved or ach_relationship.rejected webhook events to be notified when verification completes.

List ACH relationships

Returns all ACH relationships associated with a Buildmarkets account, across all statuses. Use the status field in each object to determine which relationships are available for transfers.

GET /v1/accounts/{accountId}/ach-relationships

Path parameters

ParameterTypeRequiredDescription
accountIdstring (UUID)The Buildmarkets account ID

Example request

curl https://api.tappengine.com/v1/accounts/b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f/ach-relationships \
  -H "Authorization: Bearer $BUILDMARKETS_API_KEY"

Example response

[
  {
    "id": "e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b",
    "account_id": "b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f",
    "status": "APPROVED",
    "bank_account_type": "CHECKING",
    "bank_account_number": "****9012",
    "bank_routing_number": "021000021",
    "bank_account_owner_name": "Jane Smith",
    "bank_name": "Chase",
    "created_at": "2026-03-15T10:30:00Z",
    "updated_at": "2026-03-15T10:30:01Z"
  },
  {
    "id": "a1b2c3d4-e5f6-7a8b-9c0d-e1f2a3b4c5d6",
    "account_id": "b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f",
    "status": "CANCELLED",
    "bank_account_type": "SAVINGS",
    "bank_account_number": "****7788",
    "bank_routing_number": "026009593",
    "bank_account_owner_name": "Jane Smith",
    "bank_name": "Bank of America",
    "created_at": "2026-01-10T08:00:00Z",
    "updated_at": "2026-02-20T14:22:00Z"
  }
]

Remove an ACH relationship

Permanently removes an ACH relationship. The status transitions to CANCELLED and the relationship can no longer be used for deposits or withdrawals. This action is irreversible — if the user needs to link the same bank account again, a new ACH relationship must be created.
Important: You cannot remove an ACH relationship that has a pending transfer in progress. Confirm all in-flight transfers have settled before removing a relationship.

DELETE /v1/accounts/{accountId}/ach-relationships/{achId}

Path parameters

ParameterTypeRequiredDescription
accountIdstring (UUID)The Buildmarkets account ID
achIdstring (UUID)The ACH relationship ID to remove
Returns 204 No Content on success. No body is returned.

Example request

curl -X DELETE \
  https://api.tappengine.com/v1/accounts/b3d9f1a2-4c7e-4f0b-9e2d-1a2b3c4d5e6f/ach-relationships/e7f2a1b3-9c4d-4e0f-8a1b-2c3d4e5f6a7b \
  -H "Authorization: Bearer $BUILDMARKETS_API_KEY"

HTTP/1.1 204 No Content

Common errors

HTTP StatusErrorCause
400INVALID_ROUTING_NUMBERRouting number is not exactly 9 digits or is not a valid ABA number
400INVALID_ACCOUNT_NUMBERAccount number is outside the 4–17 character range
404ACCOUNT_NOT_FOUNDThe accountId does not exist or is not accessible with your API key
404ACH_RELATIONSHIP_NOT_FOUNDThe achId does not exist for this account
409DUPLICATE_ACH_RELATIONSHIPAn active relationship already exists for this routing + account number combination
422ACCOUNT_NOT_ACTIVEThe Buildmarkets account is not in ACTIVE status

Webhook events

Buildmarkets fires webhook events when an ACH relationship changes status. Subscribe to these to drive real-time UI updates.
EventFired when
ach_relationship.approvedVerification succeeded; relationship is now APPROVED
ach_relationship.rejectedVerification failed; relationship is now REJECTED
ach_relationship.cancelledA DELETE was processed; relationship is now CANCELLED
See Webhook Events Reference for full payload schemas.

Next steps