The WEX Mobility APIs Team: Rafik Bennacer, Ruihang Liu, Matthew Brock, and Jana Venkataramanan
Integrating complex mobility (vehicle fleet management) services shouldn’t require a stack of static documentation and a mountain of manual validation. Our Mobility APIs team recently set out to change how external partners and developers onboard, interact with, and learn about our tools.
What started as an internal hackathon experiment is now an agentic API AI Assistant, live in beta inside our developer portal. It replaces rigid, language-specific static documentation and passive search indexers with a conversational interface that reasons through complex workflows, generates code in any language, and safely executes non-mutating data queries in real time.
Mobility applications operate in a highly sophisticated data environment — managing a constant stream of real-time data around driver activities, fueling stations, transactions, and vehicle telemetry. Developers integrating with our systems have historically faced a steep learning curve, requiring deep familiarity with advanced REST APIs, intricate filter geometries, domains, and complex multi-step workflows. This complexity made it harder for developers at our partner and customer organizations to grow with us, build with us, and ultimately to see WEX as a place that made their job easier.
Previously, developers relied on static, off-the-shelf documentation platforms to parse endpoints and utility tools to manually test their calls. To clarify workflows, our team maintained static “recipes” — discrete sequences of stitched-together API calls showing how to accomplish multi-step workflows (such as creating an account, onboarding a driver, and assigning a card).
This static approach got the job done, but we knew we could do better for customers and developers by moving past:
During a December 2025 internal hackathon, we built a proof-of-concept centered on one question: Why make developers translate documentation into code when an AI can dynamically reason through the developer’s intent in real time?
Our solution is an intelligent, agentic API AI Assistant integrated directly into our developer ecosystem. Unlike a search box that surfaces documentation, the assistant acts as an active, always-on integration consultant.
To deliver maximum developer value while maintaining tight operational security, we decoupled the assistant into two fundamental processing paths:
Before we dive into the architecture, let’s explore a few examples of what a partner actually sees.
API Advisor Mode — “Give me the Python snippet to create a driver” The assistant returns a requests call with the correct endpoint, headers, body schema, and a note on which scopes the caller needs. Nothing hits the Mobility APIs.
Plan-Execute Mode — “Show me 5 drivers with first name John.” The Planner turns this somewhat complex API call with multiple filters into a single Task: fetch drivers filtered by first name. The Executor picks the appropriate MCP tool, generates the OData arguments ($filter=first_name eq ‘John’, $top=5), runs the GET against Mobility API (read-only), and stores the response in the Artifact Store. The LLM sees a lightweight summary — artifact_id=drv_1a2b, count=5, preview=[…] — and the Synthesizer returns a clean, human-readable list of the five matching drivers. The assistant is built around a cyclic state machine using LangGraph, where specialized agents — a planner, executors, validators, and a synthesizer — loop together to plan, execute, and validate each step, sharing state and memory until the task is complete.
Security is foundational to our design. To protect the core state, the assistant cannot execute mutating calls directly inside its runtime environment. If a user says “Create a new card for driver X,” the router directs the request to the API Advisor node, which returns a structured code snippet that the developer can copy, audit, and run locally. True runtime actions are strictly gated to read-only GET transactions — mutating tools exist in the MCP server code but are filtered out before they are ever exposed to the LLM.
Our engine handles reasoning and execution on separate layers. We use the Supervisor Pattern — a single coordinator that decides which specialist runs next — to control state across a unified global loop:
One of the largest hurdles with LLMs is their tendency to hallucinate query options or introduce syntax malformations when confronting structured filter standards like OData. We use OData for filtering and search because it gives callers flexible, partial-match queries across complex mobility objects — without us hand-coding every permutation. But that flexibility comes with a cost: LLMs frequently hallucinate invalid options or malform the syntax. To mitigate this, we built a multi-layered self-healing loop.
If a pre-flight parser check catches a syntax bug, or if an in-flight execution raises an API error code, the graph catches the event, bumps a per-task retry counter, and passes the precise system error directly back into the LLM context. The Executor reads its own past failure and immediately re-generates a corrected call. If retries are exhausted, the task cleanly falls back to API Advisor Mode so the user still gets value. Passing a large JSON payload (for example, thousands of unique asset nodes) directly back into the LLM conversation context quickly exhausts token thresholds, degrades reasoning accuracy, and drives up cost.
We implemented a Split-State Memory architecture. Raw API responses are retained inside an isolated backend artifact store. The LLM is only exposed to brief, lightweight summary metadata referencing unique artifact IDs. Follow-up requests drill down into specific items by looking up IDs within our persistent application layer, keeping the model’s context clean and focused.
To ship prompt or model changes without regressions, we built an automated benchmarking pipeline that leverages the LLM-as-a-Judge pattern. It answers the one question every prompt adjustment needs to answer: did this change make things better or worse?
The dataset is a hand-curated set of test cases spanning four categories — code_generation, factual_knowledge, reasoning, and safety — where each case carries not just a question but an explicit grading rubric, so the judge grades the substance of the response rather than matching a fragile expected string. The judge is always a different model than the one under test, grading on a 3-point scale (10 = correct, 5 = partial, 0 = wrong). Every run appends a row to history.csv tagged with git commit, model, judge model, OpenAPI hash, dataset hash, and prompt version — so every score is traceable back to the exact code, spec, and prompt that produced it.
Averaged across runs, the assistant lands around 9.4/10 on the curated rubric — a reliable baseline we hold the line on before any prompt or model change ships.
Accuracy is only one axis. We also track response latency and token usage on every run — latency to keep the experience snappy, and tokens because they translate directly to LLM cost. The goal is to maximize correctness while minimizing both latency and spend; any prompt or model change that regresses one of these metrics gets flagged before it ships.
An always-on AI assistant hitting a production API needs guardrails that protect both our LLM budget and the upstream services. We approach this in three layers:
Developing the assistant was only half the challenge; ensuring secure, seamless access was equally critical.
Historically, our Mobility APIs relied on standard client credentials, necessitating a manual provisioning process for every new customer. For an AI-driven assistant intended for external partners, a workflow requiring users to “submit a request and wait for engineering approval” was not viable. Furthermore, requiring developers to manually input tokens into the chat was inefficient and prevented us from accurately distinguishing assistant-generated API calls from manual requests, thereby complicating usage attribution and security monitoring.
We needed an authentication strategy capable of supporting two distinct user journeys: partners seeking a low-friction experimentation environment, and those ready to integrate with live data — all while eliminating the need for manual, one-off setup tickets.
We built a two-tier access model behind our standard developer login:
This removed our biggest onboarding bottleneck. The path from “I’m curious” to “I’m actively integrating” no longer runs through an engineering queue or a support ticket.
What began as an internal discovery experiment is now an active beta driving integration times down for corporate developer spaces. The application is live in our developer web portal and has successfully onboarded its first wave of beta partners.
Because our foundational orchestrator reads from standardized OpenAPI schemas, the entire assistant architecture is built for horizontal scaling. While our current focus remains anchored on deep validation inside the Mobility ecosystem, the core routing engine is deliberately generic. In upcoming cycles, we plan to:
This work is all about making it easier to interact with and build alongside WEX, and we’re just getting started.
Copyright ©2026 WEX Inc. All rights reserved.
From hackathon spark to production reality: building an agentic API assistant was originally published in Stackademic on Medium, where people are continuing the conversation by highlighting and responding to this story.