MCP App Store
by KeenEthics

Overview

Connect Brex to Claude for automating your company's finances. Finance monitors compliance and runs powerful queries. Employees get personalized memo guidance, policy answers, and status updates. Permission-based access ensures admin oversight while streamlining management.

Tools

assign_limit_for_card_expenses

ChatGPT
Assign one or more card expenses to a spend limit. TERMINOLOGY: On Brex, these are called "limits" — NOT "budgets." There are two kinds: card limits (built into a card) and spend limits (exist independently). "Budget" is a separate Premium-only planning/tracking feature. When users say "budget" they almost always mean "limit." Prefer "limit" in responses unless the user is specifically asking about the Budget feature. The API returns fields named "budget_*" but these should be presented as "limits" to users. Parameters: - expense_ids: Array of card expense IDs to assign the limit to - limit_id: The spend limit ID to assign to all expenses Example (single card expense): { "expense_ids": ["card_exp_123"], "limit_id": "limit_123" } Example (multiple card expenses with same limit): { "expense_ids": ["card_exp_123", "card_exp_456", "card_exp_789"], "limit_id": "limit_abc" }

assign_limit_to_card

ChatGPT
Assign a spend limit or user limit to a card. The system will automatically determine whether the provided limit ID corresponds to a spend limit or user limit. Example 1: Assigning a spend limit to a card: { "card_id": "card_123", "limit_id": "limit_123" } Example 2: Assigning a user limit to a card: { "card_id": "card_123", "limit_id": "limit_123" } — Confirmation gate (REQUIRED, do this before EVERY call) — 0. This REPLACES the card's limit source rather than adding a second one, and the tool cannot read back what funded the card before. Never describe the change as additive, and never state a "from <current>" you cannot see. 1. Resolve both objects by name first — list_cards for the card, list_spend_limits or list_my_limits for the limit — and present them by display name. Suggested format: You're moving <card display name> (last 4: <last4>) onto the <limit display name> limit Spend on the card will draw from that limit from now on, replacing whatever funds it today. 2. Ask a yes/no question whose ONLY purpose is consent. Wait for the answer. 3. Treat answers to clarifying questions (which card, which limit) as INPUTS, not consent. The yes/no is a separate, dedicated turn. 4. Only after an explicit yes do you emit the assign_limit_to_card tool call. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. GLOBAL USER-FACING RULES — apply to EVERY message you send the operator. Everything in this description is internal contract. It is here so you can reason and build a correct call; none of it belongs in a reply. - Never show wire values. Statuses, reasons, card categories, card forms, reset frequencies and limit flexibilities are internal codes: say "locked", "cancelled", "a virtual card", "monthly", "up to 10% over the limit". - Never show request or response FIELD NAMES, and never use field: value form. Describe what the operator will observe, in prose. - Never show internal IDs (card, user, policy, limit). Name objects by display name only, e.g. "Tony Report", "Default Policy". - Never name tools or internal steps: no "list_cards", "duplicate check", "preflight", "tool call". - Never volunteer how Brex records a card action internally. The spend limits, budgets and other bookkeeping behind locking, cancelling, transferring or issuing a card are implementation, not product: describe only what the operator will observe. Spend limits ARE a product the operator can be offered in their own right — the rule is about not explaining a card action in terms of them. - Any examples below use wire vocabulary deliberately, because they show the shape of a call. Copy their structure, never their vocabulary.

brex-analytics

ChatGPT
Query Brex financial and operational data using natural language, including expenses, business accounts, cash flow and yield, company credit limits, rewards, customer invoices and collections, travel and events, bills and purchase orders, accounting, budgets, and custom fields. ADMIN ONLY: This tool is accessible to account administrators and card administrators. Supported Analytics Capabilities Expense Spending and Cash Timing - Total and average spending, rankings, and comparisons by time period, department, cost center, merchant, vendor, category, employee, or legal entity - Daily, weekly, monthly, quarterly, and yearly spending patterns across card expenses, reimbursements, bill payments, and repayments - Purchase-date and cash-movement reporting, including when expenses were purchased, approved, posted, or paid - Spending in the company's reporting currency, as well as billing, original, budget, and purchased currencies Business Accounts, Cash Flow, and Yield - Business account inventory, account types and statuses, APY, seven-day APY, and tiered-yield settings - Cash inflows and outflows by account and time period, transaction amounts, and settled balances - Transfer and payment statuses, initiating employees, counterparties, memos, and recorded return or cancellation reasons - Yield accrued by account, date, and tier, and dividend income received Company Credit Limits - Current company credit limit, highest historical limit, and limit changes over time - When credit limits took effect or were superseded, their currencies, and previous nonzero amounts Rewards - Points earned, redeemed, and net points activity by period, employee, and earning category - Earning rates, qualifying spend, incentive tiers, redemption channels, and dollar value per redeemed point - Rewards balance and gift-card brands, values, points used, order dates, and fulfillment statuses Customer Invoices and Collections - Invoices issued to customers, amounts billed, outstanding and overdue balances, and aging buckets - Collection rates, days to pay, invoice statuses, sent/paid/due dates, and recurring invoice activity - Invoiced products, quantities, line-item amounts, invoice creators, and customer-level comparisons Travel and Company Events - Travel spending by booking type, booking source, payment method, employee, department, and trip - Trip counts, durations, cancellations, and employee versus guest travelers - Flight routes, origin and destination cities/countries, cabin and service classes, segment counts, and travel durations - Company event dates, attendee counts, flight/hotel/car/rail requirements, and associated budgets or spend limits Bills and Purchase Orders - Bill payment methods, invoice-processing statuses and reasons, auto-approval settings, batch payments, and duplicate flags - Scheduled payment dates versus due dates, and exchange-rate differences between approval and payment - Purchase order numbers, statuses, sources, amounts, open balances, and utilization Reimbursements and Repayments - Reimbursement approval and payment status by employee, manager, department, and period - Submission, approval, payment-posting, and completion timelines, including elapsed time between stages - Employee repayments (clawbacks), refunds, and card dispute status and trends Compliance, Policy, and Risk - Missing receipts or memos, documentation coverage, itemization status, and approval/compliance rates - Policy violation reasons, review-action status, violation counts, and distinct affected expenses - Recorded expense risk tiers and reasons, government-official involvement, and review activity Budgets and Spend Limits - Budget and spend-limit configurations, targets, periods, statuses, visibility, and lifecycle changes - Spend attributed to budgets or spend limits, utilization, overruns, and comparisons across employees, departments, categories, and vendors - Permanent and temporary limit increases, amounts, reasons, expiration, and voiding - Budget ownership, membership, and employee-budget relat…

cancel_card

ChatGPT
Cancel a card permanently. Works for purchasing cards, employee cards, and spend-limit cards. This cannot be undone — a cancelled card cannot be reactivated; issue a new card instead. If any of these are true, this tool is NOT to be called. Recommend the alternative and stop. - Operator wants to temporarily pause spend (reversible) → use lock_card, not cancel_card. - Operator wants a new card number and a replacement card → use replace_card, not cancel_card. - Operator wants to change WHO holds the card while keeping its number → use transfer_card. - Operator wants to change the limit, name, policy, or controls → use update_purchasing_card / update_employee_card. - The card is already cancelled → calling this tool again is a harmless no-op; it will report that nothing changed rather than erroring. — Resolving the card — If the operator names it by vendor / display name / last4 ("cancel the Figma card"), call list_cards FIRST. Read the current holder from the user field — NEVER holder_name, which is the name embossed at issuance and is stale on any card that has been transferred. If more than one candidate matches, present them (display name, last4, cardholder) and ask which one; never guess. — Talking to the operator — A cancelled card reads as TERMINATED on the wire; to the operator it is "cancelled", never "terminated". Mention the card's state only when it adds something, and skip it entirely when it does not. When reporting a completed cancellation, carry the permanence over into your own words. "Cancelled" and "can no longer be used" both read as a reversible pause to an operator who also uses lock_card, so say that it cannot be undone and that a replacement means issuing a new card. Say it again in the final report even though the confirmation recap already said it: the report is what the operator keeps. The result's message states this; paraphrasing it away is the failure to avoid. — Reason — CARD_LOST and CARD_DAMAGED apply to physical cards only — using either on a non-physical card is rejected. NO_LONGER_NEEDED covers both physical and virtual cards and is the right default for "we don't need this anymore" / offboarding without a transfer. FRAUD marks later declines as fraud-related rather than simply "card cancelled" — only use it when the operator says the card was compromised. Everything else is OTHER (the default when omitted). — Confirmation gate (REQUIRED, do this before EVERY call) — 1. Present the card being cancelled and what cancellation means. Suggested format: You're cancelling: <display name> (last 4: <last4>), held by <cardholder> This cannot be undone: the card will stop working immediately, any pending physical shipment will be cancelled, and recurring subscriptions billed to it will start declining rather than being cancelled automatically. 2. Ask a yes/no question whose ONLY purpose is consent. Wait for the answer. 3. Treat answers to clarifying questions (which card) as INPUTS, not consent. The yes/no is a separate, dedicated turn. 4. Only after an explicit yes do you emit the cancel_card tool call. — Retry policy — Do NOT automatically retry on an uncertain failure — re-check with get_card_by_id instead. A repeat call after a successful cancellation is a no-op, not a double-cancel, so retrying a call whose outcome is unclear is safe, but blind automatic retries still are not the default here — confirm with the operator first. — Example scenario — Operator: "Chris left the company — cancel his Figma card." 1. Call list_cards, find the Figma card, confirm Chris currently holds it. 2. Recap: "Cancelling Figma (last 4: 2836), held by Chris Reporter. This cannot be undone: the card will stop working immediately and subscriptions billed to it will start declining. Proceed?" 3. On "yes," call cancel_card with the resolved card ID and reason "NO_LONGER_NEEDED". 4. Report the outcome in plain language, permanence included: "Cancelled the Figma card ending 2836. This can't be undone — if the team still needs Figma, issue a new card." Do NOT say "status is now TERMINATED." SPEND TERMINOLOGY: - Spend …

create_employee_card

ChatGPT
Issue up to 10 virtual employee cards and set each user's monthly employee-card limit in one call. — What this tool does — This tool creates an employee card for travel, entertainment, and other employee expenses. Before anything, when the operator asks for an employee card, BEFORE any clarifying question about configurations such as the limit: 1. Call list_cards once with card_category: ["EMPLOYEE_CARD"] and user_ids containing every distinct target cardholder ID. Each user can have at most one active employee card. 2. If an active employee card already exists for any user (status ACTIVE, WAITING_ACTIVATION, or LOCKED), surface it FIRST and recommend update_employee_card for that user. Exclude that user from the create batch unless the operator changes the request. The service also reports duplicates as per-card failures with EMPLOYEE_CARD_ALREADY_EXISTS. 3. Call list_employee_card_limits with limit: 100 (the maximum page size) to look up whether each target cardholder already has a spendable employee-card limit on file, following next_cursor for further pages until it comes back null so a match isn't missed on a later page. Use this as the primary source for the "existing non-zero limit → propose it as default" logic below — prefer it over inspecting a nested USER_LIMIT off a TERMINATED card from step 1. If list_employee_card_limits fails with a permission/access error (missing scope, permission, or feature flag) rather than a network/timeout error, treat this check as unavailable and fall back to the TERMINATED-card USER_LIMIT check from step 1 instead of blocking the flow. 4. Call list_spend_limits with status: ACTIVE and limit: 100, following next_cursor the same way, and scan every returned name for anything topically related to the operator's stated reason for the card — the same event, offsite, trip, or project (e.g. a "NYC Offsite" spend limit when the operator wants a card for someone attending the NYC offsite). If a clearly related spend limit exists, surface it FIRST and ask whether the operator wants to add the person to that existing spend limit via the Brex dashboard instead of creating a new employee card — a spend limit already represents shared/event-scoped spend that a per-user employee card can't. If list_spend_limits fails with a permission/access error rather than a network/timeout error, treat this check as unavailable and continue the employee-card flow normally — a caller authorized to create employee cards is not guaranteed the separate access either listing tool requires, and that must never block card creation. 5. For users with no active employee card, no relevant spend limit hand-off, and no other blocker, present the complete proposed batch for confirmation. This is an internal preflight — do not mention it unless an existing active employee card or a relevant spend limit was found. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. GLOBAL USER-FACING …

create_purchasing_card

ChatGPT
Issue up to 20 virtual purchasing cards (P-Cards) for operational spend in one call. — What this tool does — This tool creates one or more P-Cards, each with its own name, primary cardholder, expense policy, and recurring spending limit. Cards are issued as VIRTUAL during creation; physical cards can be ordered separately afterward. Before anything, the moment the operator asks for one or more P-Cards ("make cards for Zoom and Figma", "create a P-Card for LinkedIn"), BEFORE any clarifying question about cardholder / limit / policy / frequency: 1. Call list_cards ONCE with card_category: ["PURCHASING_CARD"] to scope the search to existing P-Cards (no search_query). Do NOT pass user_ids — duplicates can be held by any cardholder. 2. Scan the returned displayName / holderName against every proposed card for anything topically related — exact match, vendor synonyms ("LinkedIn" ≈ "Professional Networks", "Zoom" ≈ "Video Conferencing", "Figma" ≈ "Design Tools" / "SaaS Subscriptions"), or category overlap. 3. Call list_spend_limits with status: ACTIVE and limit: 100 (the maximum page size) to scope the search to existing spend limits, and follow next_cursor for further pages until it comes back null — an account can have more active spend limits than fit on one page, and stopping early risks missing the relevant one. Scan every returned name the same way as step 2 for anything topically related to the proposed card(s) — the same event, project, department, or vendor (e.g. a "NYC Offsite" spend limit when the operator asks for a card for someone attending the NYC offsite). If list_spend_limits fails with a permission/access error (missing scope, permission, or feature flag) rather than a network/timeout error, treat this check as unavailable and continue the P-Card flow normally — a caller authorized to create P-Cards is not guaranteed the separate access this listing tool requires, and that must never block card creation. 4. If likely duplicates exist (from either step 2 or step 3), surface all flagged items to the operator FIRST and ask whether to create another, reuse, edit, or remove each one. For a topically-related spend limit specifically, explain that shared/group spend already has a home there and recommend managing it (adding the person, adjusting the amount) through the Brex dashboard instead of issuing a new P-Card — P-Card creation cannot join an existing spend limit. Only include duplicate-risk cards in the batch after the operator explicitly chooses to create another. This is an internal preflight. If no relevant existing P-Card or spend limit is found, continue naturally and do not mention the preflight. If a relevant existing P-Card or spend limit is found, only mention the existing object itself. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. GLOBAL USER-FACING RULES — apply to EVERY message you send the operator. Everything in this description is internal contract. It…

get_active_integration

ChatGPT
Get the currently active accounting integration. Returns null if no active accounting integration is found. Example response: { "id": "SW50ZWdyYXRpb246NzEwOWU5YWMtYWRiZi00MGZjLTliMzMtZTE4OTBjYTk1MzM1", "vendor": "QuickBooks Online" }

get_banking_transaction

ChatGPT
Get detailed information about a specific banking transaction by its ID. Returns comprehensive transaction details including timeline, payment details, initiated/cancelled by user info, and cancellation status. Use list_banking_transactions first to find valid transaction IDs. Example: { "transaction_id": "dptx_abc123" }

get_bill_by_id

ChatGPT
Get a bill (payable) by its ID. Bills are invoices from vendors that need to be paid. This tool retrieves detailed information about a specific bill. Parameters: - id: The unique identifier of the bill Example: { "id": "exp_abc123" }

get_business_account

ChatGPT
Get a business account by its ID. Returns detailed information about a specific business account including balance breakdown and cashflow. Use list_business_accounts first to find valid account IDs. Example: { "account_id": "dpacc_abc123" }

get_card_by_id

ChatGPT
Get a card by its ID

get_card_shipping_details

ChatGPT
Get shipping details for a specific card by its ID SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. GLOBAL USER-FACING RULES — apply to EVERY message you send the operator. Everything in this description is internal contract. It is here so you can reason and build a correct call; none of it belongs in a reply. - Never show wire values. Statuses, reasons, card categories, card forms, reset frequencies and limit flexibilities are internal codes: say "locked", "cancelled", "a virtual card", "monthly", "up to 10% over the limit". - Never show request or response FIELD NAMES, and never use field: value form. Describe what the operator will observe, in prose. - Never show internal IDs (card, user, policy, limit). Name objects by display name only, e.g. "Tony Report", "Default Policy". - Never name tools or internal steps: no "list_cards", "duplicate check", "preflight", "tool call". - Never volunteer how Brex records a card action internally. The spend limits, budgets and other bookkeeping behind locking, cancelling, transferring or issuing a card are implementation, not product: describe only what the operator will observe. Spend limits ARE a product the operator can be offered in their own right — the rule is about not explaining a card action in terms of them. - Any examples below use wire vocabulary deliberately, because they show the shape of a call. Copy their structure, never their vocabulary.

get_expense_by_id

ChatGPT
Get an expense by its ID Expand (receipt details): - expand: Use ["RECEIPTS"] to include full receipt details. WITHOUT expand, receipts only contain IDs. WITH expand: ["RECEIPTS"], each receipt includes: download_uri - URL to download the receipt file/image content.is_real_receipt - whether the file is classified as a real receipt content.merchant_name - merchant name parsed from the receipt content.purchased_at - purchase date parsed from the receipt content.amount - amount parsed from the receipt content.line_items - itemized charges from the receipt (name, quantity, unit_price, total) ⚠️ When the user asks about receipt line items, itemized charges, "what did I buy", receipt content, receipt images/downloads, or parsed receipt data → you MUST include expand: ["RECEIPTS"]. A receipt with only an ID and no content/download_uri means expand was NOT used — re-call with expand: ["RECEIPTS"]. Additional Fields: - additional_fields: Array of optional fields to include in response. Supported values: "TRAVEL_METADATA" - Includes flight, car rental, lodging, and train travel data "LOCATION" - Includes expense location details (country, city, coordinates, etc.) IMPORTANT: Location and travel data are ALWAYS null unless you explicitly request them via additional_fields. A null location does NOT mean "no location exists" - it means you did not request it. If the user asks about where an expense occurred, you MUST call this tool again with additional_fields: ["LOCATION"]. Same for travel - use additional_fields: ["TRAVEL_METADATA"]. Example 1: Getting an expense with expanded receipts (includes line items, download URL, parsed content): { "id": "expense_123", "expand": ["RECEIPTS"] } Example 2: Getting an expense with travel metadata and location: { "id": "expense_123", "additional_fields": ["TRAVEL_METADATA", "LOCATION"] } Example 3: Getting an expense with everything: { "id": "expense_123", "expand": ["RECEIPTS"], "additional_fields": ["TRAVEL_METADATA", "LOCATION"] } Understanding Expense Lifecycle and Compliance Status: Expense Lifecycle: 1. New expense created (card transaction or reimbursement submitted) 2. Documentation phase: System checks if documentation is required (receipts, memo, attendees, etc.) 3. Spender submits documentation if needed 4. Review phase: System checks if approval/review is required based on company policy 5. Reviewer reviews and approves/rejects if necessary 6. Expense is finalized Each expense returns TWO sets of compliance-related fields: A. DOCUMENTATION COMPLIANCE (for spenders - receipts, memo, attendees): - documentationComplianceStatus: Status of documentation requirements that the spender must fulfill "NOT_REQUIRED" - Company policy does not require any documentation for this expense. Empty receipts/memo are acceptable. "COMPLETED" - All required documentation has been provided according to policy. "DUE" - Documentation is required by policy but not yet provided. Check missingDocumentations field for specifics. "OVERDUE" - Required documentation is past its submission deadline. Check missingDocumentations field for specifics. - missingDocumentations: Array of specific items required by policy but not yet provided. Possible values: ["MEMO", "RECEIPT", "ATTENDEES", "EXTENDED_FIELD"] Empty array [] - Either no documentation is required OR all required documentation is complete Non-empty array - Lists specific items that must be provided (e.g., ["MEMO", "RECEIPT"]) - documentationSubmissionDeadline: The UTC timestamp by which documentation must be submitted (only present if documentation is required) B. REVIEW COMPLIANCE (for reviewers - approval/rejection): - reviewComplianceStatus: Status of review/approval requirements that the reviewer must fulfill "NOT_REQUIRED" - Company policy does not require review/approval for this expense. "COMPLETED" - The expense has been reviewed and approved/rejected. "DUE" - Review is required by policy but not yet completed. "OVERDUE" - Required review is past its deadline. - reviewDeadline: The UTC timestamp by which the review must be completed (only present if review is required) KEY DISTINCTIONS: - DocumentationComplianceStatus="NOT_REQUIRED" and missingDocumentations=[] → Documentation not required by company policy - Empty receipts/memo with documentationComplianceStatus="DUE" or "OVERDUE" and missingDocumentations=["RECEIPT","MEMO"] → Documentation IS required by policy but missing - reviewComplianceStatus="DUE" or "OVERDUE" → Expense is waiting for someone to review/approve it - reviewComplianceStatus="NOT_REQUIRED" → No approval needed

get_expense_download_result

ChatGPT
Check the status of an expense download job and get the download URL when ready. Call this after start_expense_download to poll for completion. Download jobs typically take 10-300 seconds. Response statuses: - PROCESSING: Job is still running. Poll again after waiting - COMPLETED: Job finished successfully. The download_url field contains a URL to download the CSV file. - FAILED: Job failed. The error field contains the failure reason IMPORTANT: Recommended polling strategy: 1. Wait 5 seconds after calling start_expense_download 2. Poll every 10 seconds until status is COMPLETED or FAILED 3. Maximum expected duration: 5 minutes The CSV file includes 15 columns: Parent ID, Flagged Expenses, Transaction Date, Expense Type, Card Last 4, Amount, Currency, Original Amount, Original Currency, Merchant Name, User, Budget Name, Memo, Expense Status, Payment Status. If fetching download_url fails after status is COMPLETED: The signed URL is valid and reusable. The most common cause of a download failure is that the client environment blocks outbound requests to external hosts. If the client has a domain/URL allowlist (e.g., Claude Code Web's "Allowed domains" setting), the user must add api.brex.com to it before the fetch will succeed. After allowlisting, simply retry the fetch — there is no need to re-run start_expense_download. Parameters: - job_id (required): The job ID returned by start_expense_download

get_expense_policy

ChatGPT
Get expense policy information for a limit as structured, validatable content. TERMINOLOGY: On Brex, these are called "limits" — NOT "budgets." There are two kinds: card limits (built into a card) and spend limits (exist independently). "Budget" is a separate Premium-only planning/tracking feature. When users say "budget" they almost always mean "limit." Prefer "limit" in responses unless the user is specifically asking about the Budget feature. The API returns fields named "budget_" but these should be presented as "limits" to users. This tool returns expense policy rules in the EXACT same format as shown in the Brex Dashboard's "View policy" sidebar, but structured as JSON for proper validation. What you'll get: - formatted_text: Human-readable policy text matching Dashboard display - sections: Array of policy sections with rules - has_restrictions: Boolean indicating if there are any policy restrictions - budget_name: Name of the limit - policy_name: Name of the policy Use this tool to answer questions like: - "Do I need a receipt for this $30 lunch?" - "Can I expense alcohol?" - "Who needs to approve my $500 dinner?" - "What's the limit before I need approval?" - "Do I need to list attendees for a business meal?" - "Can I expense Uber Eats?" - "What's the approval policy?" IMPORTANT: This tool requires a spend_limit_id. When the user asks policy questions without specifying a limit: 1. First call list_my_limits to get available limit IDs 2. If there's only one limit, use its ID automatically 3. If there are multiple limits and the user didn't specify which one, ask for clarification Parameters: - spend_limit_id: REQUIRED - The ID of the limit. Use the ID directly from list_my_limits response. - rules_filter: OPTIONAL - Which view of the policy to return: - "ONLY_RELEVANT_FOR_REQUESTER" (default): Shows personalized rules for the requesting user - "ALL_RULES": Shows complete policy including all user-specific exceptions (requires admin permissions) Response Format:* Returns structured JSON with: - formatted_text: Natural language policy rules - sections: Array of {title, type, description, rules[]} - has_restrictions: boolean - budget_name: string - policy_name: string

get_reimbursement_payout_date

ChatGPT
Get the expected payout date for a reimbursement expense. Returns the date when the reimbursement payment is expected to arrive. Only works for REIMBURSEMENT type expenses that are paid through Brex. Note: This tool will return an error if the reimbursement is configured to be paid outside of Brex (Pay outside of Brex / PoB). In those cases, the payment is handled directly between the company and employee (usually at payroll time), and Brex does not control the payment date. Parameters: - expense_id: The ID of the reimbursement expense Example: { "expense_id": "expense_123" } Response includes: - expense_id: The ID of the expense - expense_type: The type of the expense (will be REIMBURSEMENT) - expected_reimbursement_payout_date: The expected date when the reimbursement will be paid out (ISO 8601 format, UTC timezone) - status: The current status of the expense

get_reward_points

ChatGPT
Get the Brex reward points balance and redemption eligibility for the authenticated account. Returns the current reward balance, wallet type (POINTS or CASH), and whether the account can currently redeem rewards. Parameters: none. Example response: { "amount": 2781573647, "type": "POINTS", "redeemable": true } Notes: - "amount" is in centipoints when "type" is POINTS (divide by 100 to get points). - "amount" is in USD cents when "type" is CASH. - "redeemable" is false if the account is delinquent.

get_spend_limit_by_id

ChatGPT
Get complete details for one spend limit by its raw ID. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. Use this only after the request or a prior tool result identifies one specific spend limit. Pass the raw budget_... ID returned by list_spend_limits or list_my_limits; do not pass a limit name or Relay-encoded ID. ROUTING EXAMPLES: - "Show full details for spend limit budget_123" → use this tool - "Show full details for the Marketing limit I manage" → use list_spend_limits first, then this tool with the resolved ID - "How much is available on that limit?" after a list result identified one limit → use this tool with that result's ID - "Which spend limits can I manage?" → use list_spend_limits - "What limits can I spend from?" → use list_my_limits Returns financial details, dates, owners, members, visibility, and the visible containing-budget path when the caller is authorized to view them.

get_user_by_id

ChatGPT
Get a user by their unique ID This tool retrieves detailed information about a specific user using their unique user ID. Use this when you have a user ID and need to get their complete profile information. Example Input: { "id": "cuuser_123" } Example Output: { "id": "cuuser_123", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "role": "CARD_ADMIN", "status": "ACTIVE", "manager_id": "cuuser_5678", "manager_first_name": "Jane", "manager_last_name": "Smith", "manager_title_id": "ti_1234", "manager_title_name": "Engineering Manager", "department_id": "cudmnt_1234", "department_name": "Engineering", "location_id": "culoc_1234", "location_name": "San Francisco", "title_id": "ti_5678", "title_name": "Software Engineer" }

get_user_myself

ChatGPT
Get the current authenticated user This tool retrieves the profile information of the currently authenticated user making the request. Use this when you need to get information about who is currently logged in or making the API call. No input parameters required. Example Output: { "id": "cuuser_123", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "role": "CARD_ADMIN", "status": "ACTIVE" }

get_vendor_by_id

ChatGPT
Get a vendor by ID

list_accounting_records

ChatGPT
List accounting records with filters and pagination. This tool returns accounting records with the full record shape, including amounts, source information, users, vendors, receipts, and line items. Supported filters: - ids: specific accounting record IDs - review_status: workflow stage for CARD and REIMBURSEMENT records - source_type: high-level source filter such as CARD, REIMBURSEMENT, or BILL - updated_at: gt/gte/lt/lte timestamp filters for polling - single_entry: return single-entry line items instead of the default double-entry view - cursor and limit: pagination controls Constraint: - review_status is not supported with source_type=BILL

list_banking_transactions

ChatGPT
List banking transactions with filters, date ranges, amount ranges, and sorting. If the user mentions an account by name, use list_business_accounts first to resolve the name to an ID. Results are paginated - use limit and cursor for pagination. IMPORTANT: Transaction amounts use signed convention: - Positive amounts = incoming money (credits/deposits) - Negative amounts = outgoing money (debits/payments) For incoming transactions (money received), use positive min_amount. For outgoing transactions (money sent/paid), use negative max_amount. CRITICAL - Amount filter decision logic: 🔍 When the user mentions amounts, ALWAYS include the appropriate filter: "Over $X" or "More than $X": - Incoming: min_amount: X (e.g., "deposits over $100" → min_amount: 100) - Outgoing: max_amount: -X (e.g., "payments over $1000" → max_amount: -1000) "Between $X and $Y": - MUST include BOTH min_amount AND max_amount - Incoming: min_amount: X, max_amount: Y (e.g., "deposits between $100 and $500") - Outgoing: min_amount: -Y, max_amount: -X (e.g., "payments between $100 and $500" → min_amount: -500, max_amount: -100) "Under $X" or "Less than $X": - Incoming: max_amount: X - Outgoing: min_amount: -X Example 1: Getting recent transactions sorted by timestamp: { "sort": "TIMESTAMP", "sort_direction": "DESCENDING" } Example 2: Getting ACH transactions for a specific account: { "business_account_ids": ["dpacc_abc123"], "type": ["ACH"] } Example 3: Incoming transactions over $100 (deposits/credits): { "start_date": "2025-01-01T00:00:00Z", "end_date": "2025-01-31T23:59:59Z", "min_amount": 100.00 } Example 4: Outgoing payments over $1,000 (debits): { "max_amount": -1000.00, "sort": "AMOUNT_USD_CENTS", "sort_direction": "ASCENDING", "limit": 10 } Example 5: Account transfers between Brex accounts: { "type": ["ACCOUNT_TRANSFER", "BOOK_TRANSFER"] } Example 6: Only processed transactions: { "status": ["PROCESSED"] } Example 7: Pending transactions (processing or awaiting approval): { "status": ["PROCESSING", "APPROVAL_REQUIRED"] }

list_bills

ChatGPT
List bills for your team members or entire company based on permissions. This tool allows managers and admins to retrieve bills using different scopes. By default, returns bills with statuses: DRAFT, SUBMITTED, APPROVED, OUT_OF_POLICY, CANCELED, VOID. Parameters: - vendor_id: Optional vendor ID to filter bills by a specific vendor - incurred_by: Determines whose bills to show (optional). Options: - Not specified: All bills you have permission to see (for admins/bookkeepers: all company bills) - "REPORTS": Bills from your direct reports only - "ALL_REPORTS": Bills from all nested reports (your reports + their reports) Note: Regular users without reports will get no results when using REPORTS/ALL_REPORTS. - statuses: Optional array of expense statuses to filter by (bills are expenses with type=BILLPAY). Supported values: DRAFT, SUBMITTED, APPROVED, OUT_OF_POLICY, CANCELED, VOID. If not specified, defaults to DRAFT, SUBMITTED, APPROVED, OUT_OF_POLICY, CANCELED, and VOID. - limit: Number of results to return (default: 15, max: 100) - cursor: Pagination cursor for next page of results Example 1: Get ALL company bills (admin/bookkeeper access): { "limit": 50 } Example 2: Get bills from direct reports: { "incurred_by": "REPORTS", "statuses": ["DRAFT", "SUBMITTED"] } Example 3: Get all team bills (including nested reports): { "incurred_by": "ALL_REPORTS" } Example 4: Get all company bills from a specific vendor: { "vendor_id": "vendor_abc123" }

list_bookings

ChatGPT
List travel bookings across the company with filtering, sorting, and pagination. Mirrors the Bookings page on the Brex dashboard (Travel → Company → Bookings). Use this tool when the user asks specifically about individual bookings (flights, hotels, car rentals) rather than whole trips. Results are always sorted by booking start date descending. Filters are grouped to match the dashboard: General: - booking_start_date_on_or_after / booking_start_date_on_or_before: Booking start date. Date (YYYY-MM-DD) bounding the booking start date (local). - booking_types: Booking type. Array of booking categories (AIR, CAR_RENTAL, LIMO, LODGING, MISC, RAIL). People: - booker_user_ids: Booker. Array of booker (employee) user IDs (cuuser_) to filter by specific bookers. - traveler_user_ids: Traveler. Array of traveler user IDs (cuuser_) to filter by traveler. - traveler_guest_emails: Traveler. Array of guest traveler emails to filter by traveler. - traveler_types: Traveler type. Array of ["EMPLOYEE", "GUEST"] to narrow by traveler type. Status: - booking_statuses: Booking status. Array of booking statuses (CONFIRMED, PENDING, CANCELED, etc.). - approval_statuses: Approval status. Array of approval statuses (APPROVED, PENDING, REJECTED). - policy_statuses: Policy status. Array (IN_POLICY, OUT_OF_POLICY). Pagination: - limit: Page size (default 25, max 100). - cursor: Cursor from a previous response's next_cursor. Example: { "booking_types": ["AIR"], "booking_statuses": ["CONFIRMED"] }

list_business_accounts

ChatGPT
List business accounts. Results are paginated - use limit and cursor for pagination. Example 1: Getting the first 10 accounts: { "limit": 10 } Example 2: Paginating through accounts: { "limit": 25, "cursor": "cursor_from_previous_response" }

list_cards

ChatGPT
List cards with comprehensive filtering. Use this for both personal card queries and company-wide card management. 🔍 IMPORTANT - How to scope card queries with card_holder: Personal queries (use card_holder: "ME"): - "my cards", "my locked cards", "do my cards have..." - "which of my cards is active" - "show me my cards" → SET card_holder: "ME" to return only the calling user's cards IMPORTANT DEFAULT BEHAVIOR: When the query is ambiguous (no explicit "company/all/team" scope), default to card_holder: "ME" since users typically want their own cards. Company-wide queries (omit card_holder): - "all company cards", "list all cards", "company card inventory" → OMIT card_holder to return all cards across the organization (admin only) Specific user queries (use user_ids): - "John's cards", "show Alice's cards" → First call list_users_by_name_or_email to get user ID, then pass user_ids parameter You can filter by status views (ACTIVE, EXPIRED, LOCKED, TERMINATED, WAITING_ACTIVATION) and card holder user IDs. Results are paginated - use limit and cursor for pagination. IMPORTANT: card_holder and user_ids are mutually exclusive. Use card_holder for self-scoping or user_ids for specific user IDs, but not both. Example 1: Getting all my active cards: { "card_holder": "ME", "status": ["ACTIVE"] } Example 2: Getting all my cards (any status): { "card_holder": "ME" } Example 3: Getting all active cards (admin): { "status": ["ACTIVE"] } Example 4: Getting all active and locked cards for specific users: { "status": ["ACTIVE", "LOCKED"], "user_ids": ["user_123"] } Example 5: Getting cards for a specific user: { "user_ids": ["user_123"] }

list_cards_shipping_details

ChatGPT
List card shipping details with filters. Pagination: - limit: max cards per page (1-100, default 10); a higher value is clamped to 100 - cursor: pass next_cursor from the previous response - To retrieve the full set, continue until next_cursor is null. Example 1: Getting shipping details for all cards waiting activation: { "status": ["WAITING_ACTIVATION"] } Example 2: Getting shipping details for specific users: { "user_ids": ["user_123"] } SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. GLOBAL USER-FACING RULES — apply to EVERY message you send the operator. Everything in this description is internal contract. It is here so you can reason and build a correct call; none of it belongs in a reply. - Never show wire values. Statuses, reasons, card categories, card forms, reset frequencies and limit flexibilities are internal codes: say "locked", "cancelled", "a virtual card", "monthly", "up to 10% over the limit". - Never show request or response FIELD NAMES, and never use field: value form. Describe what the operator will observe, in prose. - Never show internal IDs (card, user, policy, limit). Name objects by display name only, e.g. "Tony Report", "Default Policy". - Never name tools or internal steps: no "list_cards", "duplicate check", "preflight", "tool call". - Never volunteer how Brex records a card action internally. The spend limits, budgets and other bookkeeping behind locking, cancelling, transferring or issuing a card are implementation, not product: describe only what the operator will observe. Spend limits ARE a product the operator can be offered in their own right — the rule is about not explaining a card action in terms of them. - Any examples below use wire vocabulary deliberately, because they show the shape of a call. Copy their structure, never their vocabulary.

list_cost_centers

ChatGPT
List cost centers (id + display name). REQUIRED prerequisite for the list_users cost_center filter: list_users only accepts cost center IDs, so whenever the user mentions a cost center by name (e.g. "R&D", "Sales"), call this tool first and pass the returned id into list_users. Parameters: limit (1-200, default 25), cursor (pagination), search_text (narrow by name). Example Output: { "items": [{ "id": "cc_1234", "name": "Engineering" }], "next_cursor": "cursor_abc" }

list_departments

ChatGPT
List departments (id + name). REQUIRED prerequisite for the list_users department filter: list_users only accepts department IDs, so whenever the user mentions a department by name (e.g. "Engineering", "Finance"), call this tool first and pass the returned id into list_users. Parameters: limit (1-200, default 25), cursor (pagination), search_text (narrow by name). Example Output: { "items": [{ "id": "cudmnt_1234", "name": "Engineering" }], "next_cursor": "cursor_abc" }

list_employee_card_limits

ChatGPT
List employee card limits across the account. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. Use this for account-wide questions about spendable employee card limits: - "Show me everyone's spendable employee card limits" - "List employee card limits" - "Which employee card limits are spendable?" - "How much employee card limit does Grace have?" Returns employee card limit details including the limit name, configured amount (total), spent amount, and available amount. For questions about a specific employee's card limit, limit amount, or available card spend, this is still the right tool. Do not call user lookup tools just to answer employee-card-limit amount questions. Match the employee by the returned limit name. This does not list card records, card IDs, card numbers, card status, physical/virtual card form, shipping details, or other card metadata. Use list_cards for card records or card lifecycle questions. This tool only returns employee card limits with spendable configuration. Here, spendable means every limit rule has a positive funded amount or is unlimited, or at least one active positive temporary override exists. It does not account for whether the cardholder has permission to spend.

list_expense_categories

ChatGPT
List all available expense categories (also known as 'expense types' in Brex) for filtering expenses. Expense categories are custom categorizations like: - Airfare, Lodging, Car Rental (travel) - Meals & Entertainment - Office Supplies - Software & SaaS - Marketing & Advertising - Professional Services Use this tool to: - Discover available expense category IDs for the expense_category_ids filter - Search categories by name (e.g., "travel", "meals") - Browse all configured expense categories Parameters: - query: Optional search to filter by name (e.g., "travel", "meals") - limit: Page size (default 25, max 100) - cursor: Pagination cursor from previous response Example — find travel categories: { "query": "travel" } Response (trimmed): { "items": [ { "id": "category_abc", "name": "Airfare" }, { "id": "category_def", "name": "Car Rental" } ], "next_cursor": null }

list_expense_policies

ChatGPT
List expense POLICY RECORDS for the account (catalog/discovery). Returns lightweight summaries only — not rules, not limit balances. Supports filtering by default flag and by status, INCLUDING listing disabled/inactive policies (statuses: ["DISABLED"]). WHEN TO USE (account policy catalog): - User wants to see which policies exist, find the default policy, or browse policy names/IDs - User wants to list DISABLED / inactive / archived policies → this IS supported here: call this tool with statuses: ["DISABLED"]. Do NOT submit_feedback claiming status filtering is unavailable — it is available via the statuses param. - Examples: "What expense policies do we have?", "Show me the default expense policy", "Which expense policy is the default?", "List all disabled expense policies" (use statuses: ["DISABLED"]). Use filters internally, but do not mention raw parameter names to the user. WHEN NOT TO USE — pick a different tool instead: - User asks policy RULES / compliance on their spending (receipts, approvals, "can I expense X") → list_my_limits then get_expense_policy with spend_limit_id - User asks about limit balances or "how much is left" → list_my_limits - User asks what they can spend on their card in general → get_expense_policy or list_my_limits (not this tool) What you get back: - items[]: policy summaries — id, display_name, description, is_default, status (NO receipt/approval/merchant rules) - next_cursor: opaque cursor for the next page, or null after the final page Scope: Returns the account's EXPENSE policies. Defaults to ACTIVE (CREATED); override with statuses. After discovery: To show full rules for a policy, you still need a spend limit attached to that policy — call list_my_limits, then get_expense_policy with spend_limit_id. This tool does not return rule text. Parameters (all optional): - limit: max policies per page (1-100). Defaults to 10 when omitted. - cursor: opaque next_cursor from the previous response; omit for the first page. - default-policy filter: true = only default policies; false = only non-default; omit = both. - policy_ids: restrict to specific policy IDs. - statuses: defaults to CREATED (active). Pass ["DISABLED"] to list disabled/inactive policies, or ["CREATED","DISABLED"] for both.

list_expenses

ChatGPT
List expenses with comprehensive filtering. Use this for both personal expense queries and company-wide financial analysis. IMPORTANT - For large datasets (50+ expenses): If your environment supports downloading files from URLs, consider using start_expense_download for CSV export instead to avoid loading hundreds of records into conversation context. This tool returns paginated results suitable for smaller queries and interactive workflows. IMPORTANT - How to scope expense queries with expense_owner: 🔍 The primary users of this tool are admins and finance operators, so the DEFAULT SCOPE is company-wide. Only narrow to the caller when the user explicitly says so. IMPORTANT DEFAULT BEHAVIOR: When the query is ambiguous or phrased generically (no possessive "my"/"mine" and no subject "I"), OMIT expense_owner. This returns all expenses across the organization, which is what admins asking questions like "show expenses over $500", "find expenses missing receipts", "which expenses are declined" expect. ⚠️ Do NOT treat "show me X" as a personal-scope signal. "me" is just the indirect object of "show" — it does NOT imply the user owns the expenses. Only the possessive "my"/"mine" or the subject "I" indicate personal scope. Personal queries ONLY when the user explicitly refers to themselves (use expense_owner: "ME"): - Possessive: "my expenses", "my receipts", "my reimbursements", "my card transactions", "which of my expenses..." - Subject "I": "how much have I spent", "what did I spend on...", "am I spending more on..." - Do NOT infer personal scope from: "show expenses", "find expenses", "list expenses", "which expenses", "show me expenses", "expenses over $X", "expenses from [merchant]" → SET expense_owner: "ME" ONLY when the user message contains "my", "mine", or "I" as a subject referring to the caller Company-wide queries (OMIT expense_owner — this is the default): - Any request without a first-person pronoun: "show expenses", "find expenses missing receipts", "which expenses are flagged", "list card expenses over $500" - Explicit company language: "our burn rate", "we spent", "company expenses", "overall spending", "analyze all card transactions", "total reimbursements" → OMIT expense_owner to return all expenses across the organization Team queries (use expense_owner: "DIRECT_REPORTS" or "ALL_REPORTS"): - "my team's expenses", "direct reports' spending" - "expenses from all my reports" → Use DIRECT_REPORTS for immediate reports only, or ALL_REPORTS for nested reports Specific user queries (use user_ids): - "show John's expenses", "Alice's reimbursements" → First call list_users_by_name_or_email to get user ID, then pass user_ids parameter IMPORTANT - Location and travel data: 🌍 Location and travel data are ALWAYS null by default unless you explicitly request them via additional_fields. When user asks about WHERE an expense occurred (location, city, country, address): - Query asks: "Where was that expense?", "What city was this from?", "Show me the location" → You MUST include additional_fields: ["LOCATION"] When user asks about travel details (flights, hotels, car rentals): - Query asks: "Was this a flight?", "Show me travel expenses", "Which hotel?" → You MUST include additional_fields: ["TRAVEL_METADATA"] ⚠️ A null location does NOT mean "no location exists" - it means you did not request it in additional_fields. expense types (BILLPAY, CARD, CLAWBACK, REIMBURSEMENT), Filter Usage Best Practices: - For CARD expense queries, always include date filters (purchased_at_start/purchased_at_end) for reliable results - When using min_amount/max_amount filters, combine with date filters for better performance Date Filtering (only one type can be used at a time): IMPORTANT - Default to purchased_at for ALL time-based queries. The purchased_at filter covers when the transaction actually occurred and is the correct filter for general date queries like "this week", "last month", "recent", "posted this week", etc. Only use posted_at when the user explicitly needs the bank settlement/accounting posting date for reconciliation purposes. - Purchase Date (DEFAULT): purchased_at_start/purchased_at_end - Filter by when expense was purchased/transacted. Use this for all general date queries. Date must be in UTC timezone. - Posted Date (accounting only): posted_at_start/posted_at_end - Filter by bank settlement/posting date. Only use when user specifically needs accounting posting dates. Date must be in UTC timezone. - Reimbursement Submission Date: reimbursement_submitted_at_start/reimbursement_submitted_at_end - Filter by when reimbursement was submitted (only works with REIMBURSEMENT type). Date must be in UTC timezone. Amount Filtering (all amounts in USD): - min_amount: Filter expenses with amount greater than or equal to this value (in USD, supports decimals with up to 2 places) - max_amount: Filter expenses with amount less than or equal to this value (in USD, supports decimals with up to 2 places) Text Search: - search: Search expenses by merchant name, memo, or other text fields (e.g., "nike", "lunch") Limit Filtering: - limit_ids: Filter expenses by spend limit IDs (e.g., ["limit_123", "limit_456"]) CRITICAL: This parameter ONLY accepts limit IDs (like "spl_abc123"). It does NOT accept limit names (like "Tony's T&E"). If the user mentions a limit by name, you MUST first call list_my_limits to resolve the name to an ID, then pass that ID here. NEVER pass a limit name directly to this parameter - it will not work correctly. Expense ID Filtering: - expense_ids: Filter by specific expense IDs (e.g., ["expense_123", "expense_456"]) Additional Fields: - additional_fields: Array of optional fields to include in response. Supported values: "TRAVEL_METADATA" - Includes flight, car rental, lodging, and train travel data "LOCATION" - Includes expense location details (country, city, coordinates, etc.) Note: Location and travel data are NOT returned by default. If the response has null location/travel and the user is asking about it, re-call with the relevant additional_fields value. Expense records include associated card details (card ID, status, last four digits) when available - you do not need to separately look up cards to answer questions about expenses on specific cards. IMPORTANT: expense_owner and user_ids are mutually exclusive. Use expense_owner for role-based scoping or user_ids for specific user IDs, but not both. Expand (receipt details): - expand: Use ["RECEIPTS"] to include full receipt details. WITHOUT expand, receipts only contain IDs. WITH expand: ["RECEIPTS"], each receipt includes: download_uri - URL to download the receipt file/image content.is_real_receipt - whether the file is classified as a real receipt content.merchant_name - merchant name parsed from the receipt content.purchased_at - purchase date parsed from the receipt content.amount - amount parsed from the receipt content.line_items - itemized charges from the receipt (name, quantity, unit_price, total) ⚠️ When the user asks about receipt line items, itemized charges, "what did I buy", receipt content, receipt images/downloads, or parsed receipt data → you MUST include expand: ["RECEIPTS"]. A receipt with only an ID and no content/download_uri means expand was NOT used — re-call with expand: ["RECEIPTS"]. Status Filters: - approval_statuses: Filter by approval status. Dashboard-exposed values: APPROVED, CANCELED, OUT_OF_POLICY, SUBMITTED. - pending_approvals: FROM_ME (pending your approval) or FROM_OTHERS (pending another approval). - payment_statuses: Payment lifecycle state (NOT_STARTED, SCHEDULED, PROCESSING, CANCELED, CLEARED, DECLINED, REFUNDING, REFUNDED, CASH_ADVANCE, CREDITED, AWAITING_PAYMENT). - dispute_statuses: Dashboard-exposed values: DISPUTE_STATUS_IN_PROGRESS, DISPUTE_STATUS_CLOSED. - reimbursement_export_statuses: EXPORTED or NOT_EXPORTED (reimbursement export state). - user_status: Filter by spender's user status. Dashboard-exposed: ACTIVE, DELETED, DISABLED. Reimbursement-only filters (require types: ["REIMBURSEMENT"]): - reimbursement_types: MILEAGE, OUT_OF_POCKET, PER_DIEM. - reimbursement_payment_method: MONEY_MOVEMENT (paid on Brex) or TRACKING (paid outside of Brex). Travel filters: - travel_provider: BREX_TRAVEL (only Brex Travel) or NON_BREX_TRAVEL (exclude Brex Travel). - trip_ids: Filter by trip IDs — use list_active_and_upcoming_travel_trips to discover IDs. Compliance Filters (matches dashboard labels): - compliance_statuses: Overall compliance status (DOCUMENTATION_DUE, REVIEW_DUE, COMPLETED). Matches the 'Compliance status' filter in the Brex dashboard. - documentation_statuses: Documentation deadline status (DUE, OVERDUE, COMPLETED). Matches the 'Documentation status' filter in the Brex dashboard. Use [DUE, OVERDUE] to find expenses missing required documentation. - receipt_status: RECEIPT_PRESENT or RECEIPT_ABSENT. - memo_status: MEMO_PRESENT or MEMO_ABSENT. - require_review_reasons: MEALS, CAR_RENTAL (Rides), FLIGHTS, LODGING, TRAINS, MILEAGE, MERCHANT_OR_CATEGORY, AMOUNT, OTHERS. - government_attendees_status: GOVERNMENT_OFFICIAL_PRESENT or GOVERNMENT_OFFICIAL_ABSENT. - expense_policy_ids: Filter by policy IDs — use get_expense_policy to inspect a specific policy. - bill_invoice_numbers: Filter Bill Pay expenses by invoice number (free text). Approver / Approval filters: - approver_user_ids: Filter by approvers in the approval chain — resolve user IDs via list_users_by_name_or_email. - next_approver_user_ids: Filter by the next approver in the chain — resolve user IDs via list_users_by_name_or_email. Organization Filters: - department_ids: Filter by department IDs — use list_departments to discover IDs. - card_ids: Filter by card IDs (use this when the user mentions a card by last-4). - vendor_ids: Bill Pay vendor IDs — use list_vendors to discover. - merchant_ids: Card merchant IDs — use list_merchants to discover. - merchant_category_ids: Merchant category IDs — use list_merchant_categories to discover. Accounting Filters: - billing_entity_ids: Filter by billing (funding) legal entity IDs. Also called 'billed entity' in the Dashboard. - spending_entity_ids: Filter by spending legal entity IDs. - cost_center_ids: Filter by cost center IDs. - expense_category_ids: Filter by expense category IDs — use list_expense_categories to discover IDs. - erp_debit_gl_account_field_key + erp_debit_gl_account_option_ids: Filter by ERP debit GL account. These two parameters MUST be sent together. Workflow: (1) call list_gl_accounts, (2) copy gl_account_field.key into erp_debit_gl_account_field_key, (3) copy the desired accounts[].identifier values (not id, not value) into erp_debit_gl_account_option_ids. Never guess the field_key — it is dynamic per accounting integration. Risk Filter: - high_risk_flagged: When true, only returns expenses flagged as HIGH risk. Omit (or false) to not filter by risk tier. Date Filters (use only ONE of purchased/posted/reimbursement_submitted at a time; assigned_at is independent): - assigned_at_start / assigned_at_end: Date expense was assigned to the caller for review. Understanding Expense Lifecycle and Compliance Status: Expense Lifecycle: 1. New expense created (card transaction or reimbursement submitted) 2. Documentation phase: System checks if documentation is required (receipts, memo, attendees, etc.) 3. Spender submits documentation if needed 4. Review phase: System checks if approval/review is required based on company policy 5. Reviewer reviews and approves/rejects if necessary 6. Expense is finalized Each expense returns TWO sets of compliance-related fields: A. DOCUMENTATION COMPLIANCE (for spenders - receipts, memo, attendees): - documentationComplianceStatus: Status of documentation requirements that the spender must fulfill "NOT_REQUIRED" - Company policy does not require any documentation for this expense. Empty receipts/memo are acceptable. "COMPLETED" - All required documentation has been provided according to policy. "DUE" - Documentation is required by policy but not yet provided. Check missingDocumentations field for specifics. "OVERDUE" - Required documentation is past its submission deadline. Check missingDocumentations field for specifics. - missingDocumentations: Array of specific items required by policy but not yet provided. Possible values: ["MEMO", "RECEIPT", "ATTENDEES", "EXTENDED_FIELD"] Empty array [] - Either no documentation is required OR all required documentation is complete Non-empty array - Lists specific items that must be provided (e.g., ["MEMO", "RECEIPT"]) - documentationSubmissionDeadline: The UTC timestamp by which documentation must be submitted (only present if documentation is required) B. REVIEW COMPLIANCE (for reviewers - approval/rejection): - reviewComplianceStatus: Status of review/approval requirements that the reviewer must fulfill "NOT_REQUIRED" - Company policy does not require review/approval for this expense. "COMPLETED" - The expense has been reviewed and approved/rejected. "DUE" - Review is required by policy but not yet completed. "OVERDUE" - Required review is past its deadline. - reviewDeadline: The UTC timestamp by which the review must be completed (only present if review is required) KEY DISTINCTIONS: - DocumentationComplianceStatus="NOT_REQUIRED" and missingDocumentations=[] → Documentation not required by company policy - Empty receipts/memo with documentationComplianceStatus="DUE" or "OVERDUE" and missingDocumentations=["RECEIPT","MEMO"] → Documentation IS required by policy but missing - reviewComplianceStatus="DUE" or "OVERDUE" → Expense is waiting for someone to review/approve it - reviewComplianceStatus="NOT_REQUIRED" → No approval needed All dates should be in ISO 8601 format (e.g., "2025-04-01T07:00:00.000Z"). Date must be in UTC timezone. All amounts are assumed to be in USD currency. Results are paginated - use limit and cursor for pagination. Example 1: Analyze company monthly burn rate (all card spend in March 2025): { "types": ["CARD"], "purchased_at_start": "2025-03-01T00:00:00.000Z", "purchased_at_end": "2025-03-31T23:59:59.999Z" } Example 2: Find all high-dollar expenses over $5,000 in Q1 2025: { "min_amount": 5000, "purchased_at_start": "2025-01-01T00:00:00.000Z", "purchased_at_end": "2025-03-31T23:59:59.999Z" } Example 3: Analyze SaaS/software spending (search for common software vendors): { "search": "AWS", "types": ["CARD"], "purchased_at_start": "2025-01-01T00:00:00.000Z", "purchased_at_end": "2025-12-31T23:59:59.999Z" } Example 4: Review all pending reimbursements awaiting payout: { "types": ["REIMBURSEMENT"] } Example 5: Analyze travel spending across the company (exclude Brex Travel): { "types": ["CARD"], "travel_provider": "NON_BREX_TRAVEL", "additional_fields": ["TRAVEL_METADATA"], "purchased_at_start": "2025-01-01T00:00:00.000Z", "purchased_at_end": "2025-03-31T23:59:59.999Z" } Example 6: Find expenses missing receipts for compliance audit (preferred): { "receipt_status": "RECEIPT_ABSENT", "types": ["CARD"], "min_amount": 1000 } Example 7: Expenses requiring review for flights / lodging: { "require_review_reasons": ["FLIGHTS", "LODGING"] } Example 8: Expenses pending my approval: { "pending_approvals": ["FROM_ME"] } Example 9: Reimbursements paid outside of Brex: { "types": ["REIMBURSEMENT"], "reimbursement_payment_method": "TRACKING" } Example 10: Expenses with a government official attendee: { "government_attendees_status": "GOVERNMENT_OFFICIAL_PRESENT" } Example 11: Expenses for a specific department (resolve name → ID with list_departments first): { "department_ids": ["cudmnt_eng123"] } Example 12: Expenses for a specific merchant: { "merchant_ids": ["mrch_starbucks"] } Example 13: Expenses by posted date (accounting): { "posted_at_start": "2025-04-01T00:00:00.000Z", "posted_at_end": "2025-04-30T23:59:59.999Z" } Example 12: Get expenses with full receipt details including line items: { "expense_owner": "ME", "expand": ["RECEIPTS"] }

list_field_values

ChatGPT
List configured choices for a field. When a request includes both an ERP code and an external reference, validate them together in one call using value_id and remote_id; each result must match both identifiers. If that combined lookup returns no choices, ask for corrected identifiers before recommending a classification. To check a specific named choice, always pass the display name as value. A response with non-null next_cursor is incomplete: fetch every remaining page or repeat the lookup with value before declaring a choice missing. A missing-choice verdict requires a successful lookup ending with next_cursor=null and no matching label. No record or expense ID is needed. Resolve field_id from the field brex_id returned by list_fields. Filter by value_id for ERP codes or remote_id for external references. For a full catalog, omit value and follow every next_cursor while preserving field_id and filters. Active and disabled choices are returned together; inspect is_disabled before recommending a choice for new coding. Show value labels to the user. The option brex_id is the Brex choice ID used as value_id for an IDENTIFIER accounting assignment; returned value_id is a separate remote-system code. This tool discovers choices and does not change record classification.

list_fields

ChatGPT
List visible field definitions to find dimensions for classifying accounting records or match a requested field. Omit group to read all eligible definitions, or narrow by group. ACCOUNTING contains custom accounting fields native to Brex, with Brex as the source of truth. ERP contains accounting fields sourced from your connected ERP, such as NetSuite, with that ERP as the source of truth. USER contains user information fields. For ERP coding with a connected non-CSV integration, use ERP fields. Inspect field_type and is_disabled before recommending a value. For selectable choices, pass a returned brex_id as field_id to list_field_values. This tool returns field definitions, rather than values selected on individual records; it does not read or change a record's classification. Use field_id to filter known field IDs. When searching across pages, keep the same filters on every paginated request and follow each returned next_cursor; pagination is complete only when next_cursor is null.

list_gl_accounts

ChatGPT
List all available GL accounts for the active accounting integration. This tool executes a 3-step process: 1. Get the active accounting integration ID 2. Use the integration ID to get the extended field ID for GL accounts 3. Use the extended field ID to get all GL account options Returns an object containing: - accounts: Array of GL accounts - glAccountField: The extended field definition for GL accounts - gl_account_type: Nullable GL account type on each account when the ERP provides it Returns null if no active integration is found. Example response: { "glAccountField": { "id": "extended_field_cm9vkatzo0b8e0i36rxhz7z4r", "key": "user_category_int_cm9vkas3n00zx0e00zsk25h7z", "name": "GL Account", "status": "ACTIVE" }, "accounts": [ { "id": "efo_cm9vkauq30b9h0i36k2r3p66f", "identifier": "1328446901", "value": "1010 Cash", "status": "ACTIVE", "gl_account_type": "ASSET" }, { "id": "efo_cm9vkauq30b9i0i36pkb9lzan", "identifier": "-1076004205", "value": "1020 Accounts Receivable", "status": "ACTIVE", "gl_account_type": null } ] }

list_limit_groups

ChatGPT
Lists spend limit groups the caller can manage: name, status, parent budget, and ID. Callers with account-wide budget access see every group; others see only groups they can access. USER-FACING RULES (every reply): - Don't show IDs unless asked; name objects by display name. - Say "spend limit group". Tell same-named groups apart by status and parent budget. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. ROUTING: - Use this tool for: groups I can manage, a named group, every group including archived, or a group's limit per user. - Spend limits I manage → list_spend_limits. Limits I can spend from → list_my_limits. Employee card limits → list_employee_card_limits. - Every group or a count → follow next_cursor until null; one page, even a full one, is never the whole set.

list_locations

ChatGPT
List locations (id + name). Deleted locations are excluded. REQUIRED prerequisite for the list_users location filter: list_users only accepts location IDs, so whenever the user mentions a location by name (e.g. "San Francisco", "New York"), call this tool first and pass the returned id into list_users. Parameters: limit (1-200, default 25), cursor (pagination), search_text (narrow by name). Example Output: { "items": [{ "id": "culoc_1234", "name": "San Francisco" }], "next_cursor": "cursor_abc" }

list_merchant_categories

ChatGPT
List merchant categories (e.g., Restaurants, Software, Travel). Used to resolve a category name to its ID so that list_expenses can filter by merchant_category_ids. Parameters: - query: Optional similarity search on category name. - limit: Page size (default 25, max 100). - cursor: Pagination cursor from a previous call. Example — find Restaurants category: { "query": "restaurant" } Response (trimmed): { "items": [{ "id": "mccat_abc", "name": "Restaurants" }], "next_cursor": null }

list_merchants

ChatGPT
Search card merchants by name. Used to resolve a merchant name to its ID so that list_expenses can filter by merchant_ids. Parameters: - query: Name substring to search for. Empty string returns popular/recent merchants. - limit: Page size (default 25, max 100). Note: this endpoint does not support cursor pagination. Example — find Starbucks: { "query": "starbucks" } Response (trimmed): { "items": [{ "id": "mrch_abc", "name": "Starbucks" }], "next_cursor": null }

list_my_limits

ChatGPT
Get all spend limits that apply to the current user with pagination support. TERMINOLOGY: On Brex, these are called "limits" — NOT "budgets." There are two kinds: card limits (built into a card) and spend limits (exist independently). "Budget" is a separate Premium-only planning/tracking feature. When users say "budget" they almost always mean "limit." Prefer "limit" in responses unless the user is specifically asking about the Budget feature. The API returns fields named "budget_*" but these should be presented as "limits" to users. Use this tool when: - The user asks about "my limits" or "my spending limits" or "my budget" - The user references a limit by name (e.g., "my Tony Report's T&E limit") - limit names may contain user names but refer to the limit, not the user - You need to find a limit ID to use in other tools - The user asks policy questions (e.g., "Can I expense Uber Eats?", "What's the approval policy?", "Do I need approval for X?", "What's the company travel policy?") → Call this tool FIRST to get limit IDs, then call get_expense_policy with the limit ID to answer the policy question → Policy information is ONLY available through get_expense_policy, which requires a limit ID from this tool DO NOT use list_users_by_name_or_email when the user is asking about their own limits, even if the limit name contains a person's name. DO NOT ask for clarification about which limit when the user asks policy questions - be proactive: call list_my_limits first, and if there's only one limit, use it. DO NOT respond with general policy information or ask which policy the user wants - all policy data comes from get_expense_policy after getting limit IDs from this tool. This includes: - User Limit: The personal spending limit for the user - Spend Limits: Shared spend limits where the user is a member Each limit shows: - Limit amount and remaining balance - Period type (MONTHLY, QUARTERLY, etc.) - Status (ACTIVE, EXPIRED, etc.) - Start and end dates - Amount spent in current period Pagination: - Use 'limit' parameter to specify how many spend limits to return (default: 100, max: 1000) - Use 'cursor' parameter to paginate through results (use next_cursor from previous response) SCENARIO-BASED EXAMPLES: Example 1: Get all my limits (default - returns up to 100 limits): {} Example 2: Get first 10 limits (useful for large accounts): { "limit": 10 } Example 3: Get next page of limits: { "limit": 10, "cursor": "eyJhZnRlciI6IjEwIn0=" } TOOL CHAINING WORKFLOWS: Scenario 1: "How much is left on my Marketing Q1 limit?" → Call list_my_limits with {} to get all limits → Find limit where name="Marketing Q1", extract ID (e.g., "spl_abc123") → Present the available balance from the "available" field Scenario 2: "Show me all expenses on my Travel & Entertainment limit" → Call list_my_limits with {} to get all limits → Find limit where name contains "Travel", extract ID (e.g., "spl_xyz789") → Call list_my_expenses with: { "limit_ids": ["spl_xyz789"] } Scenario 3: "Can I expense Uber Eats on my company card?" (policy question) → Call list_my_limits with {} to get all limits → If user has only one active limit, extract its ID (e.g., "spl_policy123") → Call get_expense_policy with: { "spend_limit_id": "spl_policy123" } → Check policy rules for Uber Eats / Food Delivery merchant restrictions Scenario 4: "Do I need approval for a $200 dinner?" → Call list_my_limits with {} to get limit IDs → Extract relevant limit ID (e.g., "spl_corp456") → Call get_expense_policy with: { "spend_limit_id": "spl_corp456" } → Check policy rules for approval thresholds on meal expenses Scenario 5: "What did I spend on my Q1 Marketing limit last month?" → Call list_my_limits with {} to find "Q1 Marketing" limit → Extract limit ID (e.g., "spl_mkt789") → Call list_my_expenses with: { "limit_ids": ["spl_mkt789"], "purchased_at_start": "2025-03-01T00:00:00.000Z", "purchased_at_end": "2025-03-31T23:59:59.999Z" } Scenario 6: "What are the rules for my Travel limit?" → Call list_my_limits with {} to find "Travel" limit → Extract the Travel limit ID (e.g., "spl_travel101") → Call get_expense_policy with: { "spend_limit_id": "spl_travel101" } → Present the complete policy rules from the response

list_roles

ChatGPT
List Brex account roles. REQUIRED prerequisite for the list_users role and access filters: list_users only accepts role IDs, so whenever the user mentions a role or access type by name (e.g. "card admin", "employee", "bill pay approver", "card access"), call this tool first and pass the returned id into list_users. Roles have two types: - FUNCTIONAL ("what the user is" — CARD_ADMIN, EMPLOYEE, ACCOUNT_ADMIN, ...). These IDs feed the list_users role filter. - ACCESS ("what the user can do" — card access, bill pay approver, travel admin, ...). These IDs feed the list_users access filter. Pass role_type=["FUNCTIONAL"] to resolve names for the role filter, role_type=["ACCESS"] to resolve names for the access filter, or omit to return both. For FUNCTIONAL roles, is_admin=true indicates the role grants admin-level access. Parameters: limit (1-200, default 100), cursor (pagination), role_type (filter by type). Example Output: { "items": [ { "id": "role_1234", "name": "CARD_ADMIN", "display_name": "Card Admin", "role_type": "FUNCTIONAL", "is_admin": true } ], "next_cursor": null }

list_spend_limits

ChatGPT
Lists spend limits the caller can manage. Never returns spend limit groups; for any question about groups, use list_limit_groups. Callers with account-wide budget access see every spend limit; others see limits they own directly or through an ancestor budget. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. ROUTING: - Use this tool for: spend limits I manage, a named spend limit, or Bill Pay limits for a draft bill (status=ACTIVE and eligible_workflow=BILLPAY_BILLS). - Limits I can spend from → list_my_limits. Employee card limits → list_employee_card_limits. - Budget expense totals → list_expenses with its budget_path ID as limit_ids. - Every limit or a count → follow next_cursor until null. - In replies, hide IDs unless asked; tell same-named limits apart by status and budget_path.

list_titles

ChatGPT
List employee titles (id + display title). REQUIRED prerequisite for the list_users title filter: list_users only accepts title IDs, so whenever the user mentions a title by name (e.g. "Software Engineer", "Product Manager"), call this tool first and pass the returned id into list_users. Parameters: limit (1-200, default 25), cursor (pagination), search_text (narrow by title name). Example Output: { "items": [{ "id": "ti_1234", "name": "Software Engineer" }], "next_cursor": "cursor_abc" }

list_trips

ChatGPT
List travel trips across the company with filtering, sorting, and pagination. Mirrors the Trips page on the Brex dashboard (Travel → Company → Trips). Use this tool when the user asks for a company-wide view of trips (e.g. "show all pending trips", "trips booked for Jane next month"). Filters are grouped to match the dashboard: General: - trip_statuses: Trip status. Array of trip statuses to include (e.g. ["UPCOMING", "PENDING"]). When omitted, trips in DRAFT, DELETED, or VOIDED states are excluded by default. To surface those, set trip_statuses explicitly. - policy_status: Policy status. Filter by policy compliance across a trip's bookings (IN_POLICY, ANY_OUT_OF_POLICY, ALL_OUT_OF_POLICY). Trips without bookings are excluded when this is set. Payment: - spend_limit_ids: Spend limit. Array of spend-limit IDs to filter trips by the associated spend limit. Date: - billable_at_on_or_after / billable_at_on_or_before: Billable at. ISO-8601 timestamps bounding the trip's billable-at time. - start_date_on_or_after / start_date_on_or_before: Start date. Date (YYYY-MM-DD) bounding the trip start date. People: - booker_scope: ALL_USERS, SELECTED_USERS, or SELF. Defaults to SELF on the GraphQL layer when omitted. - booker_user_ids: Booker. Array of booker (employee) user IDs (cuuser_). Required when booker_scope is SELECTED_USERS. - traveler_user_ids: Traveler. Array of traveler user IDs (cuuser_) for employees to filter by traveler. - traveler_guest_emails: Traveler. Array of guest traveler emails. - traveler_types: Traveler type. Array of ["EMPLOYEE", "GUEST"] to narrow by traveler type. Sorting: - order_field: Field to sort by (START_DATE, BILLABLE_AT, INSERTED_AT). - order_direction: ASCENDING or DESCENDING. Defaults to DESCENDING. Pagination: - limit: Page size (default 25). - cursor: Cursor from a previous response's next_cursor. Example: { "trip_statuses": ["UPCOMING", "PENDING"], "order_field": "START_DATE", "order_direction": "DESCENDING", "limit": 25 }

list_users

ChatGPT
List users with optional filtering and pagination. ℹ️ Response narrowing for non-admin callers: callers without the user.list operation permission receive the same users, but with email, phone_number, location_id, and location_name omitted. Names, titles, departments, managers, roles, and status are always returned. Use this tool freely for discovery (e.g. picking attendees); fall back to get_user_myself when the caller needs their own contact info. 🚨 CRITICAL — ID filters REQUIRE companion discovery tools FIRST 🚨 The following filters accept ONLY Brex resource IDs (never names, labels, or human-readable strings). If the user describes a filter in plain English (e.g. "Engineering department", "San Francisco office", "Brex Inc. entity", "Software Engineer title", "R&D cost center", "bill pay approvers", "card admins", "reports to Jane Smith"), you MUST call the matching discovery tool first to resolve that string into an ID, then pass the ID here. DO NOT guess IDs. DO NOT pass the human-readable name directly. DO NOT silently drop the filter — always resolve it. Filter → required discovery tool (ALWAYS call the discovery tool first when the user gives you a name instead of an ID): • department → list_departments (IDs look like cudmnt_...) • location → list_locations (IDs look like culoc_...) • cost_center → list_cost_centers (IDs look like cc_...) • entity → list_legal_entities (IDs look like le_...) • title → list_titles (IDs look like ti_...) • role → list_roles with role_type=["FUNCTIONAL"] (IDs look like role_... or aurl_...) • access → list_roles with role_type=["ACCESS"] (IDs look like role_... or aurl_...) • manager → list_users_by_name_or_email (IDs look like cuuser_...) Decision rule: if the user says a NAME, call the discovery tool; pass only the returned ID(s) into list_users. If the user already supplied an ID with the expected prefix, skip discovery and pass it straight through. ✅ Pagination & sorting (no discovery needed): - cursor: Pagination cursor returned from a previous response. - limit: Number of users to return (1-1000, default: 100). - direction / sort: Sort direction ("asc"/"desc") and field (FIRST_NAME, LAST_NAME, EMAIL, ...). ✅ Enum filters (values listed inline — no discovery tool needed): - status: Array of UserStatus (INVITED, PENDING_ACTIVATION, ACTIVE, INACTIVE, DISABLED, ARCHIVED). Defaults to [INVITED, PENDING_ACTIVATION, ACTIVE, INACTIVE] if omitted. - admin_role: Single value of "ADMINS" | "NON_ADMINS" | "ALL". ⚠️ When combining filters (e.g. "active users in Finance"), you MUST still resolve every name-based filter via its discovery tool AND include all requested filters in the final list_users call. Never drop a filter just because another filter was already applied. Example Input 1 (basic, with defaults): {} Example Input 2 (filter by department and role — department and role were resolved via list_departments and list_roles first): { "department": ["cudmnt_1234"], "role": ["role_5678"], "status": ["ACTIVE"] } Example Input 3 (sort descending by last name, paginated): { "limit": 50, "direction": "desc", "sort": "LAST_NAME", "cursor": "cursor_1234" } Example Output: { "items": [ { "id": "cuuser_123", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com", "role": "CARD_ADMIN", "status": "ACTIVE" } ], "next_cursor": "cursor_5678" }

list_users_by_name_or_email

ChatGPT
List users by name or email This tool allows you to search for users by name or email. It will return a paginated list of up to 10 users that match the search criteria, sorted by first name. If you only have the name or email, you can use this tool to find the user ID and their full details. Example Input 1 (search by name): { "search_text": "John Smith" } Example Input 2 (search by email): { "search_text": "john.smith@example.com" } Example Output: { "items": [ { "id": "cuuser_123", "first_name": "John", "last_name": "Smith", "email": "john.smith@example.com", "role": "CARD_ADMIN", "status": "ACTIVE" } ], "next_cursor": "cursor_1234" }

list_vendors

ChatGPT
Get all vendors for the current authenticated user. Results are paginated - use limit and cursor for pagination. IMPORTANT: Always use search_text to filter results when users ask about specific vendors, categories, or contact information. This tool is designed for efficient searching and filtering. Parameters: - cursor: Pagination cursor for next page of results - limit: Default 30 | Max 100 - search_text: Text to filter vendors by name - status: Optional single vendor status to filter by (ACTIVE, DELETED, PENDING, DRAFT, DECLINED, or MERGED) If omitted: Returns only ACTIVE vendors (default backend behavior) If empty array []: Returns vendors of ALL statuses If specified: Returns only vendors with that single status NOTE: Only ONE status can be filtered at a time Search capabilities: - Text search: Searches vendor name, legal name, and business name fields (case-insensitive, partial matching) - Status filtering: Filter by a single vendor status at a time - Combined filtering: Use both search_text and status together for precise results Example usage: - "Show me all my vendors" (only ACTIVE by default): { "limit": 100 } - "Show me ALL my vendors regardless of status": { "status": [], "limit": 100 } - Search for a specific vendor by name across ALL statuses: { "search_text": "Acme", "status": [], "limit": 25 } - Find active software vendors: { "search_text": "Software", "status": ["ACTIVE"], "limit": 100 } - Search by business name (ACTIVE by default): { "search_text": "Corp", "limit": 10 }

lock_card

ChatGPT
Temporarily lock a card only AFTER a separate confirmation turn. The initial request to lock a card is not confirmation: first identify the card, explain that all transactions (including recurring payments) will decline, ask whether to proceed, and STOP to wait for the operator's reply. Do not call lock_card during that first turn. After the operator confirms, call it once. Reversible — a locked card can be restored with unlock_card. While locked, ALL transactions decline, including recurring subscriptions billed to it (they are not paused or cancelled — they simply fail). If any of these are true, this tool is NOT to be called. Recommend the alternative and stop. - Operator wants a new card number because the card was lost, stolen, or compromised → use replace_card, not lock_card. - Operator wants to permanently retire the card without a replacement → use cancel_card, not lock_card. - Operator wants to change the limit, name, policy, or controls → use update_purchasing_card / update_employee_card. - The card is already locked → calling this tool again is a harmless no-op; it will report that nothing changed rather than erroring. - The card is neither active nor awaiting activation (e.g. expired, cancelled) → locking is rejected locally; resolve the underlying issue first. A card that has been issued but not yet activated CAN be locked, and is a normal thing to lock — a physical card in the post that the operator wants stopped before it arrives. Unlocking it later returns it to awaiting activation, not to active: it still has to be activated before it can be used. Say that when it applies, so nobody expects a usable card. — Resolving the card — If the operator names it by vendor / display name / last4 ("lock the Figma card"), call list_cards FIRST. Read the current holder from the user field — NEVER holder_name, which is stale on any card that has been transferred. If more than one candidate matches, present them and ask which one; never guess. — Admin lock warning — Whether a lock becomes an "admin lock" is decided upstream by the CALLER'S ROLE, not by whose card it is: if the caller holds an admin role, the lock is recorded as an admin lock and only an admin can reverse it. The cardholder cannot unlock it themselves — that holds even for an admin locking their own card — and would have to ask an admin. Assume this applies whenever the caller is locking a card they do not hold, and say so explicitly in the confirmation step below. Never promise the cardholder will be able to unlock it themselves. — Confirmation gate (REQUIRED, do this before EVERY call) — 0. reason is optional and never blocks the lock. Pass it only when the operator has already said WHY — their words, not a paraphrase of "lock this card". If they haven't, omit it and carry on; do NOT invent one, and do NOT hold up the gate to ask for one. It is recorded for audit and changes nothing about what the lock does. 1. Present the card being locked and what locking means. Suggested format: You're locking: <display name> (last 4: <last4>), held by <cardholder> This will decline all transactions, including recurring payments, until the card is unlocked.<If admin-locking someone else's card, add:> Because you're locking this on behalf of <cardholder>, only an admin will be able to unlock it — <cardholder> cannot unlock it themselves and would have to ask an admin. 2. Ask a yes/no question whose ONLY purpose is consent. Wait for the answer. 3. Treat answers to clarifying questions (which card) as INPUTS, not consent. The yes/no is a separate, dedicated turn. 4. Only after an explicit yes do you emit the lock_card tool call. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing…

query_expense_analytics

ChatGPT
Query Brex expense data using natural language for comprehensive financial and operational analytics This tool provides access to advanced expense reporting and analytics powered by specialized data models. It allows you to ask questions about spending patterns, compliance issues, budget performance, and organizational metrics using natural language queries. ADMIN ONLY: This tool is only accessible to account administrators. Supported Analytics Capabilities Financial Analysis - Total spending analysis by time period, department, merchant, vendor, or category - Spending trends, comparisons (month-over-month, year-over-year), and forecasting - Top spenders, vendors, and merchants by spend volume - Category-level analytics across 40+ expense categories (travel, software, meals, etc.) - Transaction-level details with temporal analysis (daily, weekly, monthly, quarterly) - Average transaction amounts, statistical outliers, and anomaly detection - Multi-currency support: billing, original, budget, and purchased currency amounts - Spending breakdowns by expense type (card, reimbursement, bill pay) Compliance & Policy Monitoring - Identify expenses missing receipts or memos - Track policy violations and out-of-policy expenses - Monitor expense approval workflows and pending reviews - Audit manually approved transactions without documentation - Receipt compliance tracking by card, user, or department - Expense status tracking (APPROVED, SUBMITTED, OUT_OF_POLICY, DRAFT, CANCELED, SETTLED) Budget & Spend Limit Management - Track department budgets and identify overruns (by $ or %) - Monitor spend limit utilization across organizational units - Track spend limit utilization by team or employee (users often say "spend limit" when they mean "budget" and vice versa — both are covered here) - Compare actual vs. budgeted spend by department or category - Analyze budget performance over time - Identify recently created or edited budgets/limits Disputes & Repayments - Disputed transaction analysis (clawbacks) - Repayment and refund pattern tracking - Dispute trends by employee, department, or time period - Canceled expense tracking Accounting & General Ledger - Double-entry accounting journal records and reconciliation - GL code mapping to expenses, vendors, and departments - GL coding patterns and line item analysis - Accrual tracking and transaction date analysis - Audit trail support across accounting records Legal Entity Analysis - Spending patterns by legal entity and country - Cross-entity comparisons of expense volumes and types - Entity-level employee and department activity - Multi-entity approval and compliance rates Organizational Analytics - Employee expense patterns and rankings (top spenders per department/category) - Department-wise spending breakdowns and comparisons - Manager-employee expense relationships and reporting hierarchies - Location-based expense analysis - User-level metrics including approval ratios and compliance rates Vendor & Merchant Analysis - Top vendors/merchants by spend volume or transaction count - Vendor performance tracking and quarterly/monthly trends - Identify recurring vs. one-time vendor relationships - Categorize SaaS vs. non-SaaS vendor spend - Maximum spend tracking per vendor Card Management & Transaction Analysis - Card inventory: active, terminated, suspended, virtual, physical - Card issuance tracking and activation rates - Card-level spending patterns and transaction volumes - Card purpose analysis (travel, office, etc.) - Cardholder administration and card lifecycle management - Per-card receipt attachment and compliance rates Operational Reporting - Pending approval workflows and manager review queues - Reimbursement tracking and payout status - Disputed transactions by user or time period - Transaction settlement status and payment processing - Card vs. reimbursement expense comparisons Available Data The tool has access to 14 specialized analytical views: - Spending Analysis: Core expense metrics, temporal trends, and multi-currency breakdowns across employees, departments, and categories - Top Spenders: Employee-level spending rankings with approval rates, vendor counts, and expense type breakdowns - Vendor Analysis: Vendor spending patterns, SaaS categorization, and merchant-category insights - Card Transaction Analysis: Card-level transaction details, daily totals, and per-card spending metrics - Card Spending Analysis: Financial analysis of card utilization, transaction volumes, and ROI by card type and purpose - Card Management: Card inventory and lifecycle tracking — issuance, activation, termination, and cardholder administration - Compliance and Approval: Policy adherence monitoring, approval workflows, receipt compliance, and audit support - Budget Management: Budget performance tracking, spend limits, over-budget identification, and budget lifecycle management - Budget Limit Increases: Limit increase approval patterns, permanent vs. temporary increases, and voiding analysis - Budget User Associations: Budget membership analysis — owners, members, and employee-budget relationships - Disputes and Repayments: Disputed transaction (clawback) analysis, repayment patterns, and refund tracking - Accounting Journal: Double-entry accounting records, reconciliation, and audit trail analysis - GL Coding Analysis: General Ledger code mapping to expenses, vendors, and departments - Legal Entity Spending: Multi-entity and multi-country spending comparisons and organizational breakdowns Expense Types Supported - CARD: Corporate card transactions - REIMBURSEMENT: Employee reimbursements - BILLPAY: Vendor bill payments - CLAWBACK: Reversed or recovered expenses Example Queries Financial Analytics 1. "What was our total spending on travel expenses in Q4 2025?" 2. "Show me the top 10 vendors by spend last month" 3. "How much did the Engineering department spend on software purchases?" 4. "Compare our card spending between December and January" 5. "What are the largest transactions over $10,000 this quarter?" 6. "Show me spending trends over the last 6 months" 7. "What's our average expense amount by category?" Compliance & Policy 8. "Which employees have the most transactions missing receipts?" 9. "Show me all manually approved expenses without documentation" 10. "List expenses that are out of policy this month" 11. "What's our receipt compliance rate by department?" Budget & Spend Limits 12. "Which departments are most over budget by percentage?" 13. "Show me budget utilization for all departments" 14. "What budgets were recently created or edited?" 15. "What's the spend limit utilization for the Engineering team?" Organizational 16. "Who are the top 5 spenders in the Engineering department?" 17. "Show me employee expense patterns by manager" 18. "Which users have the most spend per merchant category?" Vendor Analysis 19. "Show me all recurring SaaS vendor spend from highest to lowest" 20. "What are our top non-SaaS vendors by spend?" 21. "Compare vendor spend quarter over quarter" Operational 22. "Which managers have the most expenses pending their review?" 23. "Show me all disputed transactions this year by user" 24. "What's the status of pending reimbursements?" Card Management 25. "How many active virtual cards do we have?" 26. "What's our card activation rate this quarter?" 27. "Show me spending by card purpose (travel vs. office)" Disputes & Repayments 28. "Show me all disputed transactions this year by user" 29. "What's the trend in clawbacks over the past 6 months?" Accounting & GL 30. "Show me GL code usage across departments" 31. "Which GL codes have the highest expense volumes?" 32. "List accounting journal entries for last month" Legal Entity 33. "Compare spending across our legal entities" 34. "Which countries have the highest expense volumes?" Example Input { "question": "What was our total spending on travel expenses in Q4 2025?" } Example Output { "answer": "Your total spending on travel expenses in Q4 2025 was $125,450.32. Here's the breakdown by month: October: $38,200, November: $42,150, December: $45,100. The top categories were flights (45%), hotels (35%), and ground transportation (20%).", "metadata": { "toolCalls": [ { "name": "query_expenses", "input": {...}, "result": {...} } ] } } Response Format - answer (string): A natural language response to your question with the requested analytics - metadata (object): Contains diagnostic information including: - toolCalls: Array of internal tool calls made to generate the answer, useful for debugging When to Use This Tool ✅ USE this tool for: - Any aggregate analytics or reporting questions - Compliance, policy, and audit queries - Budget tracking and spend limit monitoring - Top N rankings (top spenders, vendors, categories) - Trend analysis and comparisons - Statistical analysis (averages, outliers, anomalies) - Operational reporting (pending reviews, approvals, disputes) - Card inventory and lifecycle management questions - Dispute and clawback analysis - GL coding and accounting journal queries - Legal entity and multi-country spending analysis - Multi-dimensional analysis (department + category, user + time period) ❌ DO NOT use this tool for: - Looking up a specific expense by ID (use get_expense_by_id instead) - Fetching a user's own expenses (use list_expenses with expense_owner: "ME" instead) - Fetching expenses for specific users by ID (use list_expenses with user_ids instead) - Questions like "show me my expenses", "what did I spend on", "my recent transactions" — always use list_expenses for these - Retrieving a specific card by ID (use get_card_by_id instead) - Non-financial queries unrelated to expenses

replace_attendees_for_card_expense

ChatGPT
Update attendees for a card expense. This tool allows you to update both external and internal attendees to any card expense. Note: This tool will replace the existing attendees with the new attendees provided. Parameters: - card_expense_id: The ID of the card expense to add attendees to - external_attendees: Array of external attendees (people outside the company with different email domains) - internal_attendees: Array of internal attendee IDs (company employees by customer user ID) Internal vs External Attendees: - Internal attendees: Company employees with the SAME email domain as the current user (e.g., @acmecorp.com) → These require a user ID lookup using list_users_by_name_or_email - External attendees: People from OTHER companies with DIFFERENT email domains (e.g., @vendorco.com) → These can be added directly with just their name, title, and company info (no user ID needed) Example workflow - Adding both internal and external attendees: Scenario: Current user is bob.wilson@acmecorp.com adding a business dinner expense with: - Jane Doe (jane.doe@acmecorp.com) - internal colleague (SAME @acmecorp.com domain) - John Smith (john.smith@vendorco.com) - external vendor (DIFFERENT @vendorco.com domain) Step 1: Identify which attendees are internal vs external by comparing email domains - Current user: bob.wilson@acmecorp.com - jane.doe@acmecorp.com → SAME @acmecorp.com domain → internal attendee → needs user ID lookup - john.smith@vendorco.com → DIFFERENT @vendorco.com domain → external attendee → add directly Step 2: Find the internal user ID using list_users_by_name_or_email Input to list_users_by_name_or_email: { "search_text": "jane.doe@acmecorp.com" } Response from list_users_by_name_or_email: { "items": [ { "id": "user_456", "firstName": "Jane", "lastName": "Doe", "email": "jane.doe@acmecorp.com", ... } ], "next_cursor": null } Step 3: Add both internal and external attendees to the expense Input to replace_attendees_for_card_expense: { "card_expense_id": "card_exp_123", "external_attendees": [ { "name": "John Smith", "title": "Account Manager", "company_name": "VendorCo", "is_government_official": false } ], "internal_attendees": [ "user_456" ] }

replace_card

ChatGPT
Replace or reissue a card through a mandatory preview followed by confirmed execution. This is destructive and cannot be undone. The first call MUST omit preview_request_fingerprint and idempotency_key. It returns the exact replacement preview and makes no changes. Keep this preview step invisible to the operator: do not announce that you will preview, run a preflight, load schemas, or call tools. After resolving the card, ask directly for any missing replacement form or any reason you cannot infer confidently. — Scope and routing — - Employee cards and purchasing cards may be replaced with either a physical or virtual card. Every other card category preserves its current form. - A phrase such as "replace my physical card" identifies the existing card; it does not choose the replacement form. Only treat the form as selected when the operator explicitly describes the replacement, such as "replace it with a physical card." - To issue a physical counterpart of a usable virtual card without replacing its credentials, use ship_physical_card instead. Use this replacement flow when the existing card is damaged, compromised, missing, or otherwise needs replacement. - For a temporarily misplaced card, use lock_card. For permanent retirement without a replacement, use cancel_card. To change the cardholder, use transfer_card. - Lost, not-received, and fraud reasons force a new card number. Damaged and other reasons keep the same number by default when the selected card format supports reissue. Keep account-updater behavior internal; never mention or predict it when speaking to the operator. - Treat a stolen card, skimmed or leaked details, or unauthorized charges as fraud. Treat a card as lost only when a physical card is missing with no evidence of compromise. Lost, damaged, and delivery-issue reasons apply only to physical cards. - Expiration reissue exists in other Brex surfaces but is intentionally excluded from this new-number MCP tool; direct the operator to the Brex dashboard. — Prepare the preview — 1. Use list_cards or get_card_by_id to resolve the exact card, then use get_card_by_id to inspect card_category and the current cardholder. Trust the returned user field for the current cardholder, not holder_name. - Brex does not designate a primary card. If the operator asks for their primary card, say that plainly, present matching active cards in customer-facing language, and ask which one they mean. - Never show raw values such as EMPLOYEE_CARD, SPEND_LIMIT_CARD, or TERMINATED. Say "employee card," "spend-limit card," and "canceled." - During resolution, never show amount spent or available. If an amount is needed to disambiguate cards, show only the configured total and reset frequency. 2. If card_category is EMPLOYEE_CARD or PURCHASING_CARD and the operator has not explicitly chosen the replacement form, ask whether the replacement should be physical or virtual and wait. Do not infer it from the existing card's form. Pass the answer as replacement_card_form. For every other category, do not ask; omit replacement_card_form so the current form is preserved. 3. Choose an explicit reason. Infer it when the operator's words are unambiguous: stolen, skimmed/leaked details, or unauthorized charges mean FRAUD; a missing physical card with no evidence of compromise means LOST; a damaged physical card means DAMAGED; and a card that never arrived means NOT_RECEIVED. Ask only when more than one reason is plausible or confidence is low. For OTHER, collect a nonblank explanation of at most 255 characters and preserve the operator's words after trimming. Never expand it into an internal rationale or mention MCP/tool names. 4. If the replacement will be physical, either reuse the complete address on file or verify an override with verify_shipping_address. Overrides must use the deliverable, non-PO-box suggestion. 5. Call this tool. Never narrate request fingerprints or call this a "revised request." — Present the result — Mirror the Brex Dashboard replacement drawer with short section headings and label-value bullets, not a Markdown tabl…

ship_physical_card

ChatGPT
Issue and ship the PHYSICAL version of a virtual card, keeping the same card number. — Resolve and prepare — 1. Use list_cards with card_form: ["VIRTUAL"] to resolve the exact card and current cardholder from user, not holder_name. The tool rejects cards that are already physical or are not eligible for physical issuance. 2. Before asking the operator for an address, suggest the current cardholder's latest past physical-card destination: - Call list_cards with user_ids: [current_cardholder_id], card_form: ["PHYSICAL"], sort: "ISSUED_AT", direction: "desc", limit: 1, and no status filter so the latest physical card is returned even if it is terminated or expired. - Call get_card_by_id on that latest card. - Suggest that exact recipient name and shipping_address. Never use the caller/operator's card history unless they are the current cardholder. If the latest physical card has no complete shipping_address, ask for one. 3. Use verify_shipping_address on the suggested or operator-provided destination. A PO box is always blocked. For a deliverable result, use the confirmed suggestion. For an undeliverable non-PO-box result, warn the operator and proceed with the original address only after they explicitly confirm shipping there anyway. 4. Apply Dashboard shipping policy using the current cardholder, never the caller/operator. Omit shipping_method for automatic/default shipping. Eligible US card-manager cardholders receive expedited shipping automatically. A regular-default cardholder may explicitly request expedited shipping for a US destination; expedited shipping is unavailable outside the US. 5. Generate one fresh idempotency_key for this logical issuance. Reuse that exact key only when retrying the exact operation. — Confirmation gate (REQUIRED before every initial issuance) — On a separate turn, recap the exact virtual card, current cardholder, exact destination, and resolved shipping behavior. For an undeliverable non-PO-box address, explicitly state that deliverability could not be verified and shipping may fail. State that the physical card keeps the same number, receives a new expiration date and CVV, and must be activated for physical use. Ask one yes/no consent question and wait. — Uncertain failures — This tool is not replay-safe after a successful issuance because the card is no longer virtual. Never blindly retry. Inspect the card first: if it is now physical, report success without retrying; only if it is still virtual may you retry the exact operation with the same idempotency_key. If the user asks for an estimated delivery date, inform them that shipping instructions and delivery follow-up will be sent by email. If the operator needs a new card number, use replace_card instead. Eligible employee cards and purchasing cards can request a physical replacement with a new number. If the operator wants to reissue an already-physical card while keeping its number, direct them to the Brex dashboard; this tool accepts virtual cards only. After every successful physical-card order, show this delivery summary. Every line is required, including the digital-card line: it tells the operator the card is usable right now, so never drop it to keep the reply short. - "Physical card ordered." - "{first name} can use the corresponding digital card online and with Apple Pay/Google Pay in the meantime." - "They can view and manage their cards on their Brex Wallet page or mobile app." - "Card and shipping details" - Cardholder: {full name} - Shipping to: {persisted shipping address} - Estimated delivery: {start}-{end} days - "Estimate subject to change until order ships" Use only values returned by the tool. Omit an unavailable estimate instead of inventing one. Example input shape: { "card_id": "card_abc123", "shipping": { "first_name": "Joao", "last_name": "Barros", "address": { "address1": "1 Market St", "address2": "Suite 400", "city": "San Francisco", "state": "CA", "zip": "94105", "country": "US" } }, "idempotency_key": "2bb6f9e7-55f2-4ec9-bf0e-02a2e853e475" } SPEND TERMINOLOGY: - Spend limits are spending controls that exis…

start_expense_download

ChatGPT
Start an asynchronous expense download job. Returns a job ID immediately. IMPORTANT: Download jobs can take up to 5 minutes to complete. Use get_expense_download_result with the returned job_id to poll for completion. Recommended polling strategy: - Poll 5s after starting - If PROCESSING, wait 10 seconds and poll again - Continue with 10-second intervals until COMPLETED or FAILED - Maximum expected duration: 5 minutes Parameters: - start_date (required): Start of date range (ISO 8601, UTC) - end_date (required): End of date range (ISO 8601, UTC) - expense_types (optional): Filter by expense types: CARD, REIMBURSEMENT, BILLPAY, CLAWBACK - statuses (optional): Filter by statuses: APPROVED, CANCELED, OUT_OF_POLICY, SETTLED, SUBMITTED - user_ids (optional): Filter by specific user IDs - min_amount (optional): Minimum expense amount (USD) - max_amount (optional): Maximum expense amount (USD) The CSV includes 15 columns: Parent ID, Flagged Expenses, Transaction Date, Expense Type, Card Last 4, Amount, Currency, Original Amount, Original Currency, Merchant Name, User, Budget Name, Memo, Expense Status, Payment Status. IMPORTANT: This tool is only useful if your client environment can download files from URLs. The completed export provides a download URL for the CSV file. If you cannot download files (e.g., you are in a plain chat session without filesystem access), this tool will not help — use list_expenses with pagination instead. When to prefer this over list_expenses: - The dataset has 50+ expenses and the task involves aggregation, analysis, or bulk processing - Your environment can download files AND run scripts to process the CSV locally (e.g., pandas, awk, shell commands) - This avoids loading all expense data into the conversation context If you are unsure whether you can download files from the returned URL, ask the user before starting the export. Example: Start export for Q1 2025: { "start_date": "2025-01-01T00:00:00.000Z", "end_date": "2025-03-31T23:59:59.999Z" }

submit_feedback

ChatGPT
Submit feedback about the Brex API or MCP tools to the Brex product team on behalf of the user. This feedback is reviewed by the product team and used to prioritize improvements. WHEN TO USE THIS TOOL: - When a tool cannot fulfill the user's request due to missing functionality or unsupported filters. Example: User asks to filter expenses by custom field, but list_expenses doesn't support that filter. -> submit_feedback with type "limitation" and describe the missing filter capability. - When list or query tools return empty or unhelpful results for a reasonable request. Example: User asks "show me spend by department last quarter" but no tool supports that aggregation. -> submit_feedback with type "limitation" describing the analytics gap. - When the user explicitly asks to share a suggestion or report a problem with Brex tools. - When a tool returns an error indicating a platform limitation (not a user input error). Example: "This operation is not supported for this card type." -> submit_feedback with type "bug" including the error message and context. - When accomplishing a task requires an unreasonably complex sequence of tool calls that could be simplified. Example: Getting a budget summary requires 4 separate API calls that could be one. -> submit_feedback with type "suggestion" describing the desired simplified workflow. WHEN NOT TO USE: - Authentication or permission errors - help the user fix their token or scopes instead. - Invalid input errors - help the user correct their input. - Transient errors - retry the original tool first. - The user has not expressed frustration or a gap - do not submit feedback proactively without cause. IMPORTANT: Always inform the user before submitting feedback. Briefly explain what you're reporting and why.

transfer_card

ChatGPT
Reassign an existing card to a different cardholder, keeping the same card number. Use this when a card should change hands — an employee is offboarding and their vendor subscriptions must keep running, or a card is simply being handed to whoever now owns that spend. If any of these are true, this tool is NOT to be called. Recommend the alternative and stop. - Operator wants the new holder to have their OWN new card → use create_purchasing_card / create_employee_card. - Operator wants to stop the card working rather than move it → use cancel_card (permanent) or lock_card (reversible). - Operator wants to replace a lost or compromised card with a new number → use replace_card. - Operator wants to change the card's limit, name, policy, or controls → use update_purchasing_card / update_employee_card. - Operator wants to attach a Spend Limit or User Limit to the card → use assign_limit_to_card. — Resolving BOTH sides before you call — This is a two-party operation and needs a resolved card ID and a resolved user ID. 1. The card: if named by vendor / display name / last4 ("transfer the Figma card"), call list_cards FIRST. Read the CURRENT holder from the user field — NEVER holder_name, which is the name embossed at issuance and is stale on any card that has already been transferred. 2. The new cardholder: if named by name or email, resolve with list_users with search_text. If it returns MORE THAN ONE match, present the candidates (name, email, department) and ask which person — never guess, and never pick the first. Transferring a live card to the wrong person hands them someone else's spending power. If either side is ambiguous, resolve it with the operator before calling. — What a transfer does, and what to warn the operator about — The card number, expiry, and last4 do not change, so vendor subscriptions billed to it keep working. Spend from the transfer onward is attributed to the new holder; past transactions stay with the previous holder. The card keeps the spending controls it already had, and the new holder inherits them — they do not get a fresh allowance. Critically, for a non-company card, transfer turns ON merchant restrictions: afterwards the card only authorizes at online merchants where it has ALREADY been used, and everything else — including all in-person transactions — declines until an admin lifts the restrictions. Whenever the result reports that, tell the operator in prose — describe the behaviour and its consequence, never the field name or a key: value pair. It is the most common post-transfer surprise. Do not describe a transfer as easily undone: returning a card re-checks the ORIGINAL holder's card access, which they may no longer have, so a transfer can be one-way in practice. — What cannot be transferred — Only an active card. A cancelled, expired, locked, or not-yet-activated card, a card being replaced, and a card whose spending controls are no longer active are all rejected. A card that has never been used online cannot be transferred either (a security rule — there is no established merchant footprint to restrict it to). The new holder must be an active user on the same Brex account and must already have the card access that matches the card's type; if they don't, the transfer is rejected and someone must enable it on the Teams page first. Transferring a card to the person who already holds it is reported as "no action taken" rather than an error. — Reason — Use EMPLOYEE_OFFBOARDED when the current holder is leaving the company. Otherwise OTHER (the default). The reason is recorded for audit and does not change what the transfer does. — Confirmation gate (REQUIRED, do this before EVERY call) — 1. Present BOTH sides of the transfer and its consequences. The operator must be able to see they are moving the right card to the right person. Suggested format: You're transferring: <display name> (last 4: <last4>) From: <current holder> → To: <new holder> The card number stays the same, so subscriptions billed to it keep working. Spend from now on is attributed to <new holder>. 2. Ask a yes/no quest…

unlock_card

ChatGPT
Lift a lock, allowing new transactions again. Unlocking sends no notification to the cardholder (locking does — an email and SMS). Unlocking reverses a lock; it does not activate a card. A card that was locked before it had ever been activated comes back awaiting activation, and still has to be activated before it can be used — tell the operator so when the response says so, rather than reporting the card as ready to spend. If any of these are true, this tool is NOT to be called. Recommend the alternative and stop. - The card is already active → calling this tool again is a harmless no-op; it will report that nothing changed rather than erroring. - The card is not currently locked (e.g. expired, cancelled) → unlocking is rejected locally. — Resolving the card — If the operator names it by vendor / display name / last4, call list_cards FIRST. Read the current holder from the user field, not holder_name. — Unlock blockers to relay, not retry — An unlock call can fail for reasons that will NOT change on a blind retry — relay these to the operator instead of calling the tool again: - The card was locked by an admin: only an admin can unlock it, and the cardholder cannot reverse it even on their own card. This is rejected before any mutation is attempted. Tell the operator plainly that they cannot undo this themselves, and that the next step is to ask an admin at their company to unlock it. Do NOT offer a replacement or newly issued card as a way around it — an admin lock is usually deliberate (offboarding, suspected fraud, a policy hold), so routing around it is the wrong move. - The card is under an open fraud/compliance review: it stays locked until that review closes, regardless of who is asking. Same guidance — the operator waits for the review, they cannot unlock their way out of it. - The card's spending controls are no longer active (e.g. the period they were set up for has ended): an admin has to restore them before the card can be unlocked. Say what the operator has to do; do not explain how Brex records it. — Confirmation gate (REQUIRED, do this before EVERY call) — 0. A lock is usually deliberate — offboarding, suspected fraud, a policy hold. If the operator has not said why the card should be spendable again, ask before you recap. Restoring spend on a card someone locked on purpose is what this gate exists to prevent, and "the operator asked me to" is not a reason. 1. Present the card being unlocked and what unlocking means. Suggested format: You're unlocking: <display name> (last 4: <last4>), held by <cardholder> The card can be used for new transactions again as soon as this goes through, and <cardholder> will not be notified that it is live. 2. Ask a yes/no question whose ONLY purpose is consent. Wait for the answer. 3. Treat answers to clarifying questions (which card) as INPUTS, not consent. The yes/no is a separate, dedicated turn. 4. Only after an explicit yes do you emit the unlock_card tool call. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type…

update_employee_card

ChatGPT
Update an existing employee card's monthly limit amount. This tool only changes the limit amount, in the limit's existing currency — an employee card has no other user-editable fields, and a limit's currency cannot be changed once it exists. If any of these are true, this tool is NOT to be called. Recommend the alternative and stop. - Operator wants to create a NEW employee card → use create_employee_card instead. - Operator wants to change WHO holds the card (cardholder reassignment) → use transfer_card. - Operator wants to change the limit's currency, temporarily increase limit, rename the card, change its expense policy, or change limit recurrence away from monthly → not supported by this tool or by employee card limits at all. Recommend the Brex dashboard. - Operator wants to cancel/terminate the card → use cancel_card. - Operator wants to lock or unlock the card → use lock_card / unlock_card. - Operator wants to attach a separate Spend Limit or User Limit to the card → use assign_limit_to_card. SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. GLOBAL USER-FACING RULES — apply to EVERY message you send the operator. Everything in this description is internal contract. It is here so you can reason and build a correct call; none of it belongs in a reply. - Never show wire values. Statuses, reasons, card categories, card forms, reset frequencies and limit flexibilities are internal codes: say "locked", "cancelled", "a virtual card", "monthly", "up to 10% over the limit". - Never show request or response FIELD NAMES, and never use field: value form. Describe what the operator will observe, in prose. - Never show internal IDs (card, user, policy, limit). Name objects by display name only, e.g. "Tony Report", "Default Policy". - Never name tools or internal steps: no "list_cards", "duplicate check", "preflight", "tool call". - Never volunteer how Brex records a card action internally. The spend limits, budgets and other bookkeeping behind locking, cancelling, transferring or issuing a card are implementation, not product: describe only what the operator will observe. Spend limits ARE a product the operator can be offered in their own right — the rule is about not explaining a card action in terms of them. - Any examples below use wire vocabulary deliberately, because they show the shape of a call. Copy their structure, never their vocabulary. - Before creating, always show the final proposed setup and ask a yes/no confirmation. - Answers to missing-field questions are inputs, not confirmation to create. — Definitions — Employee cards What it is: Employee cards are for employee T&E and incidental spend. They can be physical or virtual and can be used with employee card limits / spend limits. Best for: Individual employee-driven spend where the employee needs general access to funds for travel, meals, or other incidental business expenses. Not best for: Recurring vendor subscriptions…

update_expense_memo

ChatGPT
Update memo for multiple expenses in bulk. All expenses will receive the same memo. Parameters: - expense_ids: Array of expense IDs to update - memo: The memo text to apply to all expenses Example (single expense): { "expense_ids": ["exp_123"], "memo": "Business lunch with client" } Example (multiple expenses with same memo): { "expense_ids": ["exp_123", "exp_456", "exp_789"], "memo": "Q1 team building event" }

update_purchasing_card

ChatGPT
Update an existing purchasing card (P-Card). Most common edit is raising or lowering the spending limit; also supports changing the card's display name, description, expense policy, limit reset frequency, limit enforcement (hard limit / percentage-based flexibility / unlimited), per-transaction maximum, validity window (start/end date), billing legal entity, merchant category controls, auto-transfer behavior, and who can spend on the card. Partial-update semantics — only the fields you pass are changed; everything else is preserved. The one exception is authorized_users, which replaces access outright rather than merging into it. If any of these are true, this tool is NOT to be called. Recommend the alternative and stop. - Operator wants to change WHO holds the card (cardholder reassignment) → use transfer_card. - Operator wants to cancel/terminate the card → use cancel_card. - Operator wants to lock or unlock the card → use lock_card / unlock_card. - Operator wants to attach a Spend Limit or User Limit to the card (not edit the card's own base limit) → use assign_limit_to_card. Terminology: when a card's status is TERMINATED, call it "cancelled" in messages to the operator (TERMINATED stays the value you pass to status filters). — Resolving the card ID — The card ID is required. If the operator names a card by vendor / display name / last4 ("change the Figma limit", "raise the card ending 2836 to $10k"), call list_cards FIRST and find the match. If list_cards returns more than one candidate (e.g. two "Figma" cards), present the candidates (display name, last4, current limit, cardholder) and ask the operator which one. Proceed only with an exact ID match. — Partial-update behavior — Only pass fields the operator explicitly asked to change. A missing or null field means "leave unchanged." Do NOT echo the current values back into the call that complicates the audit trail. base_limit_amount changes the limit in the card's existing currency; a card's limit currency cannot be changed. — Changing the limit amount and its cadence — A limit the operator states with a cadence sets BOTH fields: "$10,000 a month" is base_limit_amount 10000 AND limit_reset_frequency PER_MONTH. Sending the amount alone leaves the card on its previous cadence, which this tool does not read back — so a weekly card silently becomes $10,000 every week, and you have no way to notice. Send base_limit_amount alone only for a bare amount ("raise it to $10k"), which deliberately preserves the existing cadence. Never tell the operator a limit is monthly (or weekly, or annual) in a call where you did not send limit_reset_frequency. — Changing limit flexibility — This tool does NOT default limit_flexibility the way create_purchasing_card does — omitting it preserves whatever the card already has. Map operator intent: "block spend over the limit" / "make it strict" → hard limit; "allow a little over" / "give it some room" → the standard 10% P-Card cushion (also the dashboard default); "stop enforcing the limit" → unlimited. A 5% or 25% cushion is available for a smaller or bigger buffer; those five presets are exactly what the dashboard offers, so if the operator names another percentage ("allow 20% over"), say 5%, 10%, and 25% are the available cushions and offer the nearest one rather than silently rounding. Each preset carries its own cushion, so switching to hard limit or unlimited clears any existing buffer. list_cards does not return the card's current flexibility, so present the change as the new value only — never state a "from <current>" you cannot see. Word each preset to the operator as "flexible, up to 25% over the limit", the way the Scenario D recap below does. — Changing the validity window — start_date / end_date bound when the card can spend, as calendar dates only (YYYY-MM-DD) — there is no time of day and no timezone, so never send one. Pass only the side the operator asked to change; the other side stays as it is. end_date is the first day the card can NO LONGER spend, so translate inclusive wording before calling ("kill it after March 31" → e…

upload_card_expense_receipt_from_urls

ChatGPT
Upload receipts to a card expense by downloading them from provided URLs. This tool downloads receipts from the given URLs and uploads them to the specified card expense. Parameters: - expense_id: The ID of the card expense to attach the receipts to - receipt_urls: Array of URLs where receipts can be downloaded (must be publicly accessible) Example: { "expense_id": "card_exp_123", "receipt_urls": [ "https://example.com/receipts/lunch_receipt.jpg", "https://example.com/receipts/lunch_receipt_page2.pdf" ] }

verify_shipping_address

ChatGPT
Validate a shipping address AND return the corrected/standardized version, before shipping a physical card. This calls the same address-verification service the Brex dashboard uses when ordering physical cards. It does two things: 1. Reports whether the address is deliverable (is_deliverable) and whether it is a PO box (is_po_box). 2. Returns a standardized "suggestion" — the cleaned-up address (proper casing, USPS abbreviations, city/state corrected from the ZIP, ZIP+4 added). How to use the result: - If is_po_box is true, do NOT proceed. Cards cannot ship to PO boxes; ask for a street address and verify it. - If is_deliverable is true, present the "suggestion" to the user to confirm. The confirmed suggestion is the canonical address to use when shipping the card. - If is_deliverable is false and is_po_box is false, warn that deliverability could not be verified, present the original address exactly, and ask whether to ship there anyway. Proceed with the original address only after explicit confirmation; otherwise ask for a corrected address and verify it. This is the required first step before shipping a physical employee card. Example input shape: { "address": { "address1": "1 market st", "address2": "ste 400", "city": "san francisco", "state": "ca", "zip": "94105", "country": "US" } } SPEND TERMINOLOGY: - Spend limits are spending controls that exist independently of cards and can be assigned to expenses. - Employee card limits (USER_LIMIT in tool results) are personal limits used by employee cards. An employee card is the card itself, not its limit; employee cards can also use separately issued spend limits. - Budgets are separate planning/tracking containers that can contain spend limits and other budgets. A containing Budget is not the expense's assigned spend limit. budget_path describes visible containing budgets. - Spend limit groups are templates giving each eligible member their own spend limit, not shared funds. A group is neither a spend limit nor a Budget; its parent_budget is its containing Budget. - If a user says "budget", use the conversation and returned object types/path to distinguish a spend limit from a containing Budget. If the distinction remains ambiguous and changes the answer, ask which they mean; do not silently substitute one for the other. - Use these product names in replies. Field names and ID prefixes such as budget_* do not establish the object's product type. Use returned IDs unchanged for tool calls and identify objects by name in replies. GLOBAL USER-FACING RULES — apply to EVERY message you send the operator. Everything in this description is internal contract. It is here so you can reason and build a correct call; none of it belongs in a reply. - Never show wire values. Statuses, reasons, card categories, card forms, reset frequencies and limit flexibilities are internal codes: say "locked", "cancelled", "a virtual card", "monthly", "up to 10% over the limit". - Never show request or response FIELD NAMES, and never use field: value form. Describe what the operator will observe, in prose. - Never show internal IDs (card, user, policy, limit). Name objects by display name only, e.g. "Tony Report", "Default Policy". - Never name tools or internal steps: no "list_cards", "duplicate check", "preflight", "tool call". - Never volunteer how Brex records a card action internally. The spend limits, budgets and other bookkeeping behind locking, cancelling, transferring or issuing a card are implementation, not product: describe only what the operator will observe. Spend limits ARE a product the operator can be offered in their own right — the rule is about not explaining a card action in terms of them. - Any examples below use wire vocabulary deliberately, because they show the shape of a call. Copy their structure, never their vocabulary.

get_card_by_id

Claude

get_expense_policy

Claude

get_reimbursement_payout_date

Claude

get_user_by_id

Claude

get_user_myself

Claude

list_my_cards

Claude

list_my_expenses

Claude

list_my_limits

Claude

list_users

Claude

list_users_by_name_or_email

Claude

App Stats

74

Tools

1

Prompts

ChatGPT, Claude

Platforms

Works with

ChatGPT
Claude

Data refreshed daily