Skip to content

How to Integrate the Brex API with Your Accounting Stack: The 2026 Engineering Guide

A complete 2026 engineering guide to integrating the Brex API with accounting systems like QuickBooks, Xero, and NetSuite. Covers rate limits, ledger mapping, and unified architecture.

Uday Gajavalli Uday Gajavalli · · 11 min read
How to Integrate the Brex API with Your Accounting Stack: The 2026 Engineering Guide

If you are building a B2B SaaS product that touches corporate spend—whether that is expense management, AP automation, procurement, or financial reporting—your customers expect you to sync their Brex transactions directly into their general ledger. Over 75% of business payments are now made through digital methods rather than analog ones, according to the Association for Financial Professionals (AFP). Yet, Mastercard reports that 69% of companies still struggle to integrate their payment systems with their business software.

When a customer swipes a Brex card, that raw transaction is just the beginning. To be useful to a finance team, that swipe must be categorized, matched with a receipt, assigned to a specific department, and written into an accounting system like QuickBooks Online, Xero, or NetSuite as a reconciled expense or journal entry.

Building this data pipeline requires more than just calling a few REST endpoints. You are bridging a high-volume fintech API with rigid, double-entry accounting ledgers. This guide breaks down the architectural requirements, rate limit handling, and ledger mapping strategies necessary to reliably integrate the Brex API with any accounting platform, and explains why point-to-point integrations between spend platforms and ERPs inevitably collapse at scale.

The Architecture of a Brex-to-Accounting Integration

The core data flow between a corporate card provider and an accounting system follows a predictable pattern: ingest, normalize, map, and write. However, the bidirectional nature of this flow is where the engineering complexity lies.

flowchart LR
    A["Brex API<br>(Transactions, Expenses,<br>Team, Payments)"] --> B["Your Mapping Layer<br>(Field transforms,<br>GL account routing,<br>currency conversion)"]
    B --> C["Target ERP/Accounting<br>(QuickBooks, Xero,<br>NetSuite, Zoho Books)"]
    C -->|Chart of Accounts,<br>Tax Rates, Vendors| B

The left side of your architecture is read-heavy: you pull settled card transactions, expense reports with receipt metadata, user/department hierarchies, and payment transfers from Brex. The right side is write-heavy: you create journal entries, bills, expenses, or vendor credits in the target accounting system.

The middle layer—the mapping logic—is where 80% of the engineering pain lives. This is not a one-directional pipe. Brex's Accounting API goes beyond traditional bank-feed integrations by enabling two-way data flow between Brex and ERPs. Your application needs to listen for spend events, enrich those events, and read the chart of accounts, tax rates, and tracking categories from the accounting platform so that Brex transactions land in the correct GL accounts.

Here is how a standard webhook-driven write flow operates in practice:

sequenceDiagram
    participant Brex as Brex API
    participant SaaS as Your Application
    participant Ledger as Accounting API (QBO/NetSuite)
    
    Brex->>SaaS: Webhook: expense.created
    SaaS->>Brex: GET /v1/expenses/{id}<br>(Fetch full receipt & metadata)
    Brex-->>SaaS: JSON Expense Payload
    Note over SaaS: Normalize data<br>Map to Chart of Accounts
    SaaS->>Ledger: POST /unified/accounting/expenses<br>(Write to General Ledger)
    Ledger-->>SaaS: 201 Created (Expense ID)
    SaaS->>Brex: Update expense status (Optional)

For a deep dive into how destination systems operate, read our guide on What Are Accounting Integrations?.

Key Brex API Endpoints for Expense Management

Brex APIs use standard REST architecture, are defined using the OpenAPI specification, and use standard HTTP response codes and verbs. All APIs accept and return JSON and require HTTPS. To build a complete spend management or accounting sync feature, you will primarily interact with these API surfaces:

API What It Gives You Key Endpoints
Transactions API Settled card and cash transactions with amounts, merchants, and expense IDs GET /v2/transactions/card/primary, GET /v2/transactions/cash/{id}
Expenses API Expense metadata, receipt attachments, coding fields, approval status GET /v1/expenses/card, PUT /v1/expenses/card/{expense_id}
Team API Users, departments, locations, card provisioning GET /v2/users, POST /v2/cards
Payments API ACH, wire, and check transfers to vendors GET /v1/vendors, POST /v1/vendors
Accounting API Two-way ERP sync with real-time webhooks Expanded endpoints for GL mapping
Webhooks API Real-time event notifications for transactions and expenses POST /v1/webhooks

The Transactions API: Your Source of Truth

This is your source of truth for settled financial movements. The Transactions API provides the raw ledger of debits and credits on the Brex account. Because accounting systems require reconciled, settled data to close the books, this API is the foundation of your sync logic.

A critical detail the docs won't tell you upfront: Brex doesn't return pending transactions today. Transactions are not returned in real-time as they happen; they will only be returned in the API as transactions settle. This means your accounting sync will always run on a settlement delay. You cannot build a real-time dashboard off the Transactions API alone. The Webhooks API with the EXPENSE_PAYMENT_UPDATED event type helps close this gap, but settled transaction data remains the authoritative source.

The Expenses API: Adding Business Context

While transactions represent the movement of money, expenses represent the business context. The Expenses API provides the metadata: memos, category tags, linked receipts, and approval statuses. When you map corporate spend to a general ledger, you are usually merging data from the Transactions API (the amount and date) with the Expenses API (the receipt and category).

The Team API: Automating Issuance

Automating card issuance and spend limits is a core use case for corporate card APIs. You can dynamically create virtual cards with spend limits for new employees or vendors through the Team API, and change spend limits per card instantly. In an accounting context, you also use the Team API to map Brex users to specific Employees or Vendors in the target ERP.

Info

Capital One Acquisition Context: Capital One completed its acquisition of Brex in April 2026 in a combination of stock and cash transactions. The Brex API continues to operate at platform.brexapis.com as of this writing, but engineering teams should monitor the developer changelog for any infrastructure or endpoint migrations as the integration progresses.

Handling Brex API Rate Limits and Pagination

High-volume financial APIs protect their infrastructure aggressively. Like most public APIs, Brex uses rate limiting to prevent buggy clients or denial-of-service attacks from affecting availability for others.

Brex rate limits are strictly enforced per Client ID and per Brex account. Brex allows up to 1,000 requests in 60 seconds, up to 1,000 transfers in 24 hours, up to 100 international wires in 24 hours, and up to 5,000 cards created in 24 hours. Exceeding a rate limit will result in an HTTP 429 (Too Many Requests) response.

Brex suggests throttling traffic more broadly per Client ID rather than for individual requests. A token bucket algorithm implemented per Client ID helps mitigate the effect of rate limits on your application.

For pagination, Brex uses a cursor-based approach. All "list" API endpoints support pagination with two parameters: limit (number of items per call) and cursor (the starting point for the set of items). The default limit is 100. It can be set up to 1000, and values greater than 1000 return a 400 Bad Request error.

Here is a practical pagination loop in Python that handles these constraints:

import requests
import time
 
def fetch_all_transactions(token: str, limit: int = 500):
    url = "https://platform.brexapis.com/v2/transactions/card/primary"
    headers = {"Authorization": f"Bearer {token}"}
    cursor = None
    all_transactions = []
 
    while True:
        params = {"limit": limit}
        if cursor:
            params["cursor"] = cursor
 
        resp = requests.get(url, headers=headers, params=params)
 
        if resp.status_code == 429:
            # Brex returns 429 - implement your own backoff
            retry_after = int(resp.headers.get("Retry-After", 60))
            time.sleep(retry_after)
            continue
 
        resp.raise_for_status()
        data = resp.json()
        all_transactions.extend(data.get("items", []))
 
        cursor = data.get("next_cursor")
        if not cursor:
            break
 
    return all_transactions

Handling this across multiple third-party APIs quickly becomes a distributed systems nightmare because every provider returns rate limit information differently. If you route Brex API calls through Truto's Proxy API, the platform normalizes upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF draft spec.

Note: Truto does not retry, throttle, or absorb 429 errors on your behalf. When Brex returns an HTTP 429, Truto passes that error directly to the caller. Your application is responsible for implementing backoff logic. This transparency gives you an accurate signal without hiding upstream behavior. For architectural patterns, review our guide on Best Practices for Handling API Rate Limits.

Mapping Corporate Spend to the General Ledger

The most complex engineering challenge in this integration is not the HTTP request—it is the accounting logic. A Brex card transaction is a flat financial event: amount, merchant, date, card holder, maybe an expense category. A general ledger entry is a structured, double-entry record—similar to the complexities we covered in our Stripe accounting integration guide—that must debit and credit specific accounts, apply the correct tax treatment, reference the right vendor, and respect the target system's strict validation rules.

When you push an expense into an accounting system, your mapping layer must resolve several relational dependencies:

1. GL Account Resolution (The Chart of Accounts) Every Brex expense needs to map to a specific account in the customer's Chart of Accounts. A "Software Subscription" expense in Brex might map to account 6200 - Software & Subscriptions in one customer's QuickBooks instance and 7100 - IT Expenses in another. Your application needs to query the accounting system's Accounts endpoint, cache the active expense accounts, and provide a configurable mapping UI for the user.

2. Vendors and Contacts Accounting systems require a vendor for every expense. Brex merchant names rarely match vendor records in accounting systems exactly. If an employee buys a flight on Delta Airlines, "DELTA AIR" from the Brex card transaction needs to resolve to "Delta Airlines" in the accounting system's Contacts directory. If it exists, you link the ID. If it does not, you must create it dynamically before writing the expense. Fuzzy matching, alias tables, or manual mapping UIs are table-stakes features here.

3. Multi-Currency Transactions Brex supports spend in multiple currencies. If your customer's accounting platform uses a base currency of GBP but a transaction posts in EUR, your integration must handle the conversion. You must extract the FX rate from Brex (typically the settlement rate), apply it to the ledger, and potentially create exchange gain/loss entries.

4. Tax Rate Application Different jurisdictions require different tax treatments. A Brex transaction in the UK might need VAT applied; the same merchant type in a US state might be tax-exempt. Your mapping layer must pull the customer's configured TaxRates from the accounting system and apply the correct one based on transaction metadata to ensure compliance.

5. Tracking Categories and Custom Segments Enterprise customers using Xero's tracking categories, QuickBooks classes, or NetSuite's custom segments expect card spend to flow into the correct dimensional buckets. A Brex transaction might need to be tagged to "Department: Engineering" and "Location: New York". Your integration must dynamically fetch these categories and append them to the payload.

Warning

NetSuite OneWorld Edge Case: If your customers use NetSuite OneWorld with multi-subsidiary and multi-currency enabled, your integration must dynamically detect these features and adjust query construction accordingly—including or excluding JOINs for currency and subsidiary tables based on the customer's NetSuite edition. Failure to handle these dependencies results in rejected API calls, out-of-balance ledgers, and extremely unhappy finance teams.

Why Point-to-Point Integrations Fail at Scale

Building a direct, point-to-point integration between Brex and QuickBooks Online is a manageable project for a senior engineer. One team, one sprint, one mapping layer. The architecture breaks down when your sales team signs a mid-market customer using Xero, and an enterprise customer running NetSuite, Sage Intacct, or Zoho Books.

If you support 3 spend platforms and 5 accounting systems, you are maintaining 15 integration paths. Every accounting platform has a completely different API philosophy:

  • QuickBooks Online uses a quirky REST-ish API with strict SQL-like querying and aggressive pagination limits that throttle at the company level.
  • Xero requires complex OAuth2 scopes, uses a sliding window rate limit per app, and handles multi-currency entirely differently than QBO.
  • NetSuite requires orchestrating across SuiteTalk REST, SuiteScript, and legacy SOAP endpoints just to fetch basic tax rates and custom fields.

If you build point-to-point, your codebase will soon be littered with integration-specific conditional logic. You will maintain separate database tables for QuickBooks tokens, NetSuite credentials, and Xero tenant IDs.

The real cost is not the initial build; it is the maintenance. Every time Brex or an ERP ships a new API version, deprecates an endpoint, or changes a field name, your engineering team must drop feature work to update the integration. This technical debt scales linearly, eventually consuming a massive percentage of your engineering capacity.

Using Truto to Sync Brex with Any Accounting Platform

To solve the integration scaling problem, engineering teams use unified APIs to abstract away provider-specific differences. Instead of writing code for QuickBooks, Xero, and NetSuite individually, you integrate once against a single standardized schema.

Truto provides a zero-code architecture that makes this process highly reliable. The platform handles 100+ third-party integrations without a single line of integration-specific code in its runtime logic. Integration behavior is defined entirely as declarative JSON configuration, and data mapping is handled via JSONata expressions.

Here is what this looks like in practice for a Brex-to-accounting sync:

Reading from Brex via the Proxy API Truto's Proxy API gives you direct, unmapped access to any Brex endpoint. You send a request to /proxy/transactions/card/primary, and Truto handles credential injection, token refresh, and rate limit header normalization—then returns the raw Brex response. This is useful for accessing highly specific, proprietary endpoints like a niche virtual card issuance feature that doesn't fit a generic schema.

Writing to Accounting via the Unified Accounting API On the other side, Truto's Unified Accounting API normalizes the chaotic schemas of QBO, Xero, and NetSuite. You push a standardized Expense or JournalEntry JSON payload to Truto, and the platform translates it into the provider-specific format, handling the complex nested arrays and custom field mappings automatically.

sequenceDiagram
    participant App as Your App
    participant Proxy as Truto Proxy API
    participant Brex as Brex API
    participant Unified as Truto Unified<br>Accounting API
    participant ERP as QuickBooks / Xero /<br>NetSuite

    App->>Proxy: GET /proxy/transactions/card/primary
    Proxy->>Brex: GET /v2/transactions/card/primary
    Brex-->>Proxy: Raw transaction data
    Proxy-->>App: Brex response + normalized rate limit headers
    App->>App: Transform & map to unified schema
    App->>Unified: POST /unified/accounting/expenses
    Unified->>ERP: Provider-specific API call
    ERP-->>Unified: Response
    Unified-->>App: Unified response

When building with Truto, you leverage several architectural advantages:

  • Pass-Through Architecture (Zero Data Retention): Financial data is highly sensitive. Truto operates as a pure pass-through proxy. It does not store your customers' sensitive financial or transaction data. The platform processes the payload in memory, executes the JSONata transformations, and immediately forwards the request to the destination. This is critical for SOC 2 and enterprise security reviews.
  • Automated Token Management: OAuth token lifecycle management is notoriously difficult in distributed systems. Truto schedules work ahead of token expiry, proactively refreshing credentials so your API calls never fail due to a stale bearer token.
  • Per-Customer Overrides: If a specific customer's NetSuite instance uses non-standard custom fields for expense categorization, Truto supports per-account configuration overrides without forking the base integration.
Tip

Idempotency is mandatory. When reading from Brex and writing to an accounting system, network timeouts will happen. Always use idempotency keys when creating records in the accounting system via Truto to ensure a retried Brex webhook does not result in duplicate expenses.

Where This Is Heading

The Brex-to-accounting integration pattern is a microcosm of a much larger trend. Brex recently announced a new AI-native Accounting API designed to automate accounting workflows end-to-end and enable deeper, real-time integrations with ERP systems. The Capital One acquisition will likely accelerate the expansion of Brex's API surface and the volume of transaction data flowing through it.

For engineering teams building spend management or fintech products, the decision is not whether to integrate Brex with accounting systems—your customers will demand it. The decision is whether you build and maintain the N×M matrix of point-to-point integrations yourself, or you invest that engineering time in your core product and let the plumbing run through an API layer designed for exactly this problem.

If you are evaluating your options, start with the hardest case. Try writing a multi-currency Brex expense to a NetSuite subsidiary with custom segments. If your integration approach handles that cleanly, everything else will be straightforward.

FAQ

How do I handle Brex API rate limits?
Brex enforces rate limits (e.g., 1,000 requests per 60 seconds) using HTTP 429 status codes. You must implement exponential backoff and cursor-based pagination in your application, utilizing standard IETF rate limit headers to determine when to retry the request.
Does the Brex API return real-time transaction data?
No. Brex only returns settled transactions through the Transactions API. Pending transactions are not available. Use the Webhooks API with EXPENSE_PAYMENT_UPDATED events for near-real-time notifications.
What is the best way to map Brex transactions to an accounting ledger?
You must dynamically fetch the destination system's Chart of Accounts, Vendors, Tax Rates, and Tracking Categories. This allows you to build a mapping interface so users can link their Brex spend to the correct double-entry accounting segments.
Does Truto store my customers' financial transaction data?
No. Truto uses a zero-data-retention, pass-through architecture. It processes API payloads in memory to execute mappings and immediately forwards them without storing your customers' sensitive data.
What happened to Brex after the Capital One acquisition?
Capital One completed its acquisition of Brex in April 2026. The Brex API continues to operate normally, but engineering teams should monitor the developer changelog for any future infrastructure changes.

More from our Blog