General Behaviors
The Fleet Service API is based on REST principles. The Fleet Service API uses JSON (Content-Type: application/json) content and the HTTP protocol to access resources as HTTP verbs.
HTTP Headers
The Fleet Service API expects the JSON content type. All requests must include the Content-Type header with a value of “application/json”.
Read-Only Fields
The Fleet Service API will ignore read-only resource fields so you can easily submit GET bodies for PUT operations without changing anything other than the desired writable values to update.
HTTP Status Codes
The Fleet Service API uses standard HTTP response codes to indicate the success or failure of an API request. In addition, most operations will return a JSON body as the Response Content.
Method | Description |
GET | Retrieves a resource |
POST | Creates a resource |
PUT | Updates a resource |
PATCH | Partially updates a resource |
DELETE | Removes a resource |
Successful Requests
Fleet Service API returns HTTP 2xx status codes for successful requests.
Status Code | Text | Description |
200 | OK | The request succeeded. |
201 | Created | A POST method successfully created a resource. |
202 | Accepted | The WEX server accepted the request and will execute it later. |
204 | No Content | The WEX server successfully executed the method but does not return any response body. |
Failed Requests 4xx Codes
Fleet Service returns HTTP 4xx status codes for unsuccessful requests, specifically, for the client-side errors.
Status Code | Description |
400 | Bad Request - Generic/unknown error. |
401 | Unauthorized - The users must log in. Also often means the user is unauthenticated. |
403 | Forbidden - The user is not authorized to use this resource. |
404 | Not Found - The resource does not exist. |
405 | Method not Allowed - WEX does not support the HTTP method. |
406 | Not Acceptable - The resource can only generate content not acceptable according to the Accept headers sent in the request. |
429 | Rate Limiting - You have exceeded your write and read requests. Wait a few seconds and try again. |
Failed Requests 5xx Codes
Fleet Service returns HTTP 5xx status codes for unsuccessful requests, specifically, for the server-side errors.
Status Code | Description |
500 | Internal Server Error - A generic error indication for an unexpected server execution problem. |
501 | Not Implemented - The server cannot fulfill the request. |
502 | Bad Gateway |
503 | Service Unavailable - The server is (temporarily) not available. |
Rate Limiting
The API implements rate limiting to manage traffic: 60 write requests and 120 read requests per minute. Before you hit a limit, the X-Rate-Limit-Remaining header will tell you how many requests you have left. If you exceed a limit, expect a “429 Too Many Requests” response. The X-Rate-Limit-Retry-After-Seconds header in this error will suggest a retry delay. Because this delay is rounded to seconds (potentially to 0), ensure you wait at least one second after receiving a 429 before retrying your request.
Results Limiting
Responses are limited to 10,000 items in a paginated dataset. The API will return a “x-total-count” header (also in metadata in body). If this value is 10,000, this indicates the result set limit was reached. Use filtering to narrow your results to smaller data sets.
ODATA
OData (Open Data Protocol) is an ISO/IEC-approved OASIS standard that defines a set of best practices for building and consuming powerful RESTful APIs.
While traditional REST APIs often treat data as simple resources, OData extends standard web protocols (like HTTP verbs GET, POST, etc.) to transform the API into a highly queryable data source. This saves developers significant time by offloading complex filtering and sorting logic from the application and pushing it back to the server.
OData vs. Traditional Query Parameters
The core value of OData lies in its standardized approach to querying, which replaces custom, proprietary query parameters with a few well-defined, globally recognized system query options.
To illustrate OData’s powerful query capabilities, let’s use an example of a client who is seeking to query for unleaded regular gas using the Fleet Service GET/sites endpoint.
In a traditional API, complex queries often involve nested, custom URL parameters that require the API server to write custom code to parse and execute. OData solves this by standardizing five primary system query options:
OData Parameter | Traditional Function | Purpose in OData |
$filter | queryString | Allows clients to specify criteria for selecting a subset of resources. |
$orderby | sort | Specifies the order in which items should be returned (ascending or descending). |
$skip | page | Determines the number of items to skip for pagination (for example, skip 25 to get page 2). |
$top | size | Limits the maximum number of items to return in the response. |
$select | (No equivalent) | Allows clients to specify which properties of a resource to include in the response, reducing payload size. |
Important Note: If an OData parameter is specified in the request, the API will typically ignore or override any non-OData query parameters to ensure standardized processing.
Powerful Querying with $filter and Lambda
The $filter parameter offers extensive capabilities, particularly when dealing with complex, nested data structures.
Simple Filtering
The $filter command uses logical operators (like eq, ne, gt, lt, ge, le) to perform comparisons.
Query Goal | Lucene Query | OData $filter Equivalent |
$Find active sites | status:Active | status eq 'Active' |
Find prices greater than $3 | price:[3 TO *] | price gt 3 |
Find prices less than $4 | price:[0 TO 4] | price lt 4 |
Advanced Filtering with Lambda Expressions
For data models involving collections (like an array of fuel types or prices within a single site record), OData uses Lambda expressions (specifically the anyand all operators) to query nested data.
The Challenge: In a traditional API model, searching for sites where at least one product (in a collection of products) meets specific criteria (for example, “Unleaded Regular” with a price between $3 and $4) is difficult, often requiring custom server-side logic.
The OData Solution: Lambda allows you to use a single expression to evaluate conditions across a collection.
Example Lambda Query: $filter=fuel_types/any(f:f/fuel_price gt 4 and f/fuel_price lt 5 and (f/fuel_type eq 'Mid/Plus' or contains(f/fuel_type,'Regular'))) and brand eq 'VALERO'
This query translates to: “Find sites where the fuel_types collection contains any entry (f) such that the price (f/fuel_price) is between $4 and $5 AND the fuel type (f/fuel_type) is ‘Mid/Plus’ or contains ‘Unleaded Regular’ and the fuel brand is ”VALERO." This provides a robust, self-describing way to query nested fields without custom code.
Optimizing Responses with **$select**
Another OData powerful feature is $select . This lets you explicitly choose which properties you want returned in the response object.
Benefit: If a resource object contains 50 fields, but your application only needs the account_id and site_name, using $select dramatically reduces the data payload size and improves network performance.
Example: $select=account_id, site_name (This tells the server to only return those two properties for the requested entity.)
HATEOAS: Hypermedia As The Engine Of Application State
HATEOAS (Hypermedia As The Engine Of Application State) is the key architectural constraint that differentiates a truly RESTful API from a simple HTTP-based service. It mandates that a client application should not rely on pre-configured, hardcoded URLs to navigate the API. Instead, the client must discover and interact with the API solely by following links dynamically provided in the server’s responses.
Core Principle and Benefits
The fundamental concept of HATEOAS mimics how a human browses a website: you only need the starting page, and every subsequent action (clicking a link, submitting a form) is guided by the document in front of you.
Feature | Description | Benefit |
$Server Response | The server returns the requested resource (data) along with associated hypermedia controls (links, typically under a _links attribute). | Discoverability: The client immediately knows what actions or related resources are available for that specific object. |
$Dynamic Navigation | The links provided reflect the current state of the resource. The client transitions its state by using these provided URIs. | Loose Coupling: The server can change its underlying URI structure (e.g., from /v1/cards to /v2/new-cards) without breaking the client, as the client only relies on the link's relationship name (rel), not the URL itself. |
HATEOAS in Practice: Fleet Service API Examples
The use of HATEOAS ensures that the client’s knowledge is limited to the initial entry point and the meaning of the link relationships (rel), making the system robust and evolvable.
Scenario A: Fetching Resource Details (Discovering Links)
When interacting with a resource collection, HATEOAS enables easy self-discovery of individual resource details:
- Client Request: You call the collection endpoint, such as
GET/accounts - Server Response: The API returns a list of accounts. For each account object in the response, the server includes a set of links, typically including a
selflink. - Client Action: By reading the
_links:"self"object and retrieving itshrefURL, the client can fetch the full, specific details for that individual account (for example,GET/accounts/1-A1BAJ2). The server dynamically provided the exact URL needed.
Scenario B: Confirming and Retrieving New Resources
HATEOAS is critical for confirming successful state transitions (like creating a resource) and providing the immediate next action.
- Client Request: You successfully call the creation endpoint, such as
POST/cards, passing the necessary vehicle and account data. - Server Response: The response confirms the card creation and, under the
_links: “self"attribute, provides the URL for the newly created card resource. - Client Action: The client can immediately use that provided link to verify the card’s details, status, or ID (
GET/cards/{new-card-id}). This process confirms successful execution and gives the client a direct, server-verified path to the new resource.
Mock Data in the XC Sandbox Environment
The sandbox environment has limited connectivity to external systems. With the goal of providing for basic development and testing, certain endpoints will return randomly generated or statically defined data for read operations, and provide limited emulation of production functionality for write and querying operations. It’s important to be aware of these limitations as your code may not return expected results and will behave differently in production.
Enforcement of certain business rules, such as same-account on retrieved or patched payments, will not be enforced. This is because the returned data is mocked/generated and thus may not correlate to a valid account for the client.
OData parameters $skip and $top will be respected, but others will not.
Any mocked endpoint that returns a PDF will return placeholder files.
These endpoints return mocked data:
- Banks
- Payments
- Invoices
DateTime
DateTime values are represented as strings in the ISO 8601 format. You can localize the DateTime depending on the user’s timezone. All DateTimes are stored in UTC only and include a Z at the end. For example, midnight UTC on April 19, 2023, would be “2023-04-19T00:00:00.000Z”.
On this page
- General Behaviors