Query
Query
A query narrows a list of entries, or of assets, to the items whose fields match the conditions you set. Use this class to
- match field values with comparisons, value lists, patterns, and existence checks
- filter entries by the entries their reference fields point to
- combine conditions with $and and $or
- sort, page, and run the request
query() takes one optional argument:
| Name | Type | Description |
|---|---|---|
| queryObj | { [key: string]: any } | Raw conditions to start with. Accepted by entry().query() only. |
Get a Query from stack.contentType('<CONTENT_TYPE_UID>').entry().query() to filter entries, or from stack.asset().query() to filter assets. The package exports Query as a type only, so you can annotate a variable with it, but you get instances from these two calls. stack.taxonomy() returns a TaxonomyQuery, which extends Query. The Taxonomy class page covers it.
addParams
addParams merges several query parameters into the request at once.
| Name | Type | Description |
|---|---|---|
| paramObj (required) | { [key: string]: string | boolean | number } | Query parameter names mapped to their values. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. addParams accepts any key, including keys that other methods set.
- Errors surface on the find() call that follows, not on addParams(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. addParams merges the keys into the stored query parameters and makes no request. A key that already exists takes the new value.
- addParams builds a new parameter object instead of changing the existing one. From that point, the query no longer shares its parameters with the Entries that created it. See Shared state on the Query class page.
- The values become query parameters, not filter conditions. Use the filter methods, such as where, for conditions.
Example
Basic usage: set two parameters at once
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('title')
.addParams({ locale: 'en-us', include_count: true })
.find();
console.log(result.count, result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}and
and matches entries that satisfy all of the given queries.
| Name | Type | Description |
|---|---|---|
| queries (required) | Query[] | Queries whose conditions to combine with $and. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. A call with no arguments compiles and sends an empty list.
- On an entry query, the API ignores the empty list and returns every entry that the other conditions match.
- On an asset query, the API rejects the empty list with status 400 and error_code 141. TypeScript rejects an argument that is not a Query.
- Errors surface on the find() call that follows, not on and(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. and collects the conditions of each query into a list, stores it under the $and key, and makes no request. find sends the conditions as the query parameter.
- A second and call replaces the first list, because the SDK stores it under one key. Pass every query in one call.
- The list sits beside the query's other conditions. Field conditions on the outer query still apply to every result.
- Only the sub-queries' conditions travel. Their content types and parameters play no part.
- Known issue: In 5.x, two queries from one Entries object share their conditions. Build each sub-query from its own entry() call, as Shared state on the Query class page describes.
- The queryOperator method does the same, with the operator passed as an argument.
Example
Basic usage: combine two conditions with $and
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const byTitle = stack.contentType('<CONTENT_TYPE_UID>').entry().query().equalTo('title', 'Home');
const byDate = stack.contentType('<CONTENT_TYPE_UID>').entry().query().greaterThan('updated_at', '2026-01-01');
const result = await stack.contentType('<CONTENT_TYPE_UID>').entry().query().and(byTitle, byDate).find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Two conditions on one field: match a date range
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
// Two filters on one field in one query would replace each other, so combine two queries.
const after = stack.contentType('<CONTENT_TYPE_UID>').entry().query().greaterThanOrEqualTo('updated_at', '2026-01-01');
const before = stack.contentType('<CONTENT_TYPE_UID>').entry().query().lessThan('updated_at', '2026-07-01');
const result = await stack.contentType('<CONTENT_TYPE_UID>').entry().query().and(after, before).find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}containedIn
containedIn matches entries whose field value equals one of the values in an array.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to filter. |
| value (required) | (string | number | boolean)[] | Values the field may equal. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, containedIn logs an error and drops the condition on invalid input. key must hold only letters, digits, underscores, periods, and hyphens, and value must be an array of strings, numbers, or booleans. Check both before you pass them.
- TypeScript rejects a value of another type at compile time, so the runtime check matters only for a value typed as any.
- An empty array passes the check. The API then matches no item.
- Errors surface on the find() call that follows, not on containedIn(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. containedIn stores { <key>: { $in: <value> } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- The notContainedIn method does the opposite.
Example
Basic usage: match entries with one of several titles
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.containedIn('title', ['Home', 'About', 'Contact'])
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}equalTo
equalTo matches entries whose field value equals the given value.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to filter. |
| value (required) | string | number | boolean | Value to compare the field against. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, equalTo logs an error and drops the condition when key holds a character other than letters, digits, underscores, periods, and hyphens. Check the field UID before you pass it.
- Known issue: In 5.x, equalTo accepts boolean in its type, but logs an error and drops the condition for a true or false value. Use where(key, QueryOperation.EQUALS, true) for a boolean field.
- Errors surface on the find() call that follows, not on equalTo(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. equalTo stores { <key>: <value> } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- The notEqualTo method does the opposite.
Example
Basic usage: match entries with an exact title
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.equalTo('title', 'Home')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Boolean field: use where instead
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
// equalTo('is_featured', true) compiles but drops the condition at runtime.
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.where('is_featured', QueryOperation.EQUALS, true)
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}exists
exists matches entries that have the named field.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to check. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, exists logs an error and drops the condition when key holds a character other than letters, digits, underscores, periods, and hyphens. Check the field UID before you pass it.
- Errors surface on the find() call that follows, not on exists(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. exists stores { <key>: { $exists: true } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- The notExists method does the opposite.
Example
Basic usage: match entries that have a title
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('title')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}find
find sends the request and returns the entries or assets that match the query.
| Name | Type | Description |
|---|---|---|
| encode | boolean | Percent-encodes string values in the conditions first. See Limitations. |
Returns: Promise<FindResponse<T>>. The matching entries or assets.
Validation
- There is no client-side validation. find sends whatever conditions and parameters the query holds.
- find throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
- An unknown content type UID throws status 422 with error_code 118.
- A network failure throws status 0, with the Node error code (for example ENOTFOUND) in error_code.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- One call sends one request and returns one page. The SDK does not iterate pages. See Pagination on the Query class page.
- Which endpoint find calls depends on where the query came from.
- From entry().query(): GET /content_types/{content_type_uid}/entries, with the results in entries.
- From asset().query(): GET /assets, with the results in assets.
- find returns the whole response body as a FindResponse<T>. Each key is optional, because the API includes only what you asked for. count appears when you chain includeCount.
- find is generic. Pass an interface as T, for example one that extends the exported BaseEntry, to type each result. The SDK does not check the response against T.
- find sends the conditions as the query parameter only when the query holds at least one. The parameters set by methods such as limit travel as separate query parameters.
- encode acts only on the conditions.
- When the Entries that created the query held variant UIDs, find sends the x-cs-variant-uid header, plus the branch header when the Entries also held a branch name.
Limitations
- Does not return every match when you omit limit. For entries, the default page size is 100 entries, and the maximum page size is 250 entries. Chain the includeCount method and page with skip and limit.
- Known issue: In 5.x, find(true) can return no results for a value that contains a space or a symbol such as & or /. It also breaks conditions that hold a list, such as containedIn, tags, and and or. Call find() instead.
Example
Basic usage: run a query against entries
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.equalTo('title', 'Home')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Typed result: read matches into your own interface
import contentstack from '@contentstack/delivery-sdk';
import type { BaseEntry } from '@contentstack/delivery-sdk';
interface BlogPost extends BaseEntry {
url: string;
}
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('url')
.find<BlogPost>();
result.entries?.forEach((post) => console.log(post.title, post.url));
} catch (error: any) {
console.error(error);
}All parameters: leave encode off
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.equalTo('title', 'Home & Garden')
.find(false);
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}Assets: run a query against assets
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack.asset().query().where('content_type', QueryOperation.EQUALS, 'image/png').find();
console.log(result.assets?.length);
} catch (error: any) {
console.error(error);
}getQuery
getQuery returns the filter conditions the query holds, in the JSON form that find sends.
Returns: object. The conditions the query holds.
Validation
- There is no validation. getQuery takes no input and makes no request, so it cannot fail.
Behavior
- Client-side only. getQuery reads local state and makes no request.
- The declared return type is { [key: string]: any }. The object holds the conditions that find sends as the query parameter.
- It returns the live object, not a copy. Changing the returned object changes the query.
- It holds filter conditions only. Parameters such as limit, locale, or the typeahead term from search are not in it.
- On a query from entry().query(), the object is the same one the Entries holds. See Shared state on the Query class page.
Example
Basic usage: inspect the conditions before sending the request
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
const query = stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.equalTo('title', 'Home')
.greaterThanOrEqualTo('updated_at', '2026-01-01');
console.log(JSON.stringify(query.getQuery()));
// {"title":"Home","updated_at":{"$gte":"2026-01-01"}}greaterThan
greaterThan matches entries whose field value is greater than the given value.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to filter. |
| value (required) | string | number | Value to compare the field against. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, greaterThan logs an error and drops the condition on invalid input. key must hold only letters, digits, underscores, periods, and hyphens, and value must be a string or a number. Check both before you pass them.
- TypeScript rejects a value of another type at compile time.
- Errors surface on the find() call that follows, not on greaterThan(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. greaterThan stores { <key>: { $gt: <value> } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- greaterThan sends value unchanged, as a string or a number. The SDK does not convert a date string.
- On a date field such as updated_at, the API compares an ISO 8601 string in date order. A date without a time, such as '2026-01-01', stands for midnight UTC at the start of that day.
Example
Basic usage: compare a date field
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.greaterThan('updated_at', '2026-01-01')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Numeric field: compare a number
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.greaterThan('price', 10)
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}greaterThanOrEqualTo
greaterThanOrEqualTo matches entries whose field value is greater than or equal to the given value.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to filter. |
| value (required) | string | number | Value to compare the field against. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, greaterThanOrEqualTo logs an error and drops the condition on invalid input. key must hold only letters, digits, underscores, periods, and hyphens, and value must be a string or a number. Check both before you pass them.
- TypeScript rejects a value of another type at compile time.
- Errors surface on the find() call that follows, not on greaterThanOrEqualTo(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. greaterThanOrEqualTo stores { <key>: { $gte: <value> } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- greaterThanOrEqualTo sends value unchanged, as a string or a number. The SDK does not convert a date string.
- On a date field such as updated_at, the API compares an ISO 8601 string in date order. A date without a time, such as '2026-01-01', stands for midnight UTC at the start of that day.
Example
Basic usage: compare a date field
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.greaterThanOrEqualTo('updated_at', '2026-01-01')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Numeric field: compare a number
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.greaterThanOrEqualTo('price', 10)
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}includeCount
includeCount adds the total number of matching items to the find response.
Returns: Query. The same query, for chaining.
Validation
- Errors surface on the find() call that follows, not on includeCount(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. includeCount sets the include_count query parameter to 'true' and makes no request. find then returns a count key beside the results.
- count is the total number of items that match the conditions, not the number on this page. Compare it with the length of entries or assets to find out whether more pages remain.
- Calling it twice changes nothing. The SDK stores the flag under one key.
Example
Basic usage: count the matching entries
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('title')
.includeCount()
.find();
console.log('matches:', result.count, 'on this page:', result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}lessThan
lessThan matches entries whose field value is less than the given value.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to filter. |
| value (required) | string | number | Value to compare the field against. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, lessThan logs an error and drops the condition on invalid input. key must hold only letters, digits, underscores, periods, and hyphens, and value must be a string or a number. Check both before you pass them.
- TypeScript rejects a value of another type at compile time.
- Errors surface on the find() call that follows, not on lessThan(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. lessThan stores { <key>: { $lt: <value> } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- lessThan sends value unchanged, as a string or a number. The SDK does not convert a date string.
- On a date field such as updated_at, the API compares an ISO 8601 string in date order. A date without a time, such as '2026-01-01', stands for midnight UTC at the start of that day.
Example
Basic usage: compare a date field
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.lessThan('updated_at', '2026-01-01')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Numeric field: compare a number
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.lessThan('price', 100)
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}lessThanOrEqualTo
lessThanOrEqualTo matches entries whose field value is less than or equal to the given value.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to filter. |
| value (required) | string | number | Value to compare the field against. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, lessThanOrEqualTo logs an error and drops the condition on invalid input. key must hold only letters, digits, underscores, periods, and hyphens, and value must be a string or a number. Check both before you pass them.
- TypeScript rejects a value of another type at compile time.
- Errors surface on the find() call that follows, not on lessThanOrEqualTo(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. lessThanOrEqualTo stores { <key>: { $lte: <value> } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- lessThanOrEqualTo sends value unchanged, as a string or a number. The SDK does not convert a date string.
- On a date field such as updated_at, the API compares an ISO 8601 string in date order. A date without a time, such as '2026-01-01', stands for midnight UTC at the start of that day.
Example
Basic usage: compare a date field
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.lessThanOrEqualTo('updated_at', '2026-01-01')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Numeric field: compare a number
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.lessThanOrEqualTo('price', 100)
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}limit
limit caps the number of items the response contains.
| Name | Type | Description |
|---|---|---|
| key (required) | number | Maximum number of items to return. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. The SDK sends zero, a negative number, or a fraction as given.
- Errors surface on the find() call that follows, not on limit(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. limit sets the limit query parameter and makes no request. find sends it.
- Omitting limit does not return every match. For entries, the default page size is 100 entries. See Pagination on the Query class page.
- For entries, the API returns at most 250 per request. It caps a larger value at 250 and does not reject it.
- Calling it twice replaces the first value. The paginate method also writes limit, so whichever runs last sets the value.
Example
Basic usage: return at most ten matching entries
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('title')
.limit(10)
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}notContainedIn
notContainedIn matches entries whose field value equals none of the values in an array.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to filter. |
| value (required) | (string | number | boolean)[] | Values the field must not equal. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, notContainedIn logs an error and drops the condition on invalid input. key must hold only letters, digits, underscores, periods, and hyphens, and value must be an array of strings, numbers, or booleans. Check both before you pass them.
- TypeScript rejects a value of another type at compile time, so the runtime check matters only for a value typed as any.
- An empty array passes the check. The API then excludes nothing, so every item matches.
- Errors surface on the find() call that follows, not on notContainedIn(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. notContainedIn stores { <key>: { $nin: <value> } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- The containedIn method does the opposite.
Example
Basic usage: leave out entries with certain titles
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.notContainedIn('title', ['Home', 'About'])
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}notEqualTo
notEqualTo matches entries whose field value differs from the given value.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to filter. |
| value (required) | string | number | boolean | Value to compare the field against. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, notEqualTo logs an error and drops the condition when key holds a character other than letters, digits, underscores, periods, and hyphens. Check the field UID before you pass it.
- Known issue: In 5.x, notEqualTo accepts boolean in its type, but logs an error and drops the condition for a true or false value. Use where(key, QueryOperation.NOT_EQUALS, true) for a boolean field.
- Errors surface on the find() call that follows, not on notEqualTo(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. notEqualTo stores { <key>: { $ne: <value> } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- The equalTo method does the opposite.
Example
Basic usage: leave out entries with one title
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.notEqualTo('title', 'Home')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Boolean field: use where instead
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
// notEqualTo('is_featured', true) compiles but drops the condition at runtime.
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.where('is_featured', QueryOperation.NOT_EQUALS, true)
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}notExists
notExists matches entries that do not have the named field.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID or dotted path of the field to check. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, notExists logs an error and drops the condition when key holds a character other than letters, digits, underscores, periods, and hyphens. Check the field UID before you pass it.
- Errors surface on the find() call that follows, not on notExists(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. notExists stores { <key>: { $exists: false } } and makes no request. find sends the conditions as the query parameter.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- The exists method does the opposite.
Example
Basic usage: match entries without a summary
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.notExists('summary')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}or
or matches entries that satisfy at least one of the given queries.
| Name | Type | Description |
|---|---|---|
| queries (required) | Query[] | Queries whose conditions to combine with $or. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. A call with no arguments compiles and sends an empty list.
- On an entry query, the API ignores the empty list and returns every entry that the other conditions match.
- On an asset query, the API rejects the empty list with status 400 and error_code 141. TypeScript rejects an argument that is not a Query.
- Errors surface on the find() call that follows, not on or(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. or collects the conditions of each query into a list, stores it under the $or key, and makes no request. find sends the conditions as the query parameter.
- A second or call replaces the first list, because the SDK stores it under one key. Pass every query in one call.
- The list sits beside the query's other conditions. Field conditions on the outer query still apply to every result.
- Only the sub-queries' conditions travel. Their content types and parameters play no part.
- Known issue: In 5.x, two queries from one Entries object share their conditions. Build each sub-query from its own entry() call, as Shared state on the Query class page describes.
- The queryOperator method does the same, with the operator passed as an argument.
Example
Basic usage: combine two conditions with $or
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const byTitle = stack.contentType('<CONTENT_TYPE_UID>').entry().query().equalTo('title', 'Home');
const byDate = stack.contentType('<CONTENT_TYPE_UID>').entry().query().greaterThan('updated_at', '2026-01-01');
const result = await stack.contentType('<CONTENT_TYPE_UID>').entry().query().or(byTitle, byDate).find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}orderByAscending
orderByAscending sorts the matching items in ascending order of the named field.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID of the field to sort by. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. The SDK sends an empty string or an unknown field UID as given.
- Errors surface on the find() call that follows, not on orderByAscending(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. orderByAscending sets the asc query parameter to the field UID and makes no request. find sends it.
- Without a sort method, the API applies its own default order.
- orderByAscending does not clear a sort that the orderByDescending method set, which uses a different key. Call the removeParam method with 'desc' to drop it.
Limitations
- Does not sort by more than one field. A second call replaces the first field, because the SDK stores it under one key.
Example
Basic usage: sort matching entries in ascending order
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('title')
.orderByAscending('updated_at')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}orderByDescending
orderByDescending sorts the matching items in descending order of the named field.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID of the field to sort by. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. The SDK sends an empty string or an unknown field UID as given.
- Errors surface on the find() call that follows, not on orderByDescending(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. orderByDescending sets the desc query parameter to the field UID and makes no request. find sends it.
- Without a sort method, the API applies its own default order.
- orderByDescending does not clear a sort that the orderByAscending method set, which uses a different key. Call the removeParam method with 'asc' to drop it.
Limitations
- Does not sort by more than one field. A second call replaces the first field, because the SDK stores it under one key.
Example
Basic usage: sort matching entries in descending order
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('title')
.orderByDescending('updated_at')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}param
param sets one query parameter on the request.
| Name | Type | Description |
|---|---|---|
| key (required) | string | Name of the query parameter. |
| value (required) | string | number | Value to send for the parameter. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. param accepts any key, including keys that other methods set.
- Errors surface on the find() call that follows, not on param(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. param stores the value under key and makes no request. find sends it as a query parameter, not as a filter condition.
- A key that already exists takes the new value, whichever method set it. For example, param('limit', 5) replaces an earlier limit(10).
- Use param for an API parameter that has no method of its own. To set several keys at once, use the addParams method.
Example
Basic usage: set one query parameter
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('title')
.param('locale', 'en-us')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}queryOperator
queryOperator combines the conditions of several queries with the $and or $or operator that you choose.
| Name | Type | Description |
|---|---|---|
| queryType (required) | QueryOperator | QueryOperator.AND or QueryOperator.OR. |
| queryObjects (required) | Query[] | Queries whose conditions to combine. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. A call with no queries compiles and sends an empty list.
- On an entry query, the API ignores the empty list and returns every entry that the other conditions match.
- On an asset query, the API rejects the empty list with status 400 and error_code 141.
- Errors surface on the find() call that follows, not on queryOperator(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. queryOperator collects the conditions of each query into a list, stores it under the queryType key, and makes no request. find sends the conditions as the query parameter.
- QueryOperator.AND writes $and, which matches entries that satisfy every query.
- QueryOperator.OR writes $or, which matches entries that satisfy at least one query.
- A second call with the same operator replaces the first list. $and and $or use different keys, so one of each can coexist.
- queryOperator(QueryOperator.AND, ...) stores the same condition as the and method, and QueryOperator.OR the same as the or method.
- Known issue: In 5.x, two queries from one Entries object share their conditions. Build each sub-query from its own entry() call, as Shared state on the Query class page describes.
Example
Basic usage: match entries that satisfy either condition
import contentstack, { QueryOperator } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const home = stack.contentType('<CONTENT_TYPE_UID>').entry().query().equalTo('title', 'Home');
const about = stack.contentType('<CONTENT_TYPE_UID>').entry().query().equalTo('title', 'About');
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.queryOperator(QueryOperator.OR, home, about)
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}All parameters: require every condition with AND
import contentstack, { QueryOperator } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const titled = stack.contentType('<CONTENT_TYPE_UID>').entry().query().exists('title');
const recent = stack.contentType('<CONTENT_TYPE_UID>').entry().query().greaterThan('updated_at', '2026-01-01');
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.queryOperator(QueryOperator.AND, titled, recent)
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}referenceIn
referenceIn matches entries whose reference field points to entries that match a sub-query.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID of the reference field to filter. |
| query (required) | Query | Query whose conditions the referenced entries must match. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, referenceIn logs an error and drops the condition when key holds a character other than letters, digits, underscores, periods, and hyphens. Check the field UID before you pass it.
- The whereIn method throws on the same input instead.
- The SDK does not check that query holds conditions. An empty sub-query sends an empty $in_query object.
- Errors surface on the find() call that follows, not on referenceIn(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. referenceIn stores { <key>: { $in_query: <conditions of query> } } and makes no request. find sends the conditions as the query parameter.
- Only the sub-query's conditions travel. Its content type, its parameters such as limit, and its variants play no part, and the SDK never sends a request for it.
- referenceIn stores a reference to the sub-query's conditions, not a copy. A filter you add to the sub-query after the call still reaches the request.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- Known issue: In 5.x, two queries from one Entries object share their conditions. Build the sub-query from its own entry() call, as Shared state on the Query class page describes.
- On an asset query, the API rejects the condition with status 400 and error_code 141.
Example
Basic usage: match entries whose author is a named author
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
// The sub-query only supplies conditions. The SDK never sends a request for it.
const authors = stack.contentType('author').entry().query().where('title', QueryOperation.EQUALS, 'John Doe');
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.referenceIn('author', authors)
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}referenceNotIn
referenceNotIn matches entries whose reference field points to entries that do not match a sub-query.
| Name | Type | Description |
|---|---|---|
| key (required) | string | UID of the reference field to filter. |
| query (required) | Query | Query whose conditions the referenced entries must not match. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, referenceNotIn logs an error and drops the condition when key holds a character other than letters, digits, underscores, periods, and hyphens. Check the field UID before you pass it.
- The whereNotIn method throws on the same input instead.
- The SDK does not check that query holds conditions. An empty sub-query sends an empty $nin_query object.
- Errors surface on the find() call that follows, not on referenceNotIn(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. referenceNotIn stores { <key>: { $nin_query: <conditions of query> } } and makes no request. find sends the conditions as the query parameter.
- Only the sub-query's conditions travel. Its content type, its parameters such as limit, and its variants play no part, and the SDK never sends a request for it.
- referenceNotIn stores a reference to the sub-query's conditions, not a copy. A filter you add to the sub-query after the call still reaches the request.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- Known issue: In 5.x, two queries from one Entries object share their conditions. Build the sub-query from its own entry() call, as Shared state on the Query class page describes.
- On an asset query, the API rejects the condition with status 400 and error_code 141.
Example
Basic usage: match entries whose author is not a named author
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
// The sub-query only supplies conditions. The SDK never sends a request for it.
const authors = stack.contentType('author').entry().query().where('title', QueryOperation.EQUALS, 'John Doe');
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.referenceNotIn('author', authors)
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}regex
regex matches entries whose field value matches a regular expression.
| Name | Type | Description |
|---|---|---|
| fieldUid (required) | string | UID or dotted path of the field to match. |
| regexPattern (required) | string | Regular expression the field value must match. |
| options | string | Regex options, such as i for case-insensitive. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, regex logs an error and drops the condition when fieldUid holds a character other than letters, digits, underscores, periods, and hyphens. Check the field UID before you pass it.
- regex throws an Error at the call when regexPattern fails its check, because the SDK refuses to send a pattern it cannot validate. The check fails in two cases:
- The pattern is empty or holds a character outside the allowed set: ASCII letters, digits, spaces, regex metacharacters, and common punctuation. Tabs, newlines, and non-ASCII letters such as é fail.
- The pattern does not compile as a JavaScript regular expression, for example (unclosed.
- The SDK does not check options.
- API and network errors surface on the find() call that follows, not on regex(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. regex stores { <fieldUid>: { $regex: <regexPattern> } }, plus $options when you pass options, and makes no request. find sends the conditions as the query parameter.
- The API runs the match. The SDK compiles the pattern only to check it.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
Limitations
- Does not accept a pattern with non-ASCII letters, tabs, or newlines. Use the where method with QueryOperation.MATCHES instead, which stores the same condition without the pattern check.
Example
Basic usage: match titles that start with a word
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.regex('title', '^Home')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}All parameters: match case-insensitively
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.regex('title', '^home', 'i')
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}Error handling: an invalid pattern throws before any request
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
const query = stack.contentType('<CONTENT_TYPE_UID>').entry().query();
try {
query.regex('title', '(unclosed');
} catch (error: any) {
// Thrown by regex() itself, because the pattern does not compile.
console.error('Invalid pattern:', error.message);
}removeParam
removeParam deletes one query parameter from the request.
| Name | Type | Description |
|---|---|---|
| key (required) | string | Name of the query parameter to delete. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. Removing a key that the chain never set does nothing.
- Errors surface on the find() call that follows, not on removeParam(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. removeParam deletes key from the stored query parameters and makes no request.
- removeParam clears parameters such as limit, include_count, or the typeahead term from search.
Limitations
- Does not clear a filter condition, because the SDK stores conditions apart from parameters. Call entry() or asset() again to build a query without the condition.
- Does not remove the environment parameter, because the stack configuration sends that value on every request. Create a second stack with another environment to read from a different environment.
Example
Basic usage: drop the search term before sending
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.search('home')
.removeParam('typeahead')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}search
search adds a typeahead search term to the request.
| Name | Type | Description |
|---|---|---|
| key (required) | string | Search term, as one word. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, search logs an error and drops a term that is empty or holds a character other than letters, digits, underscores, periods, and hyphens. It drops a multi-word term such as red shoes too. Use the regex method on a specific field instead.
- Errors surface on the find() call that follows, not on search(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. search sets the typeahead query parameter and makes no request. find sends it.
- The API matches the term anywhere inside the text fields of an entry, such as title, url, and other text fields, and ignores case. For example, search('ello') matches an entry titled Hello World.
- The search does not cover tags, number fields, taxonomy terms, or the fields of referenced entries.
- On an asset query without a locale, the API returns an asset once for each of its published locales. Pass a locale, for example with addParams({ locale: 'en-us' }), to get each asset once.
- The term is a query parameter, not a condition, so getQuery does not show it, and the removeParam method clears it with removeParam('typeahead').
- A second call replaces the first term.
Example
Basic usage: search for a one-word term
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.search('home')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}skip
skip sets the number of matching items the response leaves out before the first one it returns.
| Name | Type | Description |
|---|---|---|
| key (required) | number | Number of items to skip. |
Returns: Query. The same query, for chaining.
Validation
- There is no client-side validation. The SDK sends zero, a negative number, or a fraction as given.
- Errors surface on the find() call that follows, not on skip(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. skip sets the skip query parameter and makes no request. find sends it.
- Combine skip with the limit method to read one page at a time. For page n of size s, pass skip(n * s) and limit(s), counting pages from 0.
- Calling it twice replaces the first value. The paginate method also writes skip, so whichever runs last sets the value.
Example
Basic usage: read the second page of ten
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.exists('title')
.skip(10)
.limit(10)
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}tags
tags filters entries by the tags assigned to them.
| Name | Type | Description |
|---|---|---|
| values (required) | (string | number | boolean)[] | The full tag list to match, in order. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, tags logs an error and drops the condition when values is not an array of strings, numbers, or booleans. Pass an array of strings.
- An empty array passes the check.
- Errors surface on the find() call that follows, not on tags(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. tags stores the array under the tags key, as { tags: <values> }, and makes no request. find sends the conditions as the query parameter.
- The API compares the whole tags array. An item matches only when its tags equal values exactly, in the same order.
- For example, tags(['news']) does not match an entry tagged news and featured.
- An empty array matches only items that have no tags.
- A second call replaces the first array. Pass every tag in one call.
- tags writes the same key as a field filter on tags. For example, containedIn('tags', [...]) replaces it, and it replaces that filter.
Limitations
- Does not match items that carry any one of several tags. Use containedIn('tags', ['news', 'featured']) for that. See the containedIn method.
Example
Basic usage: filter entries by tags
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.tags(['featured', 'news'])
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}where
where adds a condition on a field, using any comparison operator or taxonomy operator.
| Name | Type | Description |
|---|---|---|
| fieldUid (required) | string | UID or dotted path of the field to filter. |
| queryOperation (required) | QueryOperation | TaxonomyQueryOperation | Comparison or taxonomy operator to apply. |
| fields (required) | string | string[] | number | number[] | object | boolean | Value to compare the field against. |
| additionalData | object | Extra operator options merged into the condition. |
Returns: Query. The same query, for chaining.
Validation
- Known issue: In 5.x, where logs an error and drops the condition when fieldUid holds a character other than letters, digits, underscores, periods, and hyphens. Check the field UID before you pass it.
- where does not check that fields suits the operator, for example an array for INCLUDES. The SDK sends a mismatched value as given.
- Errors surface on the find() call that follows, not on where(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. where stores the condition and makes no request. find sends the conditions as the query parameter.
- With QueryOperation.EQUALS, where stores the value itself, for example { title: 'Home' }. It ignores additionalData.
- With any other operator, where stores an object, for example { price: { $lt: 100 } }, and merges additionalData into it.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- The table below lists the ten QueryOperation members.
| Member | API operator | Matches when the field |
|---|---|---|
| EQUALS | None, the value itself | equals the value |
| NOT_EQUALS | $ne | does not equal the value |
| INCLUDES | $in | equals one of the values in the array |
| EXCLUDES | $nin | equals none of the values in the array |
| IS_LESS_THAN | $lt | is less than the value |
| IS_LESS_THAN_OR_EQUAL | $lte | is less than or equal to the value |
| IS_GREATER_THAN | $gt | is greater than the value |
| IS_GREATER_THAN_OR_EQUAL | $gte | is greater than or equal to the value |
| EXISTS | $exists | exists, for true, or is absent, for false |
| MATCHES | $regex | matches the regular expression |
- With a comparison operator on a date field such as updated_at, the API compares an ISO 8601 string in date order. A date without a time, such as '2026-01-01', stands for midnight UTC at the start of that day.
- The table below lists the four TaxonomyQueryOperation members. Each takes the field path taxonomies.<TAXONOMY_UID> as fieldUid and a term UID as fields.
| Member | API operator | Matches entries tagged with |
|---|---|---|
| ABOVE | $above | an ancestor of the term, excluding the term |
| BELOW | $below | a descendant of the term, excluding the term |
| EQ_ABOVE | $eq_above | the term or one of its ancestors |
| EQ_BELOW | $eq_below | the term or one of its descendants |
- Pass { levels: <number> } as additionalData to set the number of hierarchy levels a taxonomy operator covers. Without it, the API covers up to 10 levels.
- The taxonomy operators also filter entries across content types on the TaxonomyQuery that stack.taxonomy() returns. See the Taxonomy class page.
- The equalTo, lessThan, containedIn, and similar methods each cover one operator with a typed value.
Example
Basic usage: match entries with an exact title
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.where('title', QueryOperation.EQUALS, 'Home')
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Comparison: match entries updated after a date
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.where('updated_at', QueryOperation.IS_GREATER_THAN, '2026-01-01')
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}All parameters: pass a regex option through additionalData
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
// additionalData merges into the condition: { title: { $regex: '^home', $options: 'i' } }
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.where('title', QueryOperation.MATCHES, '^home', { $options: 'i' })
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}Taxonomy: match entries tagged with a term or its children
import contentstack, { TaxonomyQueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.where('taxonomies.<TAXONOMY_UID>', TaxonomyQueryOperation.EQ_BELOW, '<TERM_UID>', { levels: 2 })
.find();
console.log(result.entries?.length);
} catch (error: any) {
console.error(error);
}Assets: match assets by MIME type
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
const result = await stack.asset().query().where('content_type', QueryOperation.EQUALS, 'image/png').find();
console.log(result.assets?.length);
} catch (error: any) {
console.error(error);
}whereIn
whereIn matches entries whose reference field points to entries that match a sub-query.
| Name | Type | Description |
|---|---|---|
| referenceUid (required) | string | UID of the reference field to filter. |
| queryInstance (required) | Query | Query whose conditions the referenced entries must match. |
Returns: Query. The same query, for chaining.
Validation
- whereIn throws an Error at the call when referenceUid contains a character other than letters, digits, underscores, periods, and hyphens. Unlike most filters, it does not log and continue. The referenceIn method logs instead.
- The SDK does not check that queryInstance holds conditions. An empty sub-query sends an empty $in_query object.
- API and network errors surface on the find() call that follows, not on whereIn(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. whereIn stores { <referenceUid>: { $in_query: <conditions of queryInstance> } } and makes no request. find sends the conditions as the query parameter.
- Only the sub-query's conditions travel. Its content type, its parameters such as limit, and its variants play no part, and the SDK never sends a request for it.
- whereIn stores a reference to the sub-query's conditions, not a copy. A filter you add to the sub-query after the call still reaches the request.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- Known issue: In 5.x, two queries from one Entries object share their conditions. Build the sub-query from its own entry() call, as Shared state on the Query class page describes.
- On an asset query, the API rejects the condition with status 400 and error_code 141.
Example
Basic usage: match entries whose author is a named author
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
// The sub-query only supplies conditions. The SDK never sends a request for it.
const authors = stack.contentType('author').entry().query().where('title', QueryOperation.EQUALS, 'John Doe');
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.whereIn('author', authors)
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Error handling: an invalid reference field UID throws before any request
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
const authors = stack.contentType('author').entry().query().exists('title');
try {
stack.contentType('<CONTENT_TYPE_UID>').entry().query().whereIn('author name', authors);
} catch (error: any) {
// Thrown by whereIn() itself, because the UID contains a space.
console.error('Invalid reference field UID:', error.message);
}whereNotIn
whereNotIn matches entries whose reference field points to entries that do not match a sub-query.
| Name | Type | Description |
|---|---|---|
| referenceUid (required) | string | UID of the reference field to filter. |
| queryInstance (required) | Query | Query whose conditions the referenced entries must not match. |
Returns: Query. The same query, for chaining.
Validation
- whereNotIn throws an Error at the call when referenceUid contains a character other than letters, digits, underscores, periods, and hyphens. Unlike most filters, it does not log and continue. The referenceNotIn method logs instead.
- The SDK does not check that queryInstance holds conditions. An empty sub-query sends an empty $nin_query object.
- API and network errors surface on the find() call that follows, not on whereNotIn(). find() throws an APIError when the request fails, carrying the HTTP status, the API error_code, and the error_message.
Additional Resource Refer to Delivery API Errors for the full error code list.
Behavior
- Client-side only. whereNotIn stores { <referenceUid>: { $nin_query: <conditions of queryInstance> } } and makes no request. find sends the conditions as the query parameter.
- Only the sub-query's conditions travel. Its content type, its parameters such as limit, and its variants play no part, and the SDK never sends a request for it.
- whereNotIn stores a reference to the sub-query's conditions, not a copy. A filter you add to the sub-query after the call still reaches the request.
- A second filter on the same field replaces this one, because the SDK keys each condition on the field UID. See How conditions combine on the Query class page.
- Known issue: In 5.x, two queries from one Entries object share their conditions. Build the sub-query from its own entry() call, as Shared state on the Query class page describes.
- On an asset query, the API rejects the condition with status 400 and error_code 141.
Example
Basic usage: match entries whose author is not a named author
import contentstack, { QueryOperation } from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
try {
// The sub-query only supplies conditions. The SDK never sends a request for it.
const authors = stack.contentType('author').entry().query().where('title', QueryOperation.EQUALS, 'John Doe');
const result = await stack
.contentType('<CONTENT_TYPE_UID>')
.entry()
.query()
.whereNotIn('author', authors)
.find();
console.log(result.entries?.length);
} catch (error: any) {
// Thrown for API rejections and network failures
console.error('Request failed:', error.status, error.error_code, error.error_message);
}Error handling: an invalid reference field UID throws before any request
import contentstack from '@contentstack/delivery-sdk';
const stack = contentstack.stack({
apiKey: '<API_KEY>',
deliveryToken: '<DELIVERY_TOKEN>',
environment: '<ENVIRONMENT>',
});
const authors = stack.contentType('author').entry().query().exists('title');
try {
stack.contentType('<CONTENT_TYPE_UID>').entry().query().whereNotIn('author name', authors);
} catch (error: any) {
// Thrown by whereNotIn() itself, because the UID contains a space.
console.error('Invalid reference field UID:', error.message);
}