Skip to content

How to Connect AI Agents to Brex Expense Data via API

Learn how to architect a secure, scalable integration between AI agents and the Brex API using the Model Context Protocol (MCP) and unified mapping layers.

Uday Gajavalli Uday Gajavalli · · 11 min read
How to Connect AI Agents to Brex Expense Data via API

Giving an AI agent read and write access to Brex expense data requires far more than wrapping a few REST endpoints in a Python script. Connecting a Large Language Model (LLM) to corporate financial systems means solving multiple distributed systems problems at once: handling OAuth token lifecycles in highly concurrent environments, managing cursor pagination, respecting aggressive rate limits, and translating unstructured text into deterministic, schema-validated API calls.

You can build that plumbing yourself against the raw Brex API, or you can wire Brex to a unified API layer that exposes the same endpoints as agent-ready tools. Engineering teams are increasingly moving away from building brittle, point-to-point API connectors and standardizing on the Model Context Protocol (MCP) and unified mapping layers.

This guide breaks down both paths, the real-world constraints of the Brex API, and the exact architectural patterns that hold up in production. This is written for product managers and engineering leads shipping AI copilots, procurement bots, or autonomous finance agents on top of corporate spend data—not for hobbyists spinning up a weekend MCP demo.

The Rise of AI in Corporate Spend Management

The transition from manual expense tracking to AI-driven financial orchestration is happening at the infrastructure level. As we noted when discussing how to automate expense management via MCP, the expense management market was estimated at USD 8.3 billion in 2025 and is expected to reach USD 9.1 billion in 2026, on track for USD 21.4 billion by 2035 at a 10% CAGR. The subset of this market specifically driven by AI is growing even faster, and Brex is at the center of that shift.

Brex has already proven what an LLM-native spend platform looks like. By building their own internal AI assistant using Claude models, Brex automated 75% of their expense workflows. This automated enforcement of expense policies improved their compliance rates from 70% to 94%, saving customers an estimated 169,000 hours monthly and $56.5 million annually through intelligent automation, conversational expense submission, and real-time policy guidance. Those numbers matter because they establish the baseline your own agent has to compete with. If your copilot cannot at least match Brex Assistant's automation rate, users will not switch tabs to use it.

This growth is driven by raw operational efficiency. Manual expense report processing costs companies approximately $58 and takes 20 minutes of human labor per report on average. By routing these workflows through automated pipelines, organizations reduce the cost to roughly $7 and compress the processing time to just two to three days.

For B2B SaaS applications, these numbers dictate the product roadmap. Your customers expect your platform to automatically ingest receipts, categorize spend, and reconcile ledgers without human intervention. To deliver this, your backend infrastructure must provide LLMs with direct, programmatic access to corporate cards and expense APIs.

Why Connect AI Agents to Brex Expense Data?

The friction between a transaction happening and it being categorized, reconciled, and posted to the general ledger is where finance teams lose weeks every quarter. When an agent has direct access to the Brex API, it can validate transactions against corporate policy at the moment of purchase, rather than waiting for an end-of-month manual audit.

Here are the core agentic patterns that actually deliver ROI:

  • Intelligent Expense Parsing: A Slackbot or email processor ingests a receipt image, uses a vision model to extract the total and vendor, queries the Brex API to find the matching transaction, categorizes it against your chart of accounts, and automatically attaches the receipt payload—all without a human touching the expense.
  • Automated Bank Reconciliation: An agent fetches raw Brex card and cash transactions, uses heuristic matching to cross-reference them against open invoices or bills in an accounting system (like QuickBooks, Xero, or NetSuite), and proposes reconciliation pairs with a confidence score. The finance team approves in bulk instead of matching line by line.
  • Natural Language Financial Reporting: A founder or CFO asks an agentic dashboard, "What did we spend on AWS across all departments last quarter?" The agent leverages the Brex API to fetch current balances, filter by merchant and date, and return a structured real-time cash flow summary without requiring a complex BI tool.
  • Policy-Aware Spend Guardrails: Before a virtual card is issued or a spend limit is raised, the agent checks policy documents, historical vendor spend, and budget remaining. It approves, denies, or routes the request for human review instantly.

For a deeper walkthrough of the production quickstart pattern, see our guide on How to Connect an AI Agent to Brex Expense Data via MCP: A Production Quickstart.

Understanding the Brex API and MCP Server

To interact with Brex, developers historically relied entirely on the Brex REST API. This API exposes well-designed endpoints for managing Team, Expenses, Transactions, Budgets, and Payments. Every endpoint uses OAuth 2.0 bearer tokens, cursor pagination, and returns JSON with predictable schemas. However, translating an LLM's unstructured text output into the exact JSON schema required by the Brex REST API requires significant middleware.

To bridge this gap, Brex officially embraced the Model Context Protocol (MCP). Brex launched an official beta MCP server that connects Brex financial data to Claude Code, Cursor, and any MCP-compatible tool so users can check expenses, balances, and bills without switching tabs.

MCP acts as a standardized broker. Instead of writing custom prompt engineering to teach an LLM how to format a Brex API request, you provide the LLM with an MCP server. The server defines the available tools (e.g., get_transactions, create_vendor) and their exact JSON schemas. The LLM outputs a standard JSON-RPC tool call, which the MCP server executes against the Brex API.

The official Brex MCP server layers a conversational interface on top of this. The connector lets users see recent expenses filtered by date, amount, or merchant, identify items missing receipts, check payout ETAs for approved reimbursements, view available spend limits, and see cards and their status. It also allows users to modify memos, receipts, attendees, and spend limits for their own transactions.

However, there is a critical scope limitation: to create reimbursements, approve or reject expenses, or modify a team's transactions, users must go to the Brex dashboard or mobile app. If your product needs write access beyond the personal-transaction scope—such as approving expenses, issuing team cards, or creating budgets programmatically—the official MCP connector alone is not enough. You need direct API access, which means owning the OAuth, pagination, and rate-limit machinery yourself, or delegating it to a unified API layer.

Brex API Architecture at a Glance

flowchart LR
    Agent["AI Agent<br>(Claude, GPT, custom)"]
    Tool["Tool Layer<br>(MCP or function calls)"]
    Auth["OAuth 2.0<br>Token Manager"]
    Brex["Brex REST API<br>platform.brexapis.com"]
    GL["Accounting System<br>(QBO / Xero / NetSuite)"]

    Agent --> Tool
    Tool --> Auth
    Auth --> Brex
    Brex --> Tool
    Tool --> GL

Architectural Challenges: Rate Limits, Pagination, and OAuth

Building a production-grade integration between an AI agent and Brex requires solving several distributed systems problems. Point-to-point integrations frequently fail under the load of agentic workflows because LLMs generate API requests at unpredictable, highly concurrent rates. Understanding these constraints before you write code will save you a rewrite.

Strict Rate Limiting (HTTP 429)

Financial APIs enforce strict rate limits to protect their infrastructure, and Brex is unforgiving of naive clients. The Brex API 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 per Client ID and Brex account. Exceeding a rate limit results in an HTTP 429 (Too Many Requests) response.

One thousand requests per minute sounds generous until you realize a single reconciliation job across a mid-market customer with 40,000 transactions can burn through it in under an hour of parallel fetches. Furthermore, LLM agents are chatty—a single natural language query can fan out to 15-20 tool calls.

If your rate limiting is due to frequent polling, you should leverage webhooks to receive real-time notifications instead. If webhooks are not viable, you must watch for 429 status codes and implement a retry mechanism using an exponential backoff schedule with jitter to avoid the thundering herd problem. Another option is to throttle traffic per Client ID using a token bucket algorithm at your application layer.

Info

Why pass 429s to the caller? When connecting to APIs via Truto, it is important to understand the division of responsibility. Truto does not silently retry, throttle, or absorb rate-limit errors. Absorbing rate limits in the middleware layer creates hidden latency. If an integration platform silently retries a request for 30 seconds, the LLM waiting for the tool response will often time out, leading to hallucinations or broken conversational flows.

Passing the 429 directly allows the agent framework to decide whether to wait, inform the user, or try a different strategy. However, Truto normalizes the upstream rate limit information into standardized headers per the IETF specification (ratelimit-limit, ratelimit-remaining, ratelimit-reset). This ensures your retry logic works identically across every provider.

Cursor Pagination and Schema Normalization

Brex list endpoints use cursor-based pagination. To bulk fetch card transactions, you need to paginate through the results with the cursor parameter. The default page size is 100, and 1,000 is the maximum.

LLMs are terrible at pagination if you expose the raw cursor as a tool parameter—they will either bail early or loop forever. Your integration layer should paginate internally and surface a single "give me everything since timestamp X" tool to the agent.

def fetch_all_expenses(token: str, since: str):
    url = "https://platform.brexapis.com/v2/expenses/card"
    headers = {"Authorization": f"Bearer {token}"}
    cursor, results = None, []
 
    while True:
        params = {"limit": 500, "purchased_at_start": since}
        if cursor:
            params["cursor"] = cursor
 
        r = requests.get(url, headers=headers, params=params)
        if r.status_code == 429:
            # Do NOT silently swallow - propagate to caller
            # or apply your own backoff strategy here.
            raise RateLimitError(r.headers.get("ratelimit-reset"))
 
        r.raise_for_status()
        body = r.json()
        results.extend(body["items"])
        cursor = body.get("next_cursor")
        if not cursor:
            return results

Furthermore, the schema of a Brex transaction is heavily nested. Extracting the actual merchant name, the settled amount, and the category requires parsing multiple layers of JSON. If your application also integrates with other corporate card providers (like Ramp or Mercury), you will quickly find that every provider structures this data differently. This forces your engineering team to write custom schema mapping logic for every integration you support.

OAuth and Token Exhaustion in a Multi-Tenant World

If you are a B2B SaaS embedding Brex into your product, you are not managing one token—you are managing a token per customer. Brex uses OAuth 2.0 for authentication. Access tokens expire quickly, and refresh tokens must be rotated.

In an agentic workflow, an LLM might trigger a loop that makes dozens of API calls in a few seconds. If the access token expires during this loop, multiple concurrent threads will attempt to use the refresh token simultaneously. This race condition often invalidates the entire token chain, forcing the end-user to manually re-authenticate.

The production pattern that actually holds up:

  1. Persist refresh tokens encrypted at rest, keyed by tenant.
  2. Schedule proactive refreshes shortly before token expiry rather than reacting to 401s.
  3. Handle refresh-token rotation by writing the new refresh token back atomically.
  4. Circuit-break on repeated auth failures per tenant so one broken customer does not poison your sync queue.

For the full architectural pattern, see our Create a Step-by-Step Developer Guide: MCP + Brex Integration.

How Truto Simplifies Brex AI Integrations

To bypass these architectural hurdles, modern engineering teams utilize unified API platforms that are specifically designed for agentic workflows. Truto approaches this problem with a fundamentally different architecture: zero integration-specific code.

Every provider—Brex included—is described declaratively as a mapping from unified endpoints to provider-specific ones, plus a generic execution pipeline that handles auth, pagination, rate-limit header normalization, and error mapping. Adding a new Brex endpoint is a configuration change, not a deploy.

Here is how the architecture handles the heavy lifting for AI teams:

  1. AI-Ready by Default: Every endpoint you map is automatically exposed as a schema-validated tool your agent or MCP server can call. You write the description and JSON schema once; it works for Claude, GPT, Cursor, LangGraph, or any custom orchestrator. See AI-ready integrations for how the tooling layer works.
  2. Managed Authentication: Truto handles the OAuth flows, state parameters, and proactive refresh token rotation ahead of expiry. Your agent simply makes requests to the Truto proxy, and Truto injects the correct, unexpired Bearer tokens into the outbound Brex request without race conditions.
  3. Normalized Data Models: Instead of writing custom logic to parse Brex's specific transaction schema, your agent interacts with Truto's Unified Accounting API or Unified Expense model. The mapping layer translates the unified request into the provider-specific format on the fly. You get a list_expenses(since=..., limit=...) tool that just works—no cursor threading in prompts.
  4. Transparent Rate Limiting: As mentioned, Truto passes standardized IETF rate limit headers back to your application. When Brex is close to its 1,000/60s cap, your code sees it in the exact same header shape as when Salesforce or QuickBooks is close to theirs, making your retry logic portable.

Unlike legacy integration platforms that attempt to sync and store all third-party data in their own databases—which introduces severe caching lag and data staleness—Truto acts as a frictionless proxy. When your agent asks for a Brex transaction, the request goes directly to Brex in real-time. This ensures your LLM is always reasoning over the absolute latest financial data, which is mandatory for use cases like real-time card authorization or budget enforcement.

End-to-End Flow with Truto in the Middle

sequenceDiagram
    participant Agent as AI Agent
    participant Truto as Truto Unified API
    participant Brex as Brex API
    participant GL as Accounting System

    Agent->>Truto: list_expenses(since="2026-08-01")
    Truto->>Truto: Fetch refresh token, refresh if needed
    loop Paginate internally
        Truto->>Brex: GET /v2/expenses/card?cursor=...
        Brex-->>Truto: 200 + next_cursor
    end
    Truto-->>Agent: Normalized expense list
    Agent->>Truto: create_journal_entry(mapped_lines)
    Truto->>GL: POST /journal_entries
    GL-->>Truto: 201 Created
    Truto-->>Agent: Success + entry_id

Trade-offs, Honestly

Unified APIs are not a free lunch. If your product needs a Brex-specific field that is not in the unified expense model, you must use a passthrough proxy call instead. This is still authenticated and rate-limit-normalized, but you have to handle the raw Brex schema. Additionally, if you need sub-second latency on write paths, a direct API call will always beat a hop through any middle layer by a few tens of milliseconds. If you only ever integrate one provider forever, the abstraction may be more machinery than you need.

However, for teams shipping AI copilots across a portfolio of finance tools—Brex plus QuickBooks plus NetSuite plus Ramp—the math tips heavily the other way. You get one auth model, one pagination pattern, one rate-limit header contract, and one tool schema across the entire stack.

Strategic Next Steps

Connecting AI agents to financial data is no longer a research project; it is a baseline expectation for modern B2B SaaS applications. The market is moving rapidly toward automated, agentic spend management, and the engineering teams that succeed will be the ones who avoid building custom point-to-point integrations.

If you are still evaluating: start by mapping the exact Brex endpoints your agent needs to call, then decide whether the official Brex MCP connector's read-mostly scope is enough. If it is, ship it and move on. If your product needs write access, multi-tenant OAuth, or reconciliation into a general ledger, you need a real integration layer.

Whether you build in-house against the raw Brex API or delegate to a unified API platform, the constraints remain the same: 1,000 requests per minute, cursor pagination, HTTP 429s on breach, and OAuth tokens that rotate. Design around those four facts, and your agent will hold up under real customer load.

FAQ

How do I connect an AI agent to Brex expense data?
You can use Brex's official MCP connector for read-mostly access inside tools like Claude or Cursor, build a custom integration against the Brex REST API handling OAuth and rate limits yourself, or delegate the plumbing to a unified API layer that exposes Brex endpoints as schema-validated, AI-ready tools.
What are the Brex API rate limits and how should AI agents handle them?
Brex allows up to 1,000 requests in 60 seconds per Client ID and account, returning HTTP 429 when exceeded. You should implement exponential backoff with jitter in your agent's execution loop, reading standardized IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) rather than silently absorbing errors.
Does Brex support the Model Context Protocol (MCP)?
Yes, Brex launched an official beta MCP server exposing over 50 tools for expenses, cards, and banking. However, write operations are largely restricted to personal transactions; team-level approvals or programmatic card issuance require direct REST API access.
How do you handle Brex API pagination for LLMs?
Brex uses cursor-based pagination with a maximum of 1,000 results per page. Because LLMs struggle with cursor threading, your integration layer should paginate internally and expose a clean, cursor-free tool signature (e.g., fetch all since a timestamp) to the AI agent.
How do I manage Brex OAuth tokens for high-concurrency AI agents?
AI agents can fan out dozens of concurrent requests. To avoid race conditions that invalidate token chains, schedule proactive refreshes shortly before token expiry, persist refresh tokens encrypted at rest, and handle rotation atomically with strict locking mechanisms.

More from our Blog

AI-ready integrations now supported by truto
AI & Agents/Product Updates

AI-ready integrations now supported by truto

Learn how to connect AI agents to Brex expense data using Truto. Includes OAuth setup, tool schemas, LangChain code, MCP config for Cursor and Claude, and troubleshooting.

Nachi Raman Nachi Raman · · 12 min read