The various collection resources (e.g. /{accountPathComponent}/api/order/) support filtering using a query parameter. The filter is placed in the query parameter as Base64 encoded JSON. The JSON is a single object with a single key corresponding to the key in the result object that should be filtered. The value is the query object is an array with two elements corresponding to the lower and upper bounds of the range to filter. If either bound is null, then the range to filter is unbounded on that side. The range is closed on both ends (the result includes elements that match either the lower or upper bound). To filter by a single value, set the range to have that value as both the lower and upper bound.

IMPORTANT: The system is optimized for filtering by lastUpdatedDate. There is one collection, the inventoryitem collection, that does not support filtering.
IMPORTANT: The lastUpdateDate filter must be a range: for example: lastUpdatedDate=["2022-01-01","2022-01-05"]
Some collections that you access may return more than 120,000 entities from the database.

  • Please note filtering large collections (greater than 120,000 entities) using the resource endpoints is not supported without a lastUpdatedDate filter because the results will not be accurate. The lastUpdatedDate filter always works, but the response is limited to 120k entities. Other filtering is supported as long as you have a lastUpdatedDate filter that will reduce the collection size below 120,000 entities.
  • The lastUpdatedDate filter is applied first before any other filters. If there are more entities matching the lastUpdatedDate filter than the maximum limit of 120k entities, other filters will only apply to those entities within that limit. That's why you would see other filters having issues when there are more than 120k entities. The limit parameter applies after all filtering.
  • When using the lastUpdatedDate , if it doesn't filter results down below the maximum limit (120k), then all the other filters only apply to data within that limited 120K response. Any entities that exist past the 120K entity after the start of the range would be ignored.

IMPORTANT NOTE: The lastUpdatedDate filter is limited to a maximum of 30 days of data. The range is calculated using the provided lower and upper bounds for the filter, or the current date if the upper bound is not present. If you specify a range larger than 30 days, or if you don't include a lower bound, an error will be returned and your request will not be processed. A request that doesn't specify a date range is not affected by this limitation.

For example, if an API user wanted to request all shipments between January 2023 and March 2023 inclusive, they would have to make three requests: one for January, one for February, and one for March, using the lastUpdatedDate parameter in the filters. Any request that exceeds this range will be rejected with a 400 error and an error message indicating what the problem is and how to fix it.

GET /{accountPathComponent}/api/shipment/ => NOT AFFECTED
GET /{accountPathComponent}/api/shipment/?filter=xyz, where xyz is lastUpdatedDate=["2022-01-01",null] => WILL RECEIVE A 400
GET /{accountPathComponent}/api/shipment/?filter=xyz, where xyz is lastUpdatedDate=["2022-01-01","2022-01-05"] => WILL BE OK
GET /{accountPathComponent}/api/shipment/?filter=xyz, where xyz is lastUpdatedDate=["2022-01-01","2022-03-25"] => WILL RECEIVE A 400

If the collection you are accessing does not have or return more than 120K entities it is not required that you use the lastUpdatedDate filter.

The collection APIs will respond quicker when you limit the number of entries. Add a limit parameter to the url with an integer value. A user set limit parameter would take the first 1000 after all other javascript filters are applied.

If you are experiencing performance issues or you need to filter a collection more precisely, you should use our reporting API instead. Filtering large collections works best using the reporting API.

How to use the Reporting API

Adding Filters to Report URL called by the API

To filter by lastUpdatedDate:

  • The required JSON is {"lastUpdatedDate":["2015-11-19T20:09:57Z",null]}.
  • Base 64 encoding that is
    eyJsYXN0VXBkYXRlZERhdGUiOlsiMjAxNS0xMS0xOVQyMDowOTo1N1oiLG51bGxdfQ
  • The full URL to query for products changed since the lastUpdateDate:
    https://app.finaleinventory.com/{accountPathComponent}/api/product/?filter=eyJsYXN0VXBkYXRlZERhdGUiOlsiMjAxNS0xMS0xOVQyMDowOTo1N1oiLG51bGxdfQ

To filter for committed sales orders:

  • The required JSON is {orderTypeId:['SALES_ORDER','SALES_ORDER'],statusId:['ORDER_LOCKED','ORDER_LOCKED']}
  • Base 64 encoding that is iseyJvcmRlclR5cGVJZCI6WyJTQUxFU19PUkRFUiIsIlNBTEVTX09SREVSIl0sInN0YXR1c0lkIjpbIk9SREVSX0xPQ0tFRCIsIk9SREVSX0xPQ0tFRCJdfQ==
  • The full URL to query for orders is:https://app.finaleinventory.com/{accountPathComponent}/api/order/?filter=eyJvcmRlclR5cGVJZCI6WyJTQUxFU19PUkRFUiIsIlNBTEVTX09SREVSIl0sInN0YXR1c0lkIjpbIk9SREVSX0xPQ0tFRCIsIk9SREVSX0xPQ0tFRCJdfQ==
  • Important note:
    Your order collection may presently contain more than 120K orders, for example, 167,000 orders, of which 200 of the most recent orders have a status of committed and you were seeking to only return those rows, you need to apply an optimized filter such as lastUpdateDate, in addition to the status filter, to get the results you seek. If you do not use the optimized lastUpdateDate filter, and only use the statusId filter, the inial fetch of records would truncate at 120,000 rows, and then the statusId filter will be applied to the truncated results. So if the orders that are in committed status are recent in time, they were not included in the initial fetch because the results were limited to the first 120,000 rows, so the orders that are really in committed status were not returned, before filtering by the statusID, and your query will return with zero results, leading you to believe there were no orders in committed status.
    Similar filters can be applied to any value that is a scalar type at the top level of the object (for example, the order orderId, the order origin location, the customer name, or the facility name). Therefore you can't filter on products in an order/shipment, or user defined fields.

The system is optimized for filtering by lastUpdatedDate. If you are encountering performance problems requesting large collections, then you should cache your collections and only fetch updates using the lastUpdatedDate filter. Typically the system performs well for collections with up to 10,000 entries, but if you have more then you should consider adding caching in your code.

The collection APIs can respond quicker when you limit the number of entries. Add a limit parameter to the url with an integer value.

  • The full URL to query for the first 1000 products ordered by their lastUpdatedDate:
    https://app.finaleinventory.com/{accountPathComponent}/api/product/?limit=1000
  • To continue iteration, you can take the last entry in the lastUpdatedDate list and use that as the starting point for your next request. The filters are inclusive so there would be overlap between requests.
  • The full URL to query for the next 1000 products changed since the lastUpdateDate:
    https://app.finaleinventory.com/{accountPathComponent}/api/product/?limit=1000&filter=eyJsYXN0VXBkYXRlZERhdGUiOlsiMjAxNS0xMS0xOVQyMDowOTo1N1oiLG51bGxdfQ

To filter for all product lookups for a specific product by productUrl:

  • The required JSON is {productUrl:['/demo/api/product/10000','/demo/api/product/10000']}
  • Base 64 encoding that is eyJwcm9kdWN0VXJsIjpbIi9kZW1vL2FwaS9wcm9kdWN0LzEwMDAwIiwiL2RlbW8vYXBpL3Byb2R1Y3QvMTAwMDAiXX0=
  • The full URL to query for that product's product lookups is https://app.finaleinventory.com/{accountPathComponent}/api/scanlookup/?filter=eyJwcm9kdWN0VXJsIjpbIi9kZW1vL2FwaS9wcm9kdWN0LzEwMDAwIiwiL2RlbW8vYXBpL3Byb2R1Y3QvMTAwMDAiXX0=

To filter for a regular product lookup by scan key:

  • The required JSON is {scanKey:['10000','10000'],scanTypeId:['UNSPECIFIED_TEXT','UNSPECIFIED_TEXT']}
  • Base 64 encoding that is eyJzY2FuS2V5IjpbIjEwMDAwIiwiMTAwMDAiXSwic2NhblR5cGVJZCI6WyJVTlNQRUNJRklFRF9URVhUIiwiVU5TUEVDSUZJRURfVEVYVCJdfQ==
  • The full URL to query for that product's product lookups is https://app.finaleinventory.com/{accountPathComponent}/api/scanlookup/?filter=eyJzY2FuS2V5IjpbIjEwMDAwIiwiMTAwMDAiXSwic2NhblR5cGVJZCI6WyJVTlNQRUNJRklFRF9URVhUIiwiVU5TUEVDSUZJRURfVEVYVCJdfQ==

To filter for a range of Finale short codes by scan key:

  • The required JSON is {scanKey:['200001000100','200001000200'],scanTypeId:['INVENTORY_SHORT_CODE','INVENTORY_SHORT_CODE']}
  • Base 64 encoding that is eyJzY2FuS2V5IjpbIjIwMDAwMTAwMDEwMCIsIjIwMDAwMTAwMDIwMCJdLCJzY2FuVHlwZUlkIjpbIklOVkVOVE9SWV9TSE9SVF9DT0RFIiwiSU5WRU5UT1JZX1NIT1JUX0NPREUiXX0=
  • The full URL to query for that product's product lookups is https://app.finaleinventory.com/{accountPathComponent}/api/scanlookup/?filter=eyJzY2FuS2V5IjpbIjIwMDAwMTAwMDEwMCIsIjIwMDAwMTAwMDIwMCJdLCJzY2FuVHlwZUlkIjpbIklOVkVOVE9SWV9TSE9SVF9DT0RFIiwiSU5WRU5UT1JZX1NIT1JUX0NPREUiXX0=