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.
What are AI-ready integrations on Truto?
Shipping AI features shouldn't mean rewriting connectors, redeploying models, or juggling new security reviews every time. That's the hidden tax most teams are paying today.
With Truto's AI-ready integrations, every API you connect can instantly become an action your AI agent understands.
Here's how it works, in plain terms:
-
You add a short description and schema to an integration method in Truto.
-
That method shows up as a ready-to-use tool your AI agent (or MCP server) can call.
-
Truto handles authentication, pagination, and errors so your tools look and feel consistent.
-
Every tool is scoped to the exact account and permissions you choose, with full observability.
-
With RapidBridge syncs, your agent always has access to the latest data, perfect for RAG or reducing hallucinations.
The result: you can add or refine AI-driven actions in hours, not weeks.
Our customers are already using AI-ready integrations to power copilots across CRM, help desk, HR, finance, and more.
If you want to try it with your stack, start with the Agent Toolsets intro and the Tools Overview.
Some of the AI-Ready integrations we already support
Apart from the apps listed above, we support over 85 AI-ready integrations that you can add without refactoring your agents or rewriting connectors.
Deep dive: Connecting an AI agent to Brex expense data
If your team is building AI-powered finance workflows - expense categorization, receipt matching, spend analysis, compliance checks - and your customers use Brex, this section walks through exactly how to wire it up with Truto.
Why Brex + AI agents?
Brex is a spend management platform covering corporate cards, expense management, reimbursements, and bill pay. Its Expenses API lets you read, update, and match receipts against card expenses programmatically.
The problem: connecting an AI agent to Brex directly means handling OAuth2 token refresh (Brex tokens expire after one hour), cursor-based pagination, rate limits (1,000 requests per 60 seconds), and mapping Brex's response format into something your LLM can reason about. Multiply that by every other financial tool your customers use - QuickBooks, Xero, NetSuite - and you're maintaining a pile of bespoke connectors.
Truto eliminates that. You connect Brex once through Truto, and your agent gets tool definitions, authentication, pagination, and error handling out of the box.
Architecture overview
sequenceDiagram
participant Agent as AI Agent<br>(LangChain / Claude / Cursor)
participant Truto as Truto Platform
participant Brex as Brex Expenses API
Agent->>Truto: Call list_expenses tool
Truto->>Truto: Validate auth, refresh<br>token if needed
Truto->>Brex: GET /v1/expenses<br>(Bearer token)
Brex-->>Truto: Raw expense response
Truto->>Truto: Normalize response
Truto-->>Agent: Unified expense dataYour agent never talks to Brex directly. Truto sits in the middle, handling credentials, retries, and response normalization.
Prerequisites and OAuth scopes
Before your agent can access Brex data through Truto, you need:
- A Truto account with API access and your
TRUTO_API_TOKEN. - Brex admin access to authorize the OAuth connection.
- The right OAuth scopes configured in Truto for the Brex integration:
| Scope | Access Level | Use Case |
|---|---|---|
expenses.card.readonly |
Read | List and retrieve card expenses |
expenses.card |
Read + Write | Update expenses, upload receipts |
openid, offline_access |
Auth | Required for OAuth token refresh and webhook registration |
Request the minimum scopes your agent needs. If your agent only reads expense data, stick with expenses.card.readonly. You can always add write scopes later by re-authorizing.
Connecting a Brex account via Truto's Link UI
Truto provides a drop-in Link UI that handles the full OAuth flow with Brex. Here's the process:
- Create a Link Token via the Truto Admin API for the Brex integration.
- Open the Link UI in your app using the token. Your customer sees a Brex authorization screen.
- Customer authorizes access. Brex redirects back to Truto with an authorization code.
- Truto exchanges the code for tokens, encrypts them at rest, and creates an integrated account.
- You receive an
integrated_account_id- this is your handle for all subsequent tool and API calls.
Truto proactively refreshes Brex OAuth tokens before they expire. Since Brex access tokens last about one hour, Truto schedules a refresh 60 to 180 seconds before expiry. If a refresh fails, the account is marked as needs_reauth and Truto fires an integrated_account:authentication_error webhook so your app can prompt the user to reconnect.
For a detailed walkthrough, see our guide on connecting accounts.
Mapping: Brex expense endpoints to Truto
Truto gives you two ways to access Brex data:
- Proxy API: A direct pass-through to Brex's endpoints with Truto handling auth and pagination. Use this when you need the full Brex response shape.
- Unified API: A normalized accounting schema that works identically across Brex, QuickBooks, Xero, and other providers. Use this when your agent needs to work across multiple expense platforms.
| Brex Endpoint | Truto Proxy Resource | Truto Unified Resource | Method |
|---|---|---|---|
GET /v1/expenses |
expenses |
accounting/expenses |
list |
GET /v1/expenses/{id} |
expenses |
accounting/expenses |
get |
PUT /v1/expenses/card/{expense_id} |
card-expenses |
accounting/expenses |
update |
POST /v1/expenses/card/receipt_match |
receipt-match |
- | create |
POST /v1/expenses/card/{expense_id}/receipt_upload |
receipt-upload |
accounting/attachments |
create |
When you use the Unified API, Truto maps Brex expense fields - amount, merchant, category, memo, status - into a common schema shared with every other accounting provider. Your agent code stays the same regardless of whether the customer uses Brex or QuickBooks.
Tool schemas for function-calling
When you call Truto's /tools endpoint for a Brex integrated account, you get back tool definitions in standard function-calling format. Here's what the response looks like for expense-related tools:
[
{
"name": "list_expenses",
"description": "List all Brex expenses. Returns card expenses with amount, merchant, category, and status.",
"parameters": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"description": "Number of results per page (default 100, max 1000)"
},
"cursor": {
"type": "string",
"description": "Pagination cursor from a previous response"
}
}
}
},
{
"name": "get_expense",
"description": "Retrieve a single Brex expense by ID. Returns full details including receipts and category.",
"parameters": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The expense ID"
}
},
"required": ["id"]
}
},
{
"name": "update_card_expense",
"description": "Update a Brex card expense. Can set memo and category.",
"parameters": {
"type": "object",
"properties": {
"expense_id": {
"type": "string",
"description": "The card expense ID to update"
},
"memo": {
"type": "string",
"description": "Updated memo for the expense"
},
"category": {
"type": "string",
"description": "Updated expense category"
}
},
"required": ["expense_id"]
}
}
]These definitions are fully customizable. You can edit descriptions, add or remove parameters, and control which tools are exposed - all from the Truto integration UI. Changes take effect immediately; no redeployment required.
Example code
LangChain (JavaScript)
Install the Truto LangChain toolset:
npm install @truto/langchain-toolset @langchain/openaiThen wire up your agent:
import { getTools } from '@truto/langchain-toolset';
import { ChatOpenAI } from '@langchain/openai';
import { HumanMessage } from '@langchain/core/messages';
const BREX_ACCOUNT_ID = process.env.BREX_INTEGRATED_ACCOUNT_ID;
async function main() {
// Load Brex expense tools from Truto
const tools = await getTools(BREX_ACCOUNT_ID, {
truto: {
token: process.env.TRUTO_API_TOKEN,
},
// Only expose read tools to this agent
methods: ['list', 'get'],
});
const llm = new ChatOpenAI({ model: 'gpt-4o' });
const llmWithTools = llm.bindTools(Object.values(tools));
const response = await llmWithTools.invoke([
new HumanMessage('Show me all Brex expenses over $500 from last week'),
]);
console.log(response.content);
}
main();The getTools function calls Truto's /tools endpoint behind the scenes and returns LangChain-compatible tool instances. Each tool call is routed through Truto to Brex with full auth handling.
Calling the /tools endpoint directly
If you're using a different framework or building your own tool layer, hit the endpoint directly:
curl -H "Authorization: Bearer $TRUTO_API_TOKEN" \
"https://api.truto.one/integrated-account/$BREX_ACCOUNT_ID/tools?methods[0]=list&methods[1]=get"The response is a JSON array of tool definitions you can pass to any LLM that supports function-calling - OpenAI, Anthropic, Gemini, or open-source models.
Cursor and Claude (MCP)
Truto auto-generates MCP servers for every integrated account. To use Brex tools in Cursor, add this to your .cursor/mcp.json:
{
"mcpServers": {
"truto-brex": {
"command": "npx",
"args": [
"@truto/mcp-server",
"--token", "<your-truto-api-token>",
"--integrated-account-id", "<your-brex-integrated-account-id>"
]
}
}
}For Claude Desktop, add the same configuration to your claude_desktop_config.json. Once configured, Brex expense tools appear automatically in your tool palette - no code required.
Pagination, rate limits, and retries
Pagination: Brex uses cursor-based pagination with a default page size of 100 and a maximum of 1,000. Truto normalizes this into its own cursor-based pagination format. Your agent receives next_cursor in every list response and passes it back to fetch the next page. You don't need to manage Brex's cursor format directly.
Rate limits: Brex allows up to 1,000 requests per 60 seconds per client and account. When Truto detects a 429 response from Brex, it retries with exponential backoff. If the limit is still exceeded after retries, your agent receives a clean 429 response with a Retry-After header.
Retries: Truto automatically retries on transient errors (5xx responses, network timeouts). For non-retryable errors like 401 or 403, Truto surfaces the error immediately so your agent can handle it.
Webhooks and real-time patterns with RapidBridge
There are two ways to get real-time Brex expense data into your agent:
Brex webhooks via Truto: Brex supports webhook events like EXPENSE_PAYMENT_UPDATED, which fires when a card charge occurs or an expense is modified. Truto ingests these webhooks, verifies signatures, and normalizes the payload into a unified record:updated event delivered to your webhook endpoint. This requires the expenses.card.readonly scope and CARD_ADMIN role on the Brex account.
RapidBridge syncs: If you need your agent to query pre-synced expense data (for example, to power RAG or vector search), RapidBridge keeps a synchronized copy of Brex expenses available for low-latency reads. This is useful for agents that need to search across thousands of historical expenses without paginating through the live API on every query.
Security, compliance, and data retention
Truto does not store your customers' Brex data on its platform. All API calls are proxied in real-time - expense data flows from Brex through Truto to your agent and is never persisted.
OAuth tokens (access and refresh) are encrypted at rest using AES-GCM. Truto is SOC 2 Type II and ISO 27001 compliant, GDPR and HIPAA certified, and adheres to CCPA regulations.
Every tool call is scoped to a specific integrated account with the exact permissions the customer authorized. Your agent can only access what was explicitly granted during the OAuth flow. You control which tools (read, write, custom) are exposed to each agent through Truto's method filtering.
Troubleshooting
401 Unauthorized: Truto auto-refreshes Brex tokens, but if the refresh token is revoked (e.g., the user removed API access in Brex), the account enters a needs_reauth state. Check the integrated account status in Truto's dashboard and prompt the user to reconnect.
403 Forbidden: The OAuth scopes don't cover the endpoint your agent is calling. For example, calling update_card_expense with only the expenses.card.readonly scope will fail. Re-authorize with the correct scopes.
429 Too Many Requests: Brex enforces 1,000 requests per 60 seconds. Truto handles retries automatically, but if your agent is making an unusually high volume of calls in a tight loop, consider adding a delay or batching requests.
Empty responses: If list endpoints return no data, verify the Brex account has actual expenses for the queried time range. Also confirm the integrated account status is active in Truto.
Receipt upload failures: The receipt_upload endpoint requires a multipart form upload. Make sure you're passing the file content correctly through Truto's Proxy API.
All new integrations built by Truto will be Agent First and support tool calling. We are rapidly expanding coverage for existing integrations too, and our goal is to have 100% tool calling coverage by the end of this year.
Follow our changelog to discover the latest AI-ready integrations we're building at Truto
If you're exploring AI agents or MCP in your organization, Truto gives you the building blocks to do it safely and at scale.
FAQ
- What OAuth scopes do I need to connect an AI agent to Brex expenses?
- For read-only access, request expenses.card.readonly. For write access (updating expenses, uploading receipts), add expenses.card. Webhook registration requires openid and offline_access scopes.
- Does Truto store my Brex expense data?
- No. Truto does not store customer data on its platform. All API calls are proxied in real-time to Brex. OAuth tokens are encrypted at rest using AES-GCM.
- How does Truto handle Brex API rate limits?
- Brex allows up to 1,000 requests per 60 seconds per client. Truto automatically retries on 429 responses with exponential backoff. If limits are still exceeded, your agent receives a clean 429 with a Retry-After header.
- Can I use Truto's Brex integration with LangChain, Cursor, or Claude?
- Yes. Truto provides a LangChain JS SDK (@truto/langchain-toolset), auto-generated MCP servers for Cursor and Claude, and a /tools REST endpoint compatible with any LLM framework that supports function-calling.
- What happens if the Brex OAuth token expires?
- Truto proactively refreshes Brex OAuth tokens 60-180 seconds before they expire. If a refresh fails, the account is marked as needs_reauth and Truto fires a webhook so your app can prompt the user to reconnect.