Skip to main content

REST API - Search

Searching for Records

POST /api/models/{schemaName}/find

Request body

The overall format of the request body for the search typically follows the following structure:

{
"filter": {
<schema_primary_key>: "<val>",
<schema_key1>: "<val>",
...
<schema_keyN>: "<val>",
},
"options": {
"limit": 10,
"offset": 0,
"sort": [
{
<schema_key1>: <"asc"|"desc">
},
...
{
<schema_keyN>: <"asc"|"desc">
},
{
"created_at": <"asc"|"desc">
},
{
"updated_at": <"asc"|"desc">
},
{
"expires_at": <"asc"|"desc">
}
]
}
}

It consists of two main parts: filter and options.

filter

filter object is used to describe search criteria. Use keys defined in the Schema and build-in record_key key to construct the criteria. For the exact match search the following options are available:

note

Pay attention that comparing operations only available for Integer and Decimal fields.

  • single value
// Matches all records where record.first_name = 'John' AND record.age = 50
{ "first_name": "John", "age": 50 }
  • multiple values as an array
// Matches all records where (record.last_name = 'Bruce' OR record.last_name = 'Gates') AND (record.grade = 1 OR record.grade = 2)
{ "last_name": ["Bruce", "Gates"], "grade": [1, 2] }
  • a logical NOT operator for String fields
// Matches all records where record.last_name <> 'Bruce'
{ "last_name": { "$not": "Bruce" } }

// Matches all records where record.occupation <> 'assistant' AND record.occupation <> 'florist'
{ "occupation": { "$not": ["assistant", "florist"] } }
  • comparison operators for Integer fields
// Matches all records where record.salary >= 5000 AND record.salary <= 10000
{ "salary": { "$gte": 5000, "$lte": 10000 } }

Available comparison operators: $gt, $gte, $lt, $lte.

  • multiple criteria with $or operator:
{
"$or": [
{ "first_name": "john", "last_name": "smith" },
{ "first_name": "joe", "last_name": "bruce" }
]
}
{
"$or": [
{ "first_name": { "$like": "john" } },
{ "first_name": { "$like": "doe" } }
]
}
note

Currently, nested $or operators and non-string fields inside $or operator are not supported.

You can also look up for data records by partial match using the search_keys operator which performs partial match search (similar to the LIKE SQL operator, without special characters) within String keys.

// Matches all records where record.<string_key_1> LIKE 'foo' OR record.<string_key_2> LIKE 'foo' OR ... OR record.<string_key_N> LIKE 'foo'
{ "search_keys": "foo" }

Please note: The search_keys operator cannot be used in combination with any String key.

// Matches all records where (record.<string_key_1> LIKE 'abc' OR record.<string_key_2> LIKE 'abc' OR ... OR record.<string_key_N> LIKE 'abc') AND (record.grade = 1 OR record.grade = 2)
{ "search_keys": "abc", "grade": [1, 2] }

// Causes validation error
{ "search_keys": "abc", "first_name": "John" }

Another way to find records by partial key match is using $like operator. It provides a partial match search (similar to the LIKE SQL operator without special characters) against one of the record’s string fields.

// Matches all records where record.first_name LIKE 'Joh'
{ "first_name": { "$like": "Joh" } }

options

The options parameter provides the following choices to manipulate the search results:

limit allows to limit the total number of records returned; offset allows to specify the starting index used for records pagination; sort allows to sort the returned records by one or multiple keys.

The sort is an array of objects

{
sort: [{
[<string_schema_key>|<int_schema_key>|created_at|updated_at|expires_at]: <"asc"|"desc">
}, ...]

}
Example cURL requests
//FINDS A RECORD BY THE SPECIFIED CRITERIA

curl --location 'https://{restApiURLAddress}/api/users/find' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"filter": {
"phone": "213123"
},
"options": {
"limit": 10,
"offset": 0
}
}'

//FINDS USERS THAT HAVE YEARLY SPENDING MORE THAN 11000

curl --request POST \
--url 'https://{restApiURLAddress}/api/users/find' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"filter": {
"yearly_spending": {"$gt":1000}
},
"options": {
"limit": 10,
"offset": 0
}
}'

//FINDS RECORDS AND SORTS THEM BY FIELD IN ASCENDING/DESCENDING ORDER

curl --request POST \
--url 'https://{restApiURLAddress}/api/users/find' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"filter": {
"yearly_spending": [10000, 12000]
},
"options": {
"limit": 10,
"offset": 0,
"sort":[{"yearly_spending":"asc"}, {"last_name": "desc"}]
}
}'

Responses

STATUS 200 - application/json Returns information about the found record or records.

This status is also returned when no records matching the search criteria are found.

Example
{
"data": [
{
"record_key": "user1_primary_key",
"first_name": "John",
"last_name": "Smith",
"phone": "25534512",
"yearly_spending": 10000,
"attachments": [],
"created_at": "2021-03-26T11:57:45.000Z",
"updated_at": "2021-03-26T11:57:45.000Z"
}
],
"meta": {
"count": 1,
"limit": 10,
"offset": 0,
"total": 1
}
}

STATUS 400 - Incorrect filtration parameters or options have been specified.

STATUS 401 - Access is denied.

STATUS 401 - Partial text-match search is not enabled for InCountry Vault.

STATUS 409 - InCountry Vault for the country is not available.

STATUS 415 - An unsupported request content type.

STATUS 422 - Validation of input parameters has failed.

STATUS 429 - The number of allowed requests has been exceeded.

STATUS 5** - Server error.

Using JSON Field in Filters

You can use contents of a JSON field as a criteria in find requests. There is a notation to select a specific path within JSON field. In case you have a field named attributes with a content like this:

{
"privileged_access": true,
"roles": ["admin", "supervisor"],
"groups": ["sales", "management", "business development"]
}

And to find all the records with privileged access you might use a filter like this:

{
"filter": { "attributes": { "$.privileged_access": true } },
"options": { "limit": 10 }
}

You can use a valid JSON path limited to only path specifiers (no filters or operators allowed) as a key for the filter. In case you need to check if there is an item (or multiple) in the target array, the filter will look like this:

{
"filter": { "attributes": { "$.roles": "admin" } },
"options": { "limit": 10 }
}

The filter above will match all the records with a roles array that includes admin. The value could be an array, it that case, we will look for a record having all the requested items.

{
"filter": { "attributes": { "$.groups": ["management", "sales"] } },
"options": { "limit": 10 }
}

Aggregating Records

POST /api/models/{schemaName}/aggregate

The endpoint is utilized for aggregating data based on the specified metrics.

Please see the example of the request structure.

Example
{
"metrics": {
"<arbitrary name for the metric>": {
"func": "sum",
"key": "yearly_spending" // or other Integer/Decimal key from the schema
},
"users_count": {
"func": "count"
}
},
"filter": {
"yearly_spending": { "$gte": 5000 } // search for the records with yearly_spending >= 5000
},
"group_by": {
"limit": 100,
"keys": ["first_name"]
}
}

After the initial request, the cursor is returned to allow you to iterate over all the results. For subsequent requests, when the cursor is available, use the following request body format:

{
"next": "<cursor_val>"
}

Within the metrics section, you can define the aggregation parameters:

ArgumentDescription
metricNameNYou can declare the aggregated metric, for example, total_sales_amount, record_count, or total_revenue.
funcYou can define the aggregation function to apply: count - count records; does not accept additional params. sum - takes a Number field as a param; summarizes values against the specified field.
cURL request
curl --request POST \
--url 'https://{restApiURLAddress}/api/users/aggregate' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"metrics": {
"total_spending": { // arbitrary name for the metric
"func": "sum",
"key": "yearly_spending" // or other Integer/Decimal key from the schema
},
"users_count": {
"func": "count"
}
},
"filter": { // filter to apply.
"yearly_spending": { "$gte": 5000 } // search for the records with yearly_spending >= 5000
},
"group_by": {
"limit": 100,
"keys": [
"first_name"
]
}
}'

// For the subsequent requests, when `cursor` is available:

curl --request POST \
--url 'https://{restApiURLAddress}/api/users/aggregate' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--header 'Content-Type: application/json' \
--data '{
"cursor": <cursor value>
}'

Responses

STATUS 200 - JSON This response returns the results of aggregation and summarization.

Example
{
"meta": {
"next": "fgfUewn=="
},
"data": [
{
"group": {
"keys": {
"first_name": "John"
}
},
"metrics": {
"total_spending": 10000,
"users_count": 1
}
},
{
"group": {
"keys": {
"first_name": "Jake"
}
},
"metrics": {
"total_spending": 12000,
"users_count": 2
}
}
]
}

STATUS 400 - Incorrect filtration parameters or options have been specified.

STATUS 401 - Access is denied.

STATUS 401 - Partial text-match search is not enabled for InCountry Vault.

STATUS 409 - InCountry Vault for the country is not available.

STATUS 415 - An unsupported request content type.

STATUS 422 - Validation of input parameters has failed.

STATUS 429 - The number of allowed requests has been exceeded.

STATUS 5** - Server error.