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
Has anyone tried $select? I tried but it does not work. I am on API v1.
Or if there is another way to reduce the number of fields to return?
Edit: I am just trying through API Help.
0 upvotes
Currently the API returns the full model with no options to retrieve just the fields you want. This is already on our backlog to address.
0 upvotes
Has this been addressed yet?
0 upvotes
Kate - Yes, please take a look at this article: https://supportcenter.ungerboeck.com/hc/en-us/articles/360012928934-Customize-the-API-with-the-select-Operator-for-Custom-Objects
This will let you get only what you want want returned within an object. As an example, the 'Event' model has around 100 properties. Using the new feature you can return an Event object with only 3 properties if you wish. It will always return primary key columns regardless of what you specify.
Also, please consider using this when editing items as well, as you'll get a performance bump since we do not have re-fetch the entity being edited.
Thanks,
Craig
0 upvotes
Is there a way to return the event logo using API EV200_EVT_LOGO
We have tried but it does not find the field
0 upvotes
Hi Theresa,
There currently is not. You can see the available event fields on the event model in your API help page.
0 upvotes
If I were to request the registration orders from particular event ID, is there any way to include order account fields such as Name, Address, email, etc. in the results?
0 upvotes
Hi John,
Not directly. You would need to perform a followup GET for the account information.
0 upvotes
Hi,
I need to retrieve list of opportunities having particular value for user text 30. API returns error if my search query is simply like UserText30 eq 'Blah blah blah' under GET Opportunities/{OrgCode} API.
In this case, shall I use the method mentioned in Search in User Field? If so, what should be the value of [User field Class]|[User field Type] ?
Thanks so much.
Bryan
0 upvotes
Hi Bryan,
This link to an example might help you. It will show you a function that has an example of searching for User Fields on an opportunity.
Rudy
0 upvotes
I'm having problems trying to query opportunities using a UDF.
My query looks like:
https://ungerboeck/TEST/api/v1/Opportunities/10?search=Type eq 'AR|C' and EventJob eq 159134 and C|AR|10|UserNumber02 eq 475951.0
Does that look right?
It returns a seemingly random opportunity (for the correct event, but not with that udf value)
Trying just:
https://jcr.ungerboeck.net/TEST/api/v1/Opportunities/10?search=Type eq 'AR|C' and EventJob eq 159134 and UserNumber02 eq 475951.0
Returns an error saying the field is unknown or not searchable?
Rudy Scoggins
Thanks!
0 upvotes
Hi Lee,
Yes, your first URL's syntax looks correct.
I gave it a whirl myself and this was my example that pulled the correct opportunity:
'EventJob eq 13774 and C|01|10|UserNumber01 eq 13275.0000'
Can you modify the query parameters to maybe see what the problem is? Perhaps taking some away?
Rudy
0 upvotes
Something weird is going on because:
https://ungerboeck/TEST/api/v1/Opportunities/10?search=Type eq 'AR|C' and EventJob eq 159134 and C|AR|10|UserNumber02 eq 475951.0
Returns a single opportunity with UserNumber02 = null...
https://ungerboeck/TEST/api/v1/Opportunities/10?search=Type eq 'AR|C' and EventJob eq 159134
Returns a handful of opportunities, one of which has UserNumber02 = 475951.0
Could we possibly arrange a quick call to take a peak? The good thing is it's a hosted database so I hope you can debug quite easily.
I though I might have been able to switch tracing on, but I think this option might be disabled for hosted customers?
Thanks!
0 upvotes
Hi Lee,
Yeah, something seems contradictory here. Can you submit a ticket with the hosted customer info and support will take a look?
Thanks,
Rudy
0 upvotes
Hi Rudy,
The API docs show that JournalEntries model includes the journal entry details. When we've tested it, we don't seem to get the details back.
Do we need to do something special to get them?
Thanks
L
0 upvotes
Hey Lee,
Yeah, this would be an opt-in property for the Select parameter.
search=Year eq 2005$select=[JournalEntryDetails]
Check out this example for more info.
Thanks,
Rudy
0 upvotes
Hero- works a treat- thanks Rudy!
0 upvotes
Hello. I'm having problems with searching for accounts with special characters in the name. How do one encode characters like Ä,Ö,Ü,ß to make an call with the Ungeboeck API? I tried it with the unicode (utf-8) with several different escaping characters, but nothing worked.
Further how can I escape single quotes in the search string?
Has anyone a clue how to get around this problems?
Thanks for any advice.
David
0 upvotes
I think you escape single quotes with an additional single quote. So:
0 upvotes
Thanks for your reply. I tried it but did not work for me.
0 upvotes
Hi David, as the search parameters are used in the URI, you need to use URL Encoding.
Example, searching for an Account with the First Name 'öäü'
The API help page should be encoding the values for you, in case you already have challenges at this stage, we recommend creating a Support Case, or if you want to have a technical discussion, your Account Manager can set up a meeting with a Solution Developer.
0 upvotes
Hi Sven, thanks a lot for your reply. Now it worked for me. I tried the api calls with postman and not through the api help page. Thanks for the advice.
One more addition to my problem with single qoutes. The answer from Lee was correct. I noticed, that in the name I was searching in the database it wasn't used a single quote but an apostrophe (´) .
1 upvotes
Hi David, thanks for the update. In such a case, I recommend extracting the name from the software and running it through URL Encoding if not returned via an API search. As this will always give you more details on the character used by the user, there is always the option for a user input error.
0 upvotes
I'm using page_size and page as parameter, but the result is always the same. No matter whether I set the page_size e.g. to 100 oder 1000.
what am I doing wrong?
e.g. /api/v1/Events/10?search=true$page_size=100
0 upvotes
Hi Markus, I would recommend the following article on searching using the API: https://supportcenter.ungerboeck.com/hc/en-us/articles/115010610608-Search-Using-the-API
The "search=true" parameter is not supported. If you need assistance in building the search query, please reach out to your account manager to schedule a training session.
0 upvotes
Hi Sven, thanks for the quick response. But my problem was not "search=true" (actually search=all gives the same results). But thanks for the right syntax. --- My problem is the page size parameter: it just doesn't work. I always get the same result, no matter if I set the page size to 1, 100, 1000, etc. ?
0 upvotes
If the page_size can be reproduced, I suggest submitting a support ticket. This allows our product team to review why this is happening with your database.
0 upvotes
Hello. I am having trouble using the POST method of the JournalEntryDetails API endpoint.
The JournalEntry (Purchase Accrual) is created successfully but the POST JournalEntryDetails with payload similar to below
{"Organization":"10",
"Year":2023,
"Period":10,
"Source":"PA",
"EntryNumber":"0000804",
"Status":"N",
"Date":"2023-11-17T14:23:08.773Z",
"Description":"Big Chairs",
"Amount":52080.0000,
"GLAccount":"0102033304567",
"Reference":"PO_ID 10204054",
"Event":12345,
"Account":"01010203",
"Department":"1234"}
fails with error
-- System.ArgumentNullException: 'column' argument cannot be null.Parameter name: column at System.Data.DataRow.CheckColumn(DataColumn column) at System.Data.DataRow.get_Item(DataColumn column) at Ungerboeck.Common.StdFuncs.GetDateColumnValue(DataRow arow, String astrColumnName, DataRowVersion aobjModifiedRowVersion, DataColumn aobjColumn, Boolean& ablnIsNull) in C:\AzureBuildAgents\USSTL-PATCH_1\_work\4\s\Base Services\USIBAS00\stdfuncs.vb:line 9036 at Ungerboeck.Common.StdFuncs.GetDateColumnVa...
Any help or suggestions would be greatly appreciated. Thank you.
0 upvotes
Hi Phil,
I have submitted this bug to our development department to fix. It should show a more informative message.
In the meantime, my quick tests show this error might occur if the EntryNumber value isn't found. Can you double check if it exists and try again?
Rudy
0 upvotes
Thanks for looking into this Rudy and for progressing it to the development team.
I can confirm that the EntryNumber is valid, having just previously successfully created the Journal Entry.
0 upvotes
Please sign in to leave a comment.