The Momentus Enterprise API provides you robust searching capabilities much like you have in the back office application. The API uses a combination of OData notation and a paging mechanism to power API searching using HTTP GET endpoints.
GETting in the API
Most of the API subjects have GET endpoints which enable the search capabilities for that subject. To see the list of GET endpoints, use the built-in API Help by browsing to your site URL and appending /api/help to the URL (ex: https://yoursitename.com/api/help). The API Help also shows you which properties are searchable. Look for the Searchable label on the field. You can access this information through a tooltip when you hover over the info field in the API Help. See below for an example.
Search Limits
There are no data, request, or size limits using the API. However, we ask that you not abuse your API with too many requests as this results in poor performance for both you and other users if you are in the Cloud. What qualifies as abuse? Actual numbers depends on factors such as call frequency within a process, response quantity, response model size and how often a process happens so it is determined on a case-by-case basis. For example, if you request 100,000 accounts through the API, that's a large quantity and the default Accounts model is large, so you can expect slow performance. Another example is if you request 10,000 events every second for days at a time. That is a large quantity in a very frequent hit on the server, resulting in a hard churn. This also might result in a negative effect.
The API does provide provide a paging mechanism which can help with the larger datasets, which is discussed in detail in Search Using the API.
If you are concerned that your call volume is too much, you can review it with our Client Care Team. Generally, a too high call volume is rare in normal API use and usually happens when accidental loops or misuse occurs.
A call to the API to get the next page retrieves the next page of results via a cached result set, thus not affecting your instance and database. By default, the first 1000 results are returned.
OData
Use OData notation to form search queries. Here is an example:
/api/v1/Accounts/10?search=EnteredOn gt DateTime'2019-09-28' and Class eq 'P'$orderby=PostalCode desc, FirstName$page_size=100
What does this do? Let’s break it down.
- /api/v1/ is the base API Url. Every call to the API has this.
- Accounts represents the subject you are searching.
- 10 represents the organization code you are searching over. Searches are per organization only.
- The next part of the OData string represents what you’re trying to search. In this case, you want individual accounts (contacts) entered into the software after September 28, 2019 sorted by postal code (descending) and then by first name. Individual accounts are represented by Class eq ‘P’ and entered into the software after September 28, 2019 is EnteredOn gt DateTime’2019-09-28’.
- Next is sorting, denoted by the >$orderby operator. After this operator, you list the properties you want to order your search by, also qualifying it with desc if you want to have that property sort descending. Each property added is sorted ascending by default. Multiple levels of sorting are achieved by comma-delimited property names.
- $page_size parameter defines how many items per page are returned. The default is 1000. It is optional.
Supported OData Operators
- Equals (eq)
- Greater Than (gt)
- Greater Than Or Equal (ge)
- Less Than (lt)
- Less Than Or Equal (le)
- Not Equal (ne)
- Substring of (substringof)
- Starts With (startswith)
- Ends With (endswith)
Also, the API can do AND and ORs together but no parentheses. It's suggested to group the ORs together to get expected results. For example:
- ODATA: A and B or C Result: A and (B or C)
- ODATA: A and B or C and D Result: A and (B or C) and D
- ODATA: A or B or C and D Result: (A or B or C) and D
Paging
The API provides a paging mechanism for all searching. By default, the page size is 1000. Below are the parameters you can send in to your search query to control how paging works:
- $page_size – Determines how many results are returned in each search call.
- $page – Gets a specific page from a result set.
- APISearch – Cache key provided by the initial search query. It is denoted by “APISearch|GUID”. If this is omitted, a fresh search is initiated.
The paged results are cached within the server that accepted the query. If future calls are load balanced, the call may not work due to hitting a different server that doesn't have that search cached. We recommend accepting and applying the response cookie delivered by the server response in the initial search call.
An example of the response cookie headers is shown below.
Add these as request headers (example below) and you stay with the specific load balanced server that originally cached the paged results.
If using the SDK, it automatically does this for you so this step is not needed.
Results
When the search completes, it returns a result set. The number of items in the result set is based on the page size specified or 1000 if not specified. You can navigate through further results using the paging links that are returned as a header within the response, “X-SearchMetadata”. That header has a structure like this:
{
"Page": "1",
"Page_Size": "1000",
"PageTotal": "25",
"ResultsTotal": "24311",
"Links": {
"Self": "https://yourUngerboeckwebsite/api/v1/Accounts/10?search=APISearch|bc941629-3c5c-49a3-8c64-b15a960e1388$page=1$page_size=1000",
"First": "https://yourUngerboeckwebsite/api/v1/Accounts/10?search=APISearch|bc941629-3c5c-49a3-8c64-b15a960e1388$page=1$page_size=1000",
"Previous": null,
"Next": "https://yourUngerboeckwebsite/api/v1/Accounts/10?search=APISearch|bc941629-3c5c-49a3-8c64-b15a960e1388$page=2$page_size=1000",
"Last": "https://yourUngerboeckwebsite/api/v1/Accounts/10?search=APISearch|bc941629-3c5c-49a3-8c64-b15a960e1388$page=25$page_size=1000"
}
}
In addition to the results information offered here, you can use the Links property to navigate to the first, previous, next, or last page of the result. A current page link is also offered. To navigate, do an API call to the given URL, making sure to include the API Token in the header.
Example:
- /api/v1/Accounts/10/search=APISearch|5a2a9ed1-4da5-4c8e-881d-9c52f9820929$page=2$page_size=1000 – Returns the second page of a previous query (denoted by the GUID). It returns the next 1000 results.
OData Examples By Type
Strings
- Find all accounts in organization 10 where the first name equals 'John' and last name equals = 'Smith'
- /api/Accounts/10/search=FirstName eq 'John' and LastName eq 'Smith'
Dates
- Find bookings after September 29, 2019
- /api/Bookings/10?search=StartDate eq DateTime'2019-09-28'
- Find bookings with the start date on 2019-09-28
- /api/Bookings/10?search=StartDate ge DateTime'2019-09-28' and StartDate lt DateTime'2019-09-29'
- Find any order items entered after 9:13:28 May 29, 2019
- /api/RegistrationOrderItems/10?search=EnteredOn gt datetime'2019-05-29T09:13:28'
Search for Null and Not Null
You can search for null and not null values. You can use this in conjunction with other filters.
Examples:
startswith('Jim', FirstName) and SynchronizedOrganization eq null
This finds all accounts with the first name starting with ‘Jim’ and has no value set for SynchronizedOrganization.
startswith('Jim', FirstName) and SynchronizedOrganization ne null
This finds all accounts with the first name starting with ‘Jim’ and has some value set for SynchronizedOrganization.
Search for User Fields
You can search for User Fields across the API.
For account user fields, the format is [Account User Field Header flag (O ([organization], P [individual], M [membership])]|[User field Class]|[User field Type]|[Organization Code]|[User field property name] ex: 'P|C|04|10|UserText01'
For all other user fields, the format is [User field Class]|[User field Type]|[Organization Code]|[User field property name] ex: 'C|04|10|UserText01'
For example, to search registration orders, here is a possible OData string:
/api/v1/RegistrationOrders/10?search=Event eq 31267 and R|AZ|10|UserNumber01 eq 8412
Along with searching for registration orders for event ID 31267, this search is looking for a user field with a value of 8412. R is always the header for registration order user fields, AZ is the issue type for this User Field set, and 10 is the targeted user field set org code. UserNumber01 denotes the actual user field you want to search for. Use syntax for the user field values respective to DateTime, Text and Integers. For more examples, check out our Github code examples.
For multi-value UDFs, it converts to a CONTAINS search.
Search and Return User Fields
You can retrieve User Defined Fields while searching by specifying which user fields you want in the Select parameter. Note that, due to performance, this is Opt-In per field to help lookup efficiency. Once you specify an active user field, it is returned as a parameter in your custom object.
For non-account user fields, the format is “[User field Type]|[User field property name]”
Example:
https://yoursitename/api/v1/Functions10?search=EventID eq '13082'$select=BU|UserDateTime02
For account user fields, the format is “[User field Class]|[User field Type]|[User field property name]”
Example:
https://yoursitename/api/v1/Accounts/10?search=AccountRep eq '0002410'$select=C|04|UserText01,LastName
Maxresults
By default, the API returns a max result set of 100000 total records, with or without paging. This protects you from unexpected slow calls and from overloading the servers. The below error returns if this is exceeded:
The total number of items returned exceeds the allowed max results. Either increase the query conditions to lower the returned results or increase the allowed max results by using the 'maxresults' parameter in the API Search URL.
As the error suggests, you should first try increasing your conditions to match your actual query. For example, don't retrieve all accounts, but rather, retrieve all event sales accounts or accounts from a certain region. This results in better performance.
If the result set is still too large, you can increase the maxresults parameter:
With the SDK
Example:
public SearchResponse<BoothsModel> SearchingWithMaxresults(int maxResults)
{
SearchResponse<BoothsModel> boothList;
var options = new Ungerboeck.Api.Models.Options.Search() { MaxResults = maxResults }; //For large result sets, you can increase the maxresults parameter
boothList = apiClient.Endpoints.Booths.Search("10", "EnteredOn gt DateTime'2000-01-01'", options);
return boothList;
}
Without the SDK
Example:
https://yourUngerboeckwebsite/api/v1/Accounts/10?search=AccountRep eq '0002410'$maxresults=105000
Keep in mind that doing incredibly large returns for constant calls does result in performance issues. If you are hosted in the cloud, this impacts other customers and Momentus may need to reach out to you so proceed carefully when using this.
Comments
36 comments
Anybody still watching this thread?
0 upvotes
I am 👋
Not sure if you mean Momentus staff specifically though :)
1 upvotes
Well maybe if we have a conversation somebody will know. I'm trying to search a field and need to figure out how to do a wildcard or similar. So currently searching with this format: {base_url}Bookings/{ORG_CODE}?search=StartDate ge DateTime'{formatted_current_date}' and Status eq '30' or Status eq '21' and (Space eq 'EXHA1' or Space eq 'EXHA2'or Space eq 'EXHA'or Space eq 'EXHB' or Space eq 'EXHC' or Space eq 'EXHD' or Space eq 'EXHA-B' or Space eq 'EXHA-C' or Space eq 'EXHA-D' or Space eq 'EXHB-C' or Space eq 'EXHB-D' or Space eq 'EXHC-D') since I could not figure out how to search for Space starting with "EXH". I tried Space eq 'EXH%' but this did not work. Any ideas how to return any Space the starts with "EXH" ???
0 upvotes
Can you try contains(Space, 'EXH') or substringof('EXH', Space) or indexof(Space, 'EXH') gt -1
I'm not at my desk at the moment, but if you can't get it working, let me know and i'll figure it out- i'm sure i've done it before.
0 upvotes
(contains(Space, 'EXH') or substringof('EXH', Space) or indexof(Space, 'EXH') gt -1) Note that OData syntax is case sensitive. --Error: An unknown function with name 'contains' was found. This may also be a key lookup on a navigation property, which is not allowed.","Source":"ListData"}]}
0 upvotes
Did you try them "all together" or each on their own?
I meant them as different options, not to be used together :)
I just tested and this works for example:
0 upvotes
Please sign in to leave a comment.