Connect Navan to AI Agents: Access Traveler Identity and Profiles
Learn how to connect Navan to AI agents using Truto's tools endpoint. This step-by-step guide covers handling rate limits, SCIM caveats, and LLM tool calling.
You want to connect Navan to an AI agent so your system can autonomously read traveler profiles, audit active bookings, manage cost centers, and reconcile expense reports. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to build and maintain a custom Navan integration from scratch.
Corporate travel and expense data is highly sensitive and tightly coupled to your organization's human resources directory. Giving a Large Language Model (LLM) read and write access to your Navan instance means it cannot afford to hallucinate API payloads or guess at pagination cursors. If your team uses ChatGPT, check out our guide on connecting Navan to ChatGPT, or if you are building on Anthropic's models, read our guide to connecting Navan to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them to your agent framework.
This guide breaks down exactly how to fetch AI-ready tools for Navan, bind them natively to an LLM using frameworks like LangChain, LangGraph, CrewAI, or the Vercel AI SDK, and execute complex travel operations workflows. For a broader look at this design pattern, read our guide on architecting AI agents and the SaaS integration bottleneck.
Why a Unified Tool Layer Matters for Agent Safety
Before writing a line of integration code, decide what layer your agent talks to. This choice determines how safe your production system will be.
Direct API tools - writing one Python or TypeScript function per raw Navan endpoint - look convenient in a local prototype. But this approach pushes provider-specific quirks directly into the LLM's context window. The model has to remember that Navan uses specific UUID formats for cost centers, handles pagination via specific cursors, and requires strict JSON shapes for expense items. Every one of those quirks is a hallucination waiting to happen.
Abstracting the underlying API behind a standardized tool layer collapses these complexities. Your agent interacts with highly constrained, descriptive tools. That gives you concrete safety wins:
- Smaller attack surface for hallucination. The LLM only ever chooses from a stable list of function names with heavily documented parameter descriptions.
- Deterministic input validation. Every tool has a strict JSON schema. Invalid arguments are rejected by the proxy layer before they hit the upstream Navan API, so a broken tool call fails fast instead of generating silent errors or corrupted expense data.
The Engineering Reality of the Navan API
Giving an AI Agent access to external data sounds simple until you hit the reality of enterprise SaaS APIs. Navan introduces specific integration challenges that break standard REST assumptions. If you hardcode these interactions into your agent, you will spend your sprints writing defensive integration code instead of improving your model's reasoning.
Entitlement-Gated User Endpoints (The 403 Trap)
Navan strictly controls access to user identity data based on the type of partner or customer integration. A standard developer creating self-serve Navan API credentials from the Travel > Settings > Integrations dashboard will quickly discover that calling the primary user directory endpoints results in a HTTP 403 Forbidden error.
Navan gates user data behind a specific partner/TMC (Travel Management Company) entitlement that standard credentials do not carry. To reliably grant an AI Agent access to the Navan user directory, you cannot rely on the standard REST API user list. Instead, you must connect the Navan SCIM integration (navanscim) to handle identity provisioning and directory lookups. If you fail to separate your agent's identity logic from its travel logic, your agent will constantly crash on 403 errors when trying to resolve a traveler's ID.
Strict Cost Center and Department Mapping
When an AI Agent attempts to update a user's profile or reassign an expense, it naturally wants to pass human-readable strings like "Engineering" or "Q3 Marketing Budget". Navan will reject this. The API requires strict mapping to internal UUIDs for Cost Centers, Departments, and Regions. Your agent must be equipped with the tools to first query the Cost Center directory, extract the correct UUID, and inject that UUID into the subsequent update payload. This requires multi-step reasoning capabilities and flawless state management.
Transparent Rate Limit Handling
When you unleash an autonomous agent on an API, it can generate hundreds of requests in seconds while paginating through historical expense reports. Navan enforces strict rate limits to protect its infrastructure.
Truto normalizes upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. However, Truto does not automatically retry, throttle, or apply backoff on rate limit errors (see our guide on handling third-party rate limits). When Navan returns a HTTP 429 Too Many Requests, Truto passes that 429 error directly back to the caller.
Your AI Agent framework is entirely responsible for catching this 429 error, reading the ratelimit-reset header, pausing execution, and retrying the tool call. Failing to implement this backoff logic will cause your agent to enter a death spiral of failed tool calls.
Hero Tools for Navan AI Agents integration
Truto's Proxy APIs expose Navan's resources as callable tools with baked-in JSON schemas. You do not need to write these schemas yourself. Below are the highest-leverage hero tools for building Navan automation AI Agents.
list_all_navan_users
Retrieves a list of users from the Navan directory. Crucial Note: Navan gates user data behind a partner/TMC entitlement that self-serve Navan API Credentials do not carry. If you use standard credentials, this method returns a 403. For user directory lookups, connect the Navan SCIM integration (navanscim) instead and use the SCIM-equivalent tool.
"Fetch the user directory to find the internal ID for Sarah Connor in the Engineering department."
get_traveler_profile
Fetches the specific travel preferences, loyalty programs, and policy limits for a single traveler using their Navan User ID. Essential for agents that need to audit if an upcoming booking violates a user's specific tier limits.
"Retrieve the traveler profile for user ID 8f72a-9b1c to check their maximum allowable nightly hotel rate."
list_cost_centers
Queries the active cost centers configured in the Navan workspace. Agents must use this tool to map human-readable department names to the required UUIDs before submitting expenses or moving users.
"List all cost centers and find the UUID associated with the 'Q4 EMEA Expansion' budget."
update_user_cost_center
Updates a user's profile to assign them to a new primary cost center. This is highly useful for autonomous HR onboarding or department transfer workflows.
"Update the profile for user ID 8f72a-9b1c, changing their cost center to UUID 112233-4455."
get_active_bookings
Retrieves all upcoming or currently active flight, hotel, and rail bookings for a specific user. This tool allows agents to autonomously cross-reference travel schedules with external calendars.
"Get all active bookings for user ID 8f72a-9b1c departing between October 1st and October 15th."
create_expense_report
Submits a new expense payload into Navan on behalf of a user. The agent must construct a strict JSON payload including the transaction amount, currency, merchant, and the associated cost center UUID.
"Create an expense report for user ID 8f72a-9b1c for $45.00 at Starbucks, assigned to the Sales cost center UUID."
To view the complete schema definitions and the full list of available tools, visit the Navan integration page.
Workflows in Action
Giving an LLM access to isolated tools is only the first step. The true value of a Navan API AI agent emerges when you chain these tools together into autonomous workflows.
Scenario 1: Autonomous Department Transfer and Travel Policy Update
When an employee changes departments, IT admins typically have to manually update their cost center in Navan so their future travel is billed correctly. An AI agent can fully automate this based on a Slack message or Jira ticket.
"Sarah Connor just moved from Support to Enterprise Sales. Update her Navan profile so her future travel is billed to the Enterprise Sales cost center."
- The agent calls
list_all_navan_users(via thenavanscimintegration) to search for "Sarah Connor" and extracts her Navan User ID. - The agent calls
list_cost_centersto search for "Enterprise Sales" and extracts the associated Cost Center UUID. - The agent calls
update_user_cost_centerusing Sarah's User ID and the Enterprise Sales Cost Center UUID to execute the update.
The user receives a confirmation: "Sarah Connor's Navan profile has been successfully updated. Her future bookings will now be routed to the Enterprise Sales cost center (UUID: 8877-6655)."
Scenario 2: Active Booking Audit and Calendar Reconciliation
Finance teams waste hours cross-referencing expense systems with employee whereabouts. An agent can proactively audit a user's active bookings to verify they match expected travel windows.
"Check John Smith's active Navan bookings for next week and summarize his flight itinerary and hotel check-in dates."
- The agent calls
list_all_navan_users(via SCIM) to find John Smith's User ID. - The agent calls
get_active_bookingsusing John's User ID, filtering for the upcoming week's date range. - The agent parses the returned JSON array of bookings, extracting the airline, flight times, and hotel confirmation details.
The user gets a concise summary: "John Smith is flying Delta to Austin on Tuesday at 8:00 AM, checking into the Marriott Downtown on Tuesday afternoon, and returning Thursday at 5:00 PM."
Building Multi-Step Workflows
To put this into production, you need to connect Truto's proxy APIs to your agent framework. The following architecture demonstrates a LangChain.js setup, but the exact same principles apply to CrewAI, LangGraph, or the Vercel AI SDK.
The flow is straightforward: fetch the tools, bind them to the LLM, enter the execution loop, and handle API constraints - specifically rate limits - explicitly.
flowchart TD
A["User Prompt<br>(Update Cost Center)"] --> B["Agent (LLM)"]
B -->|"Selects list_all_navan_users"| C["Truto Tool Manager"]
C -->|"HTTP GET /users"| D["Upstream API<br>(Navan SCIM)"]
D -->|"Returns User ID"| C
C -->|"Parses Schema"| B
B -->|"Selects list_cost_centers"| C
C -->|"HTTP GET /cost-centers"| E["Upstream API<br>(Navan)"]
E -->|"HTTP 429 Too Many Requests<br>ratelimit-reset: 10"| C
C -->|"Throws RateLimitError"| F["Agent Error Handler"]
F -->|"Sleeps 10s"| B
B -->|"Retries list_cost_centers"| C
C -->|"HTTP GET /cost-centers"| E
E -->|"Returns UUID"| C
C --> B
B -->|"Selects update_user_cost_center"| C
C -->|"HTTP PATCH /users/:id"| E
E -->|"200 OK"| C
C --> B
B --> G["Final Response"]Implementing the Agent Loop in TypeScript
The code below shows how to initialize the TrutoToolManager, fetch the Navan tools, and safely execute them while actively handling the HTTP 429 rate limit errors that Truto passes through.
import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";
import { HumanMessage } from "@langchain/core/messages";
async function runNavanAgent() {
// 1. Initialize the LLM
const llm = new ChatOpenAI({
modelName: "gpt-4o",
temperature: 0,
});
// 2. Initialize the Truto Tool Manager
const toolManager = new TrutoToolManager({
trutoApiKey: process.env.TRUTO_API_KEY,
});
// 3. Fetch tools for the connected Navan integrated account
const integratedAccountId = "navan-account-id-123";
const tools = await toolManager.getTools(integratedAccountId);
// 4. Bind the tools to the LLM
const llmWithTools = llm.bindTools(tools);
// 5. Initialize conversation history
const messages = [
new HumanMessage(
"Find the cost center for 'Enterprise Sales' and assign user Sarah Connor to it."
)
];
console.log("Starting autonomous Navan workflow...");
// 6. The Agent Execution Loop
while (true) {
const response = await llmWithTools.invoke(messages);
messages.push(response);
// If the LLM didn't call a tool, we have our final answer
if (!response.tool_calls || response.tool_calls.length === 0) {
console.log("\nFinal Result:", response.content);
break;
}
// Execute each requested tool call
for (const toolCall of response.tool_calls) {
console.log(`Executing tool: ${toolCall.name}`);
const tool = tools.find((t) => t.name === toolCall.name);
if (!tool) continue;
let toolResult;
try {
toolResult = await tool.invoke(toolCall.args);
} catch (error: any) {
// Explicitly handle HTTP 429 Rate Limits passed through by Truto
if (error.response && error.response.status === 429) {
const resetSeconds = parseInt(error.response.headers.get('ratelimit-reset') || '5', 10);
console.warn(`Rate limit hit on ${toolCall.name}. Sleeping for ${resetSeconds} seconds...`);
await new Promise(resolve => setTimeout(resolve, resetSeconds * 1000));
// Tell the LLM the tool failed due to rate limits and it should try again
toolResult = JSON.stringify({
error: "Rate limit exceeded. Please retry the exact same tool call now."
});
} else {
// Handle 403s (like the SCIM entitlement issue) or 400s
toolResult = JSON.stringify({
error: error.message || "Unknown API error occurred"
});
}
}
messages.push({
role: "tool",
tool_call_id: toolCall.id,
name: toolCall.name,
content: typeof toolResult === 'string' ? toolResult : JSON.stringify(toolResult),
});
}
}
}
runNavanAgent().catch(console.error);In this execution loop, the agent takes full control. It fetches the tools dynamically, parses their descriptions, constructs the JSON arguments, and interprets the results.
Crucially, the catch block intercepts HTTP 429 errors. Because Truto normalizes the headers but does not absorb the backoff, your application logic reads the ratelimit-reset header, sleeps the thread, and informs the LLM to retry. This guarantees your agent remains robust even during heavy pagination across large Navan environments.
Moving to Production
Connecting AI agents to Navan requires more than just API credentials. It requires a resilient architecture that maps complex entities, handles strict authorization boundaries like the SCIM entitlement gap, and gracefully manages rate limits.
By routing your LLM through a unified tool proxy, you eliminate the boilerplate of authentication, pagination mapping, and schema definition. Your engineering team can focus on improving the agent's prompts and orchestration logic, while the infrastructure layer guarantees that only strictly validated payloads reach the Navan API.
FAQ
- Why does the Navan list users tool return a 403 Forbidden?
- Navan gates user directory data behind partner/TMC entitlements. Self-serve API credentials do not carry this entitlement. You must use a Navan SCIM integration to access the user directory.
- Does Truto automatically handle Navan API rate limits?
- No. Truto normalizes the upstream rate limit headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) and passes the HTTP 429 error directly to the caller. Your AI agent framework is responsible for handling the retry and backoff logic.
- Can I use Truto's Navan tools with LangChain or LangGraph?
- Yes. Truto's auto-generated tools provide standard JSON schemas that can be bound natively to any LLM framework, including LangChain, LangGraph, CrewAI, and the Vercel AI SDK.
- How does an AI agent handle Navan's nested cost center data?
- Navan requires strict UUID mapping for cost centers and departments. An AI agent must first use the list_cost_centers tool to find the correct UUID, and then inject that UUID into subsequent tool calls like creating an expense or updating a user.