Skip to content

Connect Perk to AI Agents: Orchestrate Travel Ops & SCIM Sync

Yuvraj Muley Yuvraj Muley 11 min read AI & Agents
TrutoFor teams building AI agents

Give your AI agent Perk tools.

Connecting AI agents to Perk requires navigating nested trip schemas, SCIM identity provisioning, and strict rate limits. This guide shows developers how to use Truto's /tools endpoint to bind reliable, type-safe API tools to LangChain or Vercel AI SDK, enabling autonomous travel ops and user lifecycle management.

In this guide

  1. 01Define your integration layer strategy
  2. 02Fetch Perk schemas via the /tools endpoint
  3. 03Filter and bind tools to your agent framework
  4. 04Implement rate limit backoff logic
  5. 05Execute multi-step travel and SCIM workflows

The guide

Learn how to connect Perk to AI agents using Truto's /tools endpoint. Build autonomous workflows for travel operations, SCIM provisioning, and expense tracking.

You want to connect Perk (TravelPerk) to an AI agent so your system can independently orchestrate travel operations, process invoice PDFs, sync custom fields, and manage SCIM identity provisioning. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to build a custom travel integration from scratch.

Giving a Large Language Model (LLM) read and write access to a travel management platform requires strict architectural guardrails. An autonomous agent cannot afford to hallucinate SCIM user schemas or blindly retry rate-limited invoice endpoints. If your operations team relies on ChatGPT interfaces, check out our guide on connecting Perk to ChatGPT, or if you are building on Anthropic's models, read our guide to connecting Perk to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them directly to your agent framework.

This guide breaks down exactly how to fetch AI-ready tools for Perk, bind them natively to an LLM using frameworks like LangChain, LangGraph, CrewAI, or the Vercel AI SDK, and execute complex travel operations. For a broader look at this design pattern across the B2B SaaS ecosystem, read our underlying research on Architecting AI Agents: LangGraph, LangChain, and the SaaS Integration Bottleneck.

Why a Tool Abstraction Layer Matters for Agent Reliability

Before writing integration code for your agent, you must decide what layer of infrastructure the LLM will actually talk to. Direct API integration - wrapping raw Perk endpoints in manual Python or TypeScript functions - looks simple in a prototype but creates severe stability issues in production.

Direct integration forces the LLM to memorize the specific quirks of the underlying API. The model has to know the difference between standard pagination and cursor-based iteration, handle complex OAuth token injection, and perfectly format heavily nested JSON payloads. Every manual API interaction is a surface area for hallucination.

By leveraging Truto's Proxy APIs, your agent interacts with a standardized REST-based CRUD abstraction. Truto maps complex underlying API endpoints into logical Resources (like trips, invoices, or scim_users) and standard Methods (List, Get, Create, Update, Delete, plus Custom operations).

When you use Truto's /tools endpoint to feed schemas to your agent, you gain three distinct architectural advantages:

  1. Deterministic input validation. Every tool provided by Truto has a strict JSON schema. The agent framework validates arguments before they hit the network, ensuring invalid calls fail fast without burning API quotas.
  2. Zero authentication logic in the agent. Truto handles the entire OAuth lifecycle and token injection behind the scenes. The LLM never sees or attempts to manage bearer tokens.
  3. Real-time schema synchronization. Tool definitions update automatically if you adjust resource descriptions or query schemas in the Truto integration UI. You do not need to redeploy your agent code to expose a new Perk endpoint.

The Engineering Reality of the Perk API

Giving an LLM access to external travel data sounds straightforward until you encounter the actual structure of the vendor's API. If you hardcode these interactions, your engineering team will spend their sprints writing defensive parsing logic instead of improving the agent's core reasoning loops.

The Perk API introduces several specific integration challenges that break standard agent assumptions.

The SCIM Extension Schema Trap

When provisioning users, Perk relies on the SCIM (System for Cross-domain Identity Management) protocol. Standard LLMs are trained to expect flat user objects like {"first_name": "John", "department": "Engineering"}.

Perk's SCIM implementation requires a highly specific payload structure that includes standard IETF schemas alongside custom travel extensions. To update a user's travel policy or cost center, the agent must construct a payload referencing custom URNs (e.g., urn:ietf:params:scim:schemas:extension:travelperk:2.0:User). If the agent hallucinates a standard REST update instead of a SCIM PatchOp body with Operations arrays, the API will reject it. Providing the LLM with a strict, pre-validated Truto Proxy API tool schema ensures the agent formats SCIM operations correctly every time.

Nested Trip and Booking Hierarchies

Travel data is inherently relational. A single trip in Perk is not a flat record; it contains nested bookings, which in turn contain specific legs, references, and geographic coordinates.

When an agent attempts to analyze a user's itinerary, it must navigate the hierarchy from the list_all_perk_trips response down into specific list_all_perk_bookings. An LLM attempting to synthesize this data via raw API calls often gets confused by the varying schemas between flights, trains, and hotels. Abstracting these endpoints into discrete, well-described tools helps the agent understand which tool to call for high-level trip metadata versus granular booking details.

Strict Idempotency and Cost Center State

Perk enforces strict rules around financial objects like cost centers. When bulk updating cost centers, the API behavior changes depending on whether cost object types are enabled for the organization. If they are not enabled, the archive boolean is strictly required. If they are enabled, the payload must supply at least one of archive or a valid non-null type string.

LLMs struggle with conditional payload requirements. By defining specific query schemas on the Truto Resources, you enforce the correct shape of the request before it reaches Perk, preventing the agent from getting stuck in an error loop.

Fetching Tools for Your AI Agent

Truto provides a dedicated endpoint to programmatically fetch all tools available for an integrated account. Instead of writing schemas by hand, your agent framework queries GET https://api.truto.one/integrated-account/<id>/tools.

You can refine this request using query parameters. If you are building a reporting agent that should never alter travel policies or cost centers, you can filter the methods:

curl -X GET "https://api.truto.one/integrated-account/<integrated_account_id>/tools?methods[0]=read"
  -H "Authorization: Bearer <your_truto_api_key>"

The response contains an array of fully-formed JSON tools, including descriptions and parameter schemas, ready to be digested by an LLM.

flowchart TD
    A["Agent Orchestrator<br>(LangGraph / CrewAI)"] -->|"GET /tools?methods[0]=read"| B["Truto API"]
    B -->|"Proxy API Schemas"| A
    A -->|"LLM Context Window"| C["Large Language Model"]
    C -->|"Tool Call Decision"| A
    A -->|"Execute Proxy API"| B
    B -->|"Raw API Request"| D["Perk API"]

Hero Tools for Perk Automation

When you connect Perk through Truto, your agent gains access to dozens of Proxy APIs. Rather than exposing every possible endpoint, you should equip your agent with high-leverage tools that enable complex orchestration.

Here are the critical "hero tools" to bind to your travel and operations agents.

1. list_all_perk_trips

This tool allows the agent to pull a comprehensive list of all trips, sorted by modified time. It returns crucial metadata including trip names, start/end locations, datetime UTC coordinates, and status. It is the entry point for any agentic workflow analyzing employee travel.

"Find all active trips starting in London this week and verify if their end datetimes overlap with the upcoming all-hands meeting."

2. get_single_perk_invoice_pdf_by_id

Expense auditing agents require access to actual documentation. This tool bypasses the standard JSON response and directly downloads a Perk invoice in PDF format based on its serial number (e.g., INV-01-987654). The agent can then pipe this binary file into an OCR or multimodal vision model for line-item verification.

"Fetch the PDF invoice for INV-01-987654 and extract the total taxes paid, comparing it against the structured JSON data."

3. create_a_perk_scim_user

Essential for IT operations and HR onboarding agents. This tool provisions a new user in Perk via SCIM, requiring strict parameters like userName, name.givenName, and active status. It allows the agent to construct the exact SCIM resource payload required by Perk.

"A new software engineer, Sarah Connor, just signed her offer letter. Provision her a Perk account using her corporate email and set her initial status to active."

4. update_a_perk_scim_user_by_id

When employees change departments or are offboarded, their travel permissions must update instantly. This tool handles the SCIM PATCH or PUT operations required to modify an existing user's travel attributes, active status, or policy assignments.

"John Doe has left the company. Immediately locate his SCIM user record in Perk and update his active status to false to revoke booking access."

5. list_all_perk_invoices_lines

For financial reconciliation, looking at total invoice amounts is insufficient. This tool fetches the granular line items of an invoice, returning expense dates, descriptions, quantities, and unit prices. This allows an agent to classify specific spend categories (e.g., flights vs hotel incidentals) autonomously.

"Retrieve all invoice lines for last month's engineering offsite and categorize the spend into transport, lodging, and meals based on the line descriptions."

6. perk_cost_centers_bulk_updates_bulk_update

Managing cost centers individually is slow. This tool enables an agent to bulk update cost centers in a single request - archiving outdated project codes or applying new cost object types across the board. It requires careful orchestration of the id_list.

"We are deprecating the 'Project Alpha' cost centers. Take the list of associated cost center IDs and bulk update them to an archived state."

For a complete list of available resources, query schemas, and return types, review the full inventory on the Perk integration page.

Workflows in Action

Exposing tools to an LLM is only half the architecture. The true value emerges when the agent autonomously chains these tools together to resolve complex operational tasks.

Automated Employee Offboarding & Travel Cancellation

When an employee is terminated, IT admins traditionally spend hours hunting through different SaaS portals to revoke access and cancel pending expenses. An AI agent handles this instantly.

"Initiate offboarding for j.smith@company.com. Revoke their Perk access and generate a report of any upcoming trips they had booked."

  1. The agent calls list_all_perk_scim_users with a filter expression (filter=userName eq "j.smith@company.com") to locate the user's SCIM ID.
  2. It calls update_a_perk_scim_user_by_id, passing active: false to instantly lock the account.
  3. It calls list_all_perk_trips filtering by the user's booker_id and looking for future start_datetime_utc values.
  4. The agent compiles the list of upcoming trips into a structured markdown report and alerts the finance team regarding pending cancellations.

Expense Auditing & Cost Center Verification

Finance teams struggle to verify if travel expenses were billed to the correct departmental cost centers. An agent can audit this continuously in the background.

"Audit all invoices issued in Q3. Ensure that any trip taken by the marketing department is correctly assigned to the 'Marketing 2024' cost center, and flag any discrepancies."

  1. The agent executes list_all_perk_scim_users to build an internal map of marketing department employees.
  2. It calls list_all_perk_invoices filtering for the Q3 date range.
  3. For each invoice, it calls list_all_perk_invoices_lines to inspect the underlying descriptions and metadata.
  4. If an invoice line belongs to a marketing employee but lacks the correct cost center ID, the agent logs the invoice_serial_number and the employee name into a discrepancy report for the accounting team.

Continuous SCIM Sync and Directory Alignment

Maintaining alignment between an HRIS and a travel management platform is a constant battle against schema drift. An agent can act as a continuous reconciliation engine.

"Compare our active employee directory against the Perk SCIM user list. Identify any active Perk users who are not in the main directory and deactivate them."

  1. The agent receives the master employee list from a separate HRIS tool (e.g., Workday or BambooHR).
  2. It pages through list_all_perk_scim_users to pull the current travel roster.
  3. The agent cross-references the data in memory. Upon finding a mismatch (an active Perk user not in the HRIS).
  4. The agent executes update_a_perk_scim_user_by_id to set the orphaned account to active: false.

Building Multi-Step Workflows

To build these autonomous loops, you must bind the Truto tools to your framework and implement robust error handling. The most critical architectural requirement when dealing with external APIs is rate limit management.

Factual Note on Rate Limits

Truto does not retry, throttle, or apply backoff on rate limit errors. If your agent attempts to fetch 500 invoices in a tight loop and the upstream Perk API returns an HTTP 429 (Too Many Requests), Truto passes that 429 error directly back to your caller.

However, Truto normalizes the upstream rate limit information into standard IETF headers: ratelimit-limit, ratelimit-remaining, and ratelimit-reset. Your agent execution loop must parse these headers and implement its own retry and backoff logic. Do not expect the LLM to simply "try again" successfully without explicitly pausing the execution thread.

sequenceDiagram
    participant Agent as Agent Framework
    participant Truto as Truto Proxy API
    participant Perk as Perk API
    Agent->>Truto: Tool Call (Execute SCIM Update)
    Truto->>Perk: Upstream API Request
    Perk-->>Truto: HTTP 429 Too Many Requests
    Truto-->>Agent: HTTP 429<br>ratelimit-reset: 1715000000
    Note over Agent: Agent parses headers<br>Executes thread sleep
    Agent->>Truto: Retry Tool Call
    Truto->>Perk: Upstream API Request
    Perk-->>Truto: HTTP 200 OK
    Truto-->>Agent: JSON Tool Result

Framework-Agnostic Agent Loop

Here is how you handle tool fetching, execution, and native rate limit backoffs in a standard TypeScript agent setup. This approach works whether you use LangChain, the Vercel AI SDK, or custom orchestration logic.

import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";
 
async function runTravelOpsAgent(prompt: string) {
  // 1. Initialize the LLM
  const model = new ChatOpenAI({ 
      modelName: "gpt-4o", 
      temperature: 0 
  });
 
  // 2. Fetch tools from Truto for the specific Perk account
  const toolManager = new TrutoToolManager({
    trutoApiKey: process.env.TRUTO_API_KEY!,
    integratedAccountId: "perk_acct_8899xyz"
  });
 
  // Filter for both read and write tools for travel ops
  const tools = await toolManager.getTools({ 
      methods: ["read", "write", "custom"] 
  });
 
  // 3. Bind the Truto proxy tools to the model
  const modelWithTools = model.bindTools(tools);
 
  console.log(`Executing prompt: ${prompt}`);
  
  // 4. Initial LLM invocation
  const response = await modelWithTools.invoke(prompt);
 
  // 5. The Agent Loop
  if (response.tool_calls && response.tool_calls.length > 0) {
    for (const toolCall of response.tool_calls) {
      console.log(`Agent chose tool: ${toolCall.name}`);
      
      let attempt = 0;
      let success = false;
      
      while (!success && attempt < 3) {
        try {
          // Locate and execute the tool
          const selectedTool = tools.find(t => t.name === toolCall.name);
          const result = await selectedTool.invoke(toolCall.args);
          
          console.log(`Tool succeeded. Parsing result for next step...`);
          // Pass result back to LLM context here...
          success = true;
          
        } catch (error: any) {
          if (error.status === 429) {
            // Read the standardized Truto rate limit headers
            const resetTimeStr = error.headers['ratelimit-reset'];
            const resetTimeMs = parseInt(resetTimeStr) * 1000;
            const delay = Math.max(0, resetTimeMs - Date.now()) + 1000; // Add 1s buffer
            
            console.warn(`Rate limited. Pausing execution for ${delay}ms...`);
            await new Promise(resolve => setTimeout(resolve, delay));
            attempt++;
          } else {
            console.error(`Tool execution failed: ${error.message}`);
            // Feed error back to LLM so it can attempt a different strategy
            break;
          }
        }
      }
    }
  }
}
 
// Kick off the workflow
runTravelOpsAgent(
    "Find the SCIM user record for a.lister@company.com and update their cost center ID to CC-998."
);

This pattern insulates the LLM from network volatility. The model decides what to do (update the cost center), the Truto schema enforces how to shape the data, and your execution loop handles when to retry based on hard network realities.

Moving Past Manual Integration Workflows

Building an AI agent that can reliably automate travel operations and SCIM provisioning requires more than clever prompt engineering. It requires stable, predictable access to underlying infrastructure.

By leveraging Truto's /tools endpoint, you abstract away the complexities of nested trip hierarchies, SCIM extension schemas, and OAuth token lifecycles. Your agent interacts with a clean set of deterministic Proxy APIs, drastically reducing hallucination and failure rates.

When your agent is insulated from the engineering realities of third-party APIs, your team can stop writing defensive parsing code and focus entirely on building more sophisticated, autonomous workflows.

Two ways to put Perk to work

Truto

For product teams

Give your agent Perk tools

Your customers connect their own Perk accounts. Your product gets one API and MCP tools for Perk, through Truto.

FAQ

Does Truto automatically handle rate limits when my AI agent calls the Perk API?
No. Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream Perk API returns an HTTP 429 error, Truto passes that error directly back to your agent. However, Truto normalizes the rate limit information into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) so your agent framework can reliably implement its own backoff logic.
How do I give my LLM access to Perk tools without building custom endpoints?
You use Truto's /integrated-account/<id>/tools endpoint. This API returns a complete, LLM-ready JSON schema of all available Proxy APIs (Methods) defined on the Perk integration. You can inject these directly into agent frameworks like LangChain using their bindTools functions.
Can I restrict my AI agent to read-only operations in Perk?
Yes. When fetching tools from the Truto API, you can pass query parameters to filter the returned tools. For example, passing ?methods[0]=read ensures your agent is only provided with tools capable of fetching data, removing the risk of unintended writes or updates.
What is the difference between a Proxy API and a Unified API for AI agents?
Proxy APIs provide normalized, REST-like CRUD endpoints that map directly to the underlying vendor's specific resources. Unified APIs add a second layer of abstraction to standardize data models across multiple vendors in a category. For AI agents, Proxy APIs are often preferred because the LLM is capable of handling data normalization on its own using the raw, vendor-specific schemas provided by the Proxy tools.
Perk PerkAI agent tools Get a sandbox

More from our Blog