Core API Features

Pagination

For performance and scalability most LOCATE endpoints are paginated. This means that when you request a list endpoint such as /part the response will be limited to a subset of records. You can choose to specify the number of records that are returned per page using the perPage GET parameter. The current page you would like to request can be specified using the page GET parameter.

ParameterDescriptionDefault ValueMin ValueMax Value
perPageNumber of records to return per page1000100
pagePage to be returned by the API11Unbounded
/part?perPage=20&page=1

The response of a paginated endpoint will be a JSON object containing your requested data along with various pagination details.

FieldData TypeDescription
totalIntegerTotal number of records across all pages
per_pageIntegerNumber of records per page
current_pageIntegerThe page number the current data set
last_pageIntegerThe last page available based on the total number of records
next_page_urlStringThe URL for the next page
prev_page_urlStringThe URL for the previous page
fromIntegerThe starting record count in the current data set
toIntegerThe ending record cound in the current data set
dataArrayArray of objects for the given endpoint

Simple Filtering

To filter the records of an endpoint you can simply pass a field name and value as a GET parameter. For example, if you would like to get a list of all active carriers you could submit a request to the /carrier endpoint with the GET parameter active=1

NOTE: Not all fields can be filtered on. These are denoted in the Model section of the API Reference.

/carrier?active=1

Advanced Filtering

LOCATE offers a more advanced filtering feature when simple comparisons aren’t enough to find the data you are looking for. You can use this feature with the filter GET parameter. Make sure that your filters are URL encoded so that they are interpreted/transmitted correctly.

NOTE: Not all fields in LOCATE are indexed for performance reasons, but key fields are and all ID fields are. There is a 60 second maximum time for all requests before they will timeout. Using indexed fields will improve your response time. For example, rather than using created_at to filter for new records you might use id instead.

The following characters are recognized by the advanced filtering engine:

OperatorCharacter(s)What It Does
parenthesis()Forms a group of logic, supports nesting
and&&logical and operator to require multiple conditions to be true
or||logical “or” operator to require one or another condition to be true
greater than>checks if the left operand is greater than the right operand
greater than or equal>=checks if the left operand is greater than or equal to the right operand
less than<checks if the left operand is less than the right operand
less than or equal<=checks if the left operand is less than or equal to the right operand
equal=checks if the left operand equals the right operand (case insensitive)
not equal!=checks if the left operand does not equal the right operand (case insensitive)
is nullIS NULLchecks if the left operand is null
is not nullIS NOT NULLchecks if the left operand is not null
fuzzy match%can be used in string matching for matching multiple unknown characters

Let’s look at a basic example of advanced filtering in action:

GET /salesorder?filter=issue_date>=”2020-12-01″

This request would find all sales orders issued after the first of December 2020 UTC

Now a multi-condition filter:

GET /salesorder?filter=(issue_date>=”2020-12-01″ && customer_id=7)

This request would find all sales orders associated with customer_id 7 that were issued after the first of December 2020 UTC

And something a bit more complex:

GET /salesorder?filter=(issue_date>=”2020-12-01″ && issue_date<“2021-01-01”) || customer.name = “s%”

This request would find all sales orders issued in the month of December 2020 UTC or that are associated with a customer who’s name starts with the letter “s”

Embedded filtering can be performed via the advanced filter feature as demonstrated above. This extends to custom fields and attributes (on parts) as well.

See more examples of advanced filters in this tutorial.

Embedding

To embed a related object on an endpoint you can use the embed GET parameter. A related object is commonly denoted by field name ending in _id. To embed multiple objects you can comma separate the related objects in the embed GET parameter.

/site?embed=sitetype,contact

You can also chain embeds to save even more requests when you need a large amount of data. This is achieved by using the dot operator between objects. Below we are loading a sales order with the customer and the customer type also included in the response.

/salesorder?embed=customer.customertype

For more information about embedding, visit this tutorial.

Sorting

To sort the records returned from an endpoint you can use the sort GET parameter. Supplying a field name such as sort=name will sort the returned records by the name field ascending. To sort descending add a minus in front of the field name sort=-name. Multi-sort can be performed by comma separating field names in the sort GET Parameter.

Note: Not all fields support sorting. If a field cannot be sorted on it will be notated in the API Reference documentation on the Model.

/user?sort=first_name,last_name

Limit Fields

To enhance the performance of your requests you can can limit the fields that are returned by the API. To limit the returned fields, specify a fields GET parameter with a comma separated list of fields you would like returned.

Note: Some fields are exempt from being eliminated and will always be returned. Embedded objects will always be returned in full.

/part?fields=number,name

Transaction Line Types

LOCATE supports a number of different “transactions” (sales orders, quotes, transfer orders, use orders, return orders, picks, packs, ships, etc.). Each of these transactions supports various line types which can change how LOCATE handles/process data. You can view a list of the available line types for any given transaction by using the /reflinktype/linetype endpoint documented here. For a list of objects that support line types and are compatible with this endpoint you can reference /object?can_linetype=1 which will filter for objects that support line types. For example, to see the various line types you can use when building a sales orders you would make the following request:

GET /salesorder/linetype

Dates and Times

LOCATE makes heavy use of dates and times to track when actions should happen and when actions did happen. As such it is important to understand how LOCATE handles dates/times in the API. All dates in LOCATE are stored and served in UTC so when filtering/viewing this data keep that in mind. All dates are served in ISO 8601 format. This is also the format that LOCATE expects dates to be submitted in.

Background Processing

Due to the size and complexity of some operations in the LOCATE API we use background processing to prevent timeouts. There are a number of factors that can affect how long an operation takes including (but not limited to): number of lines, type of lines, type of operation, load on servers, concurrent operations by other users, and more. As such there is no perfect metric by which to gauge when we should or should not use background processing for a given operation. LOCATE utilizes different metrics for different operations, but it consistently returns a 202 response when an operation has been backgrounded rather than processed synchronously. There is a header by which you can force LOCATE to always or never use background processing. Always using background processing doesn’t have any ill effect other than you would need to implement code to appropriately handle checking when an operation is completed which will vary based on load/demand. On the other hand forcing background processing off can result in a timeout and inconsistent outcomes when a timeout does occur. You can control this feature using the “X-Background-Processing” header and specifying either “always” or “never” as a value. Any other value or not providing the header will result in LOCATE dynamically choosing whether to background requests or not using its own metrics.

Viewing Deleted Records

LOCATE soft deletes the majority of data to facilitate the recovery of data that was unintentionally deleted as well as to maintain historically accurate data. Viewing these records can also be helpful for users who want to sync deleted data over to another platform. The /object endpoint has a property “uses_softdeletes” which indicates which objects/endpoints explicitly support the soft delete feature. By default all API endpoints serve only current (i.e. non-deleted) data. To include soft deleted data you would include the “withTrashed” URL parameter with a value of 1. For example, to view all customers including those that are deleted the call would look like this.

/customer?withTrashed=1

When including soft deleted data you can differentiate between non-deleted and deleted data by the “deleted_at” timestamp. When null, it indicates that the record is an active (non-deleted) record. When set with a timestamp that will be the date/time when the record was deleted.