Skip to main content
POST
/
v1
/
{indexAlias}
Query items
curl --request POST \
  --url https://query.enterspeed.com/v1/{indexAlias} \
  --header 'Content-Length: <content-length>' \
  --header 'Content-Type: application/json' \
  --header 'X-Api-Key: <x-api-key>' \
  --data '
{
  "filters": {
    "and": [
      {
        "field": "title",
        "operator": "contains",
        "value": "*hoodie*",
        "caseInsensitive": true
      },
      {
        "or": [
          {
            "field": "isInStock",
            "operator": "equals",
            "value": true
          },
          {
            "field": "allowPreorder",
            "operator": "equals",
            "value": true
          }
        ]
      }
    ]
  },
  "aliases": [
    "productTile"
  ],
  "facets": [
    {
      "name": "Categories",
      "field": "category",
      "size": 20
    },
    {
      "name": "In Stock",
      "field": "isInStock"
    }
  ],
  "sort": [
    {
      "field": "price",
      "order": "asc"
    }
  ],
  "pagination": {
    "page": 0,
    "pageSize": 20
  }
}
'
{
  "status": 0,
  "totalResults": 200,
  "results": [
    {
      "sku": "p-5427",
      "name": "Running shoe",
      "url": "/products/running-shoe/",
      "_originId": "p-5427",
      "_sourceGuid": "9f741916-19e3-4791-9ebd-701634ba9b75",
      "_updatedAt": "2025-01-07T08:43:15.7351089Z",
      "_views": {
        "productTile": {
          "sku": "p-5427",
          "name": "Running shoe",
          "url": "/products/running-shoe/",
          "image": "/media/running-shoe.webp",
          "shortDescription": "My short description of the product",
          "price": 199.99
        }
      }
    }
  ],
  "facets": [
    {
      "name": "Categories",
      "field": "category",
      "groups": [
        {
          "value": "Caps",
          "count": 8
        },
        {
          "value": "Hoodies",
          "count": 2
        }
      ],
      "isValid": true
    }
  ],
  "nextPageToken": "WyIyMDI0LTAxLTAxIiwiYWJjMTIzIl0="
}

Headers

X-Api-Key
string
required

Api key to validate your environment.

Example:

"environment-1637c4d0-e878-4738-b866-152106a4f88c"

Content-Length
number
required

The length of the message body, in bytes (this header is automatically added by most clients).

Path Parameters

indexAlias
string
required

The alias of the index to be queried.

Example:

"productIndex"

Body

application/json

The query object including things like filters, sorting and pagination.

All root properties like, filters, sort, pagination and facets are optional.

Filters

filters are nested in one or two levels grouped in and or or.

"filters": {
  "and":  [
    {
      "field": "title",
      "operator": "equals",
      "value": "Enterspeed Hoodie"
    }
  ]
}
"filters": {
  "or":  [
    {
      "field": "isInStock",
      "operator": "equals",
      "value": true
    },
    {
      "field": "allowPreorder",
      "operator": "equals",
      "value": true
    }
  ]
}
"filters": {
  "and":  [
    {
      "field": "title",
      "operator": "equals",
      "value": "Enterspeed Hoodie"
    },
    {
      "or": [
        {
          "field": "isInStock",
          "operator": "equals",
          "value": true
        },
        {
          "field": "allowPreorder",
          "operator": "equals",
          "value": true
        }
      ]
    }
  ]
}

Operators

equals

{
  "field": "title",
  "operator": "equals",
  "value": "Enterspeed Hoodie",
  "caseInsensitive": true
}

notEquals

{
  "field": "title",
  "operator": "notEquals",
  "value": "Enterspeed Hoodie",
  "caseInsensitive": true
}

contains

Working on text or text list fields, it's possible to use wildcard annotations * if you want to query the fields only for specific words or sentences, no matter what comes before and after the phrase you search for. It's also possible to set if the search should be case insentitive by setting caseInsensitive to true.

{
  "field": "title",
  "operator": "contains",
  "value": "*hoodie*",
  "caseInsensitive": true
}

Working on list fields on the other hand, the contains operator performs an equals on the list items, which will look for an exact match within the list. If working on text lists, it's also possible here to set if the search should be case insentitive by setting caseInsensitive to true as above.

{
  "field": "categories",
  "operator": "contains",
  "value": "Hoodies",
  "caseInsensitive": true
}

greaterThan

{
  "field": "price",
  "operator": "greaterThan",
  "value": 100
}

greaterThanOrEquals

{
  "field": "price",
  "operator": "greaterThanOrEquals",
  "value": 100
}

lessThan

{
  "field": "price",
  "operator": "lessThan",
  "value": 100
}

lessThanOrEquals

{
  "field": "price",
  "operator": "lessThanOrEquals",
  "value": 100
}

in

{
  "field": "tag",
  "operator": "in",
  "value": ["shoes", "caps", "pants"],
}

Sorting

sort is an array of objects defining the sort order. Each object defines the property to sort on and the direction.

If you have multiple sorting object the sorting will be in the order of the object. In the example below it would mean: first sort by isInStock in descending order and then by title in ascending order.

Default values

field: _updatedAt
order: desc

For custom sorting, default order is asc.

"sort": [
  {
    "field": "isInStock",
    "order": "desc"
  },
  {
    "field": "title",
    "order": "asc"
  }
]

Pagination

pagination supports two modes: offset-based and token-based.

Default values

page: 0
pageSize: 10

Offset-based pagination

Use page and pageSize to paginate by offset. The total number of reachable items is limited to 10.000 (from + pageSize). The maximum page size is 1.000. Use this method when you need to display the current page number, allow users to jump to a specific page, or navigate back to previous pages.

"pagination": {
  "page": 0,
  "pageSize": 20
}

Token-based pagination

Use nextPageToken to paginate beyond the 10.000-item offset limit, or for more efficient iteration over large result sets. The token is returned in every response and is null when no further results exist. Pass it back in the next request to retrieve the next page. page is ignored when nextPageToken is provided. Use this method for integrations and bulk processing where you need to iterate the full result set — note that it does not expose the current page number or support navigating back to a previous page.

First request — omit the token to get the first page:

"pagination": {
  "pageSize": 100
}

Response — includes nextPageToken alongside results:

{
  "totalResults": 5000,
  "results": [...],
  "nextPageToken": "WyIyMDI0LTAxLTAxIiwiYWJjMTIzIl0="
}

Subsequent requests — pass the token to get the next page:

"pagination": {
  "pageSize": 100,
  "nextPageToken": "WyIyMDI0LTAxLTAxIiwiYWJjMTIzIl0="
}

Repeat until nextPageToken is null.

Token scoping — a nextPageToken is tied to the index it was issued for. Using it against a different index alias returns an Invalid nextPageToken error. Always use the token with the same index it came from.

Last page behaviour — when the total number of results is an exact multiple of pageSize, the final page returns a full set of results with a non-null token. One additional request is needed to confirm there are no more results; that request returns an empty results array and a null token. This is expected — treat an empty response with null token as end-of-results, not an error.

Aliases

Using aliases in the query will return views for the provided schema aliases for each item in the result. The specific views returned for each item is the view created by the same source entity as the item. As views are returned, only schema aliases of full schemas are supported, as it's the only schema type that's creating views.

This allows you to return different views for the same index. E.g. a productTile view or a productDetails view for a product index, whitout having to add all presentation data for both views to the index. You only need the data to filter and sort on.

"aliases": ["productTile"]

Facets

Using facets in the query allows for aggregated groupings of fields values used for facets.

A facet is requested by a required field name to do the aggregation on. There are options to add an optional name for the facet, and an optional size field to adjust the number of aggregated values returned - the size defaults to 10 and has a maximum of 100. The returned aggregated values are sorted by highest count first, i.e., requesting with a size of 5 would return the 5 facets with the highest count.

All index schema types are supported for facet aggregation except the following: object, integerRange, longRange, floatRange, doubleRange and dateRange.

Default values

name: The value of field
size: 10

"facets": [
  {
    "name": "Categories",
    "field": "category",
    "size": 20
  },
  {
    "field": "isInStock"
  }
]

Response

Valid request.

status
number
Example:

0

totalResults
number

The total number of results matched by query.

Example:

200

results
object[]

List of items from the index matched by the query provided.

Built in fields are prefixed with underscore (_).

facets
object[]

List of aggregated field values based on the requested facet fields.

nextPageToken
string | null

Continuation token for the next page of results. Pass this value in the pagination.nextPageToken field of the next request. null when no further results exist.

Example:

"WyIyMDI0LTAxLTAxIiwiYWJjMTIzIl0="