---
title: "Taxonomy"
description: "Taxonomy"
url: "https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/python/reference/taxonomy"
product: "Contentstack"
doc_type: "guide"
audience:
  - developers
  - admins
version: "current"
last_updated: "2026-10-23"
---

# Taxonomy

## Taxonomy

[Taxonomy](/docs/headless-cms/about-taxonomy) organizes content in a stack into hierarchical terms that you can tag entries with. Use this class to

*   list the taxonomies published in a stack
*   read one taxonomy by its UID
*   filter entries by the terms they carry

| Name | Type | Description |

| --- | --- | --- |

| taxonomy\_uid | str | UID of the taxonomy. |

Omit taxonomy\_uid to get a TaxonomyQuery: call find() alone to list taxonomies, or chain a filter before find() to filter entries. Pass it to get a Taxonomy for reading one taxonomy by UID.

## above

above matches entries tagged with the ancestors of a term, excluding the term itself.

```
The same query, for chaining.
ValidationThere is no client-side validation. above accepts an empty string for either text argument, and a negative or non-integer levels, and stores each one as given.Omitting field or term_uid raises TypeError immediately, because both are positional parameters with no default. Omitting levels is valid and applies the SDK default of 10.Errors that do occur come from the find() call that follows, not from above().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, a term UID that does not exist) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. above records the condition {"$above": term_uid, "levels": levels} under the field path and makes no request.The match excludes the named term. An entry tagged only with paris does not match above('taxonomies.regions', 'paris'). Use the equal_and_above method to include it.A root term has no ancestors, so above on a root term matches nothing. The API returns an empty entry list rather than an error.Calling above twice on the same field replaces the first condition. Use the or_ method to combine two hierarchy conditions on one field.Chaining this filter routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.ExampleBasic usage: match the ancestors of a termimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().above('taxonomies.regions', 'paris').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')All parameters: match the immediate parent onlyimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # levels=1 stops at the direct parent of 'paris'.
    result = stack.taxonomy().above('taxonomies.regions', 'paris', levels=1).find()
except Exception as error:
    print('Request failed:', error)Edge case: an empty result from a root termimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # 'world' sits at the root, so nothing is above it. This returns no entries
    # and no error, which is easy to mistake for a broken query.
    result = stack.taxonomy().above('taxonomies.regions', 'world').find()
    print('entries:', len(result.get('entries', [])))
except Exception as error:
    print('Request failed:', error)
```

Taxonomy field path to match against.

UID of the term whose ancestors to match.

How many hierarchy levels above the term to include.

## and_

and\_ matches entries satisfying all of the given conditions.

```
The same query, for chaining.
ValidationThere is no client-side validation. and_ accepts any object as a condition, including a value that is not a dictionary, and stores it as given.Calling and_() with no arguments is valid and stores an empty condition list. The API then receives {"$and": []}.Errors that do occur come from the find() call that follows, not from and_().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, a malformed condition) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. and_ collects its arguments into a list and records them under the single $and key. It makes no request.Pass each condition as a separate argument, not as one list. See How filters combine on the Taxonomy class page. and_([cond_a, cond_b]) produces the nested structure {"$and": [[cond_a, cond_b]]}.Calling and_ twice replaces the whole condition set, because both calls own the same $and key.Chaining two separate filter methods already behaves as a conjunction, because the API combines the stored field conditions. Use and_ when you need two conditions on the same field, which a repeated filter method cannot express.and_ and or_ own different keys, so you can chain both on one query.ExampleBasic usage: require two taxonomy conditions togetherimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().and_(
        {'taxonomies.regions': {'$in': ['europe']}},
        {'taxonomies.products': {'$in': ['laptops']}}
    ).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')Combining both logical filters on one queryimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # $and and $or are separate keys, so both conditions reach the API.
    result = stack.taxonomy() \
        .and_({'taxonomies.regions': {'$exists': True}}) \
        .or_(
            {'taxonomies.products': {'$in': ['laptops']}},
            {'taxonomies.products': {'$in': ['tablets']}}
        ) \
        .find()
except Exception as error:
    print('Request failed:', error)Edge case: a second call discards the first condition setimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Only the products condition survives.
    result = stack.taxonomy() \
        .and_({'taxonomies.regions': {'$in': ['europe']}}) \
        .and_({'taxonomies.products': {'$in': ['laptops']}}) \
        .find()

    # Pass both conditions to a single call instead.
    correct = stack.taxonomy().and_(
        {'taxonomies.regions': {'$in': ['europe']}},
        {'taxonomies.products': {'$in': ['laptops']}}
    ).find()
except Exception as error:
    print('Request failed:', error)
```

Condition dictionaries, passed as separate arguments.

## below

below matches entries tagged with the descendants of a term, excluding the term itself.

```
The same query, for chaining.
ValidationThere is no client-side validation. below accepts an empty string for either text argument, and a negative or non-integer levels, and stores each one as given.Omitting field or term_uid raises TypeError immediately, because both are positional parameters with no default. Omitting levels is valid and applies the SDK default of 10.Errors that do occur come from the find() call that follows, not from below().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, a term UID that does not exist) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. below records the condition {"$below": term_uid, "levels": levels} under the field path and makes no request.The match excludes the named term. An entry tagged only with europe does not match below('taxonomies.regions', 'europe'). Use the equal_and_below method to include it.The SDK always sends levels, even when you omit the argument, because the default lives in the method signature rather than at the API.Calling below twice on the same field replaces the first condition. Use the or_ method to combine two hierarchy conditions on one field.Chaining this filter routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.ExampleBasic usage: match the descendants of a termimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().below('taxonomies.regions', 'europe').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')All parameters: match direct children onlyimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # levels=1 stops at the immediate children of 'europe'.
    result = stack.taxonomy().below('taxonomies.regions', 'europe', levels=1).find()
except Exception as error:
    print('Request failed:', error)Edge case: entries tagged with the parent term are missingimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # An entry tagged 'europe' and nothing else does not appear here.
    descendants = stack.taxonomy().below('taxonomies.regions', 'europe').find()

    # Switch filters to include it.
    inclusive = stack.taxonomy().equal_and_below('taxonomies.regions', 'europe').find()
except Exception as error:
    print('Request failed:', error)
```

Taxonomy field path to match against.

UID of the term whose descendants to match.

How many hierarchy levels below the term to include.

## equal_and_above

equal\_and\_above matches entries tagged with a term or with any of its ancestors.

```
The same query, for chaining.
ValidationThere is no client-side validation. equal_and_above accepts an empty string for either text argument, and a negative or non-integer levels, and stores each one as given.Omitting field or term_uid raises TypeError immediately, because both are positional parameters with no default. Omitting levels is valid and applies the SDK default of 10.Errors that do occur come from the find() call that follows, not from equal_and_above().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, a term UID that does not exist) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. equal_and_above records the condition {"$eq_above": term_uid, "levels": levels} under the field path and makes no request.The match includes the named term itself. Use the above method to exclude it.Ancestor matching traverses toward the root, so a deep taxonomy needs fewer levels than a descendant search covering the same tree. Each term has one path to the root.Calling equal_and_above twice on the same field replaces the first condition. Use the or_ method to combine two hierarchy conditions on one field.Chaining this filter routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.ExampleBasic usage: match a term and its ancestorsimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().equal_and_above('taxonomies.regions', 'paris').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')All parameters: match the term and one level upimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Matches 'paris' and its immediate parent, for example 'france'.
    result = stack.taxonomy().equal_and_above(
        'taxonomies.regions', 'paris', levels=1
    ).find()
except Exception as error:
    print('Request failed:', error)
```

Taxonomy field path to match against.

UID of the term at the bottom of the range.

How many hierarchy levels above the term to include.

## equal_and_below

equal\_and\_below matches entries tagged with a term or with any of its descendants.

```
The same query, for chaining.
ValidationThere is no client-side validation. equal_and_below accepts an empty string for either text argument, and a negative or non-integer levels, and stores each one as given.Omitting field or term_uid raises TypeError immediately, because both are positional parameters with no default. Omitting levels is valid and applies the SDK default of 10.Errors that do occur come from the find() call that follows, not from equal_and_below().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, a term UID that does not exist) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. equal_and_below records the condition {"$eq_below": term_uid, "levels": levels} under the field path and makes no request.The match includes the named term itself. Use the below method to exclude it.The SDK always sends levels, even when you omit the argument, because the default lives in the method signature rather than at the API. A query that omits it therefore caps the search at ten levels below the term.Calling equal_and_below twice on the same field replaces the first condition. Use the or_ method to combine two hierarchy conditions on one field.Chaining this filter routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.ExampleBasic usage: match a term and everything under itimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().equal_and_below('taxonomies.regions', 'europe').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')All parameters: limit the search to two levels below the termimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Matches 'europe', its children, and its grandchildren. Nothing deeper.
    result = stack.taxonomy().equal_and_below(
        'taxonomies.regions', 'europe', levels=2
    ).find()
except Exception as error:
    print('Request failed:', error)Edge case: the default depth silently caps a deep hierarchyimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # A taxonomy deeper than ten levels loses its deepest terms here,
    # because the SDK sends levels=10 whenever you omit the argument.
    capped = stack.taxonomy().equal_and_below('taxonomies.regions', 'world').find()

    # Raise levels explicitly to reach the whole tree.
    full = stack.taxonomy().equal_and_below(
        'taxonomies.regions', 'world', levels=50
    ).find()
except Exception as error:
    print('Request failed:', error)
```

Taxonomy field path to match against.

UID of the term at the top of the range.

How many hierarchy levels below the term to include.

## exists

exists matches entries that carry a value in the given taxonomy field.

```
The same query, for chaining.
ValidationThere is no client-side validation. exists accepts an empty string as the field and stores it as given.Omitting the argument raises TypeError immediately, because field is a positional parameter with no default.Errors that do occur come from the find() call that follows, not from exists().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, a field path that names no taxonomy) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. exists records the condition {"$exists": True} under the field path and makes no request.The condition is always True. There is no parameter for matching entries that lack the field. Use the or_ method with an explicit {"$exists": False} condition dictionary for the inverse.Chaining exists routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.Calling exists twice on the same field is a no-op the second time, because both calls write the identical condition to the same key.LimitationsDoes not distinguish an empty term list from an absent field. Filter the returned entries in your own code when that difference matters.ExampleBasic usage: match every entry tagged in one taxonomyimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().exists('taxonomies.regions').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('tagged entries:', len(result.get('entries', [])))Inverse condition: match entries that lack the fieldimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # exists always sends True, so build the negative condition by hand.
    result = stack.taxonomy().or_(
        {'taxonomies.regions': {'$exists': False}}
    ).find()
except Exception as error:
    print('Request failed:', error)
```

Taxonomy field path that must hold a value.

## fetch

fetch retrieves one published taxonomy by its UID.

```
The requested taxonomy.
Validationfetch validates nothing itself. The UID check happens earlier, in the constructor.stack.taxonomy('') never reaches this method. The empty string is falsy, so stack.taxonomy returns a TaxonomyQuery, which has no fetch, and the call raises AttributeError. See the Warning on the Taxonomy class page.Constructing Taxonomy directly with an empty or None UID raises KeyError with the message "Invalid key or value. Provide valid values and try again." because the SDK cannot build the taxonomy URL without an identifier.fetch raises an exception only for network failures (timeout, DNS error, dropped connection). The exception type is RequestError.An API-level rejection, including a UID that names no taxonomy, returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorCalls GET /taxonomies/{taxonomy_uid} and makes one HTTP request per call.Returns the contents of the taxonomy key on success, not the response envelope around it.Falls back to the whole response body when the taxonomy key is absent, which is what happens on an API rejection. That is why an error body still reaches you with its error key intact.Sends whatever locale, include_fallback, include_branch, and param recorded on the instance. Calling fetch twice on one instance repeats the same request.LimitationsDoes not return the taxonomy's terms. Use the term method to reach them.ExampleBasic usage: read one taxonomy by UIDimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print(result['uid'], result['name'])All modifiers: locale, fallback, branch, and an extra parameterimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions') \
        .locale('fr-fr') \
        .include_fallback() \
        .include_branch() \
        .param('include_count', 'true') \
        .fetch()
    print('branch:', result.get('_branch'))
except Exception as error:
    print('Request failed:', error)Error handling: an unknown UID does not raiseimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('no_such_taxonomy').fetch()
except Exception as error:
    print('Request failed:', error)
else:
    # A missing taxonomy arrives as an ordinary return value, not an exception.
    if 'error' in result:
        print('code:', result.get('error_code'), 'message:', result.get('error_message'))Edge case: an empty UID returns the wrong objectimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

taxonomy_uid = ''

try:
    result = stack.taxonomy(taxonomy_uid).fetch()
except AttributeError as error:
    # Fires because the empty string returned a TaxonomyQuery, which has no fetch.
    print('Guard the UID before calling fetch:', error)
```

## find

find lists the published taxonomies in a stack, or returns the entries matching a chained filter.

```
The published taxonomies, or the entries matching the chained filter.
ValidationPassing a non-dictionary as params fails on the taxonomy-list path, where find passes it to dict.update. A non-zero integer raises TypeError, and a non-empty string or a list of wrong-length items raises ValueError. On the entry-filter path it raises AttributeError from items instead.Passing None for params is valid and is the default. find skips the merge entirely.find never validates the chained filter or the pagination values. It serializes whatever the query holds and sends it.find raises an exception only for network failures (timeout, DNS error, dropped connection). The exception type is RequestError.An API-level rejection returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorWhich endpoint find calls depends on whether you chain a filter. See One method, two endpoints on the Taxonomy class page.No filter chained: GET /taxonomies, returning {'taxonomies': [...]} plus count when you chain include_count.Any filter chained: GET /taxonomies/entries, returning the matching entries.One call makes one HTTP request. The SDK does not iterate pages.params reaches the two paths differently.On the taxonomy-list path the SDK merges params into the stored query parameters, so a key that collides with limit, skip, or include_count overwrites it.On the entry-filter path the SDK appends params to the URL as raw key=value pairs without encoding them. Encode any value containing a reserved character before passing it.find sends the environment parameter on the entry-filter path only. The list path relies on the environment header that Stack supplies.LimitationsDoes not return every taxonomy when you omit limit. The API applies its own page size. Chain the include_count method and compare count against the length of the returned list to detect a truncated page.Does not accept pagination on the entry-filter path. Chaining a filter makes find drop skip, limit, and include_count.ExampleBasic usage: list the published taxonomiesimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        for taxonomy in result.get('taxonomies', []):
            print(taxonomy['uid'], taxonomy['name'])All parameters: pass an extra query parameter alongside paginationimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # params is merged into the stored query parameters on the list path.
    result = stack.taxonomy().skip(10).limit(10).include_count().find(
        params={'locale': 'fr-fr'}
    )
    print('total:', result.get('count'))
except Exception as error:
    print('Request failed:', error)Filtering: return entries instead of taxonomiesimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Chaining in_ routes find to GET /taxonomies/entries.
    result = stack.taxonomy().in_('taxonomies.regions', ['europe']).find()
except Exception as error:
    print('Request failed:', error)Edge case: a chained filter drops the pagination valuesimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # limit(5) applies here.
    capped = stack.taxonomy().limit(5).find()

    # limit(5) is silently ignored here, because the filter changes the endpoint.
    # Use Query.limit on a content type query to cap entry results instead.
    entries = stack.taxonomy().limit(5).exists('taxonomies.regions').find()
except Exception as error:
    print('Request failed:', error)
```

Extra query parameters merged into the request.

## in_

in\_ matches entries tagged with any of the given terms.

```
The same query, for chaining.
ValidationThere is no client-side validation. in_ accepts an empty string as the field, an empty list, and a non-list value for terms, and stores each one as given.Omitting either argument raises TypeError immediately, because both are positional parameters with no default.Errors that do occur come from the find() call that follows, not from in_().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, a field path that names no taxonomy) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. in_ records the condition {"$in": terms} under the field path and makes no request.Chaining in_ routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies. See One method, two endpoints on the Taxonomy class page.The field path takes the form taxonomies.<TAXONOMY_UID>. It names the taxonomy field on the entry, not the term.Calling in_ twice on the same field replaces the first condition. Use the or_ method to combine two conditions on one field.The type annotation names TaxonomyFilter as the return type, but in_ returns the same instance you called it on. Calling it on stack.taxonomy() therefore returns a TaxonomyQuery.ExampleBasic usage: match entries tagged with either of two termsimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().in_('taxonomies.regions', ['europe', 'asia']).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')Edge case: a second call on the same field replaces the firstimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Only the second condition survives, so this matches 'asia' alone.
    overwritten = stack.taxonomy() \
        .in_('taxonomies.regions', ['europe']) \
        .in_('taxonomies.regions', ['asia']) \
        .find()

    # Pass both terms in one list instead.
    correct = stack.taxonomy().in_('taxonomies.regions', ['europe', 'asia']).find()
except Exception as error:
    print('Request failed:', error)
```

Taxonomy field path to match against.

Term UIDs that satisfy the condition.

## include_branch

include\_branch adds the \_branch field to the taxonomy in the response.

```
The same taxonomy, for chaining.
ValidationThere is nothing to validate. include_branch takes no arguments and cannot fail.Errors that do occur come from the fetch() call that follows, not from include_branch().fetch() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. Sets include_branch=true as a string and makes no request. fetch sends the flag on that call.The flag reports which branch served the taxonomy. It does not select one. Pass branch to Stack to choose the branch a request targets.A stack with no branches enabled returns no _branch field even with the flag set, so read the key defensively.ExampleBasic usage: confirm which branch served the taxonomyimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').include_branch().fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('served from branch:', result.get('_branch', 'branches not enabled'))Selecting a branch, which this method does not doimport contentstack

stack = contentstack.Stack(
    '<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>', branch='release-2'
)

try:
    # branch on Stack picks the branch. include_branch only reports it back.
    result = stack.taxonomy('regions').include_branch().fetch()
    print('requested release-2, served:', result.get('_branch'))
except Exception as error:
    print('Request failed:', error)
```

## include_count

include\_count adds the total number of published taxonomies to the response.

```
The same query, for chaining.
ValidationThere is nothing to validate. include_count takes no arguments and cannot fail.Errors that do occur come from the find() call that follows, not from include_count().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. Sets include_count=true as a string and makes no request. find sends the flag on that call.The count key holds the total number of published taxonomies in the stack, not the number returned in this page. Compare it against the length of the taxonomies list to find out whether more remain.Chaining a filter such as in_ silently drops the flag, so the entry-filter response carries no count.ExampleBasic usage: detect a truncated taxonomy listimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().limit(10).include_count().find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        returned = len(result.get('taxonomies', []))
        total = result.get('count', 0)
        print(f'showing {returned} of {total}')
        if returned < total:
            print('more pages remain, raise skip to read them')Edge case: no count on the entry-filter pathimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # The filter routes find to GET /taxonomies/entries, which ignores the flag.
    result = stack.taxonomy().include_count().in_('taxonomies.colors', ['red']).find()

    # count is absent here, so the default guards against a KeyError.
    print('count key present:', 'count' in result)
except Exception as error:
    print('Request failed:', error)
```

## include_fallback

include\_fallback returns an earlier locale in the hierarchy when the taxonomy has no localization in the requested one.

```
The same taxonomy, for chaining.
ValidationThere is nothing to validate. include_fallback takes no arguments and cannot fail.Errors that do occur come from the fetch() call that follows, not from include_fallback().fetch() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. Sets include_fallback=true as a string and makes no request. fetch sends the flag on that call.The flag alone changes nothing. Chain the locale method as well, because the fallback only applies when the requested locale differs from the master locale.The API resolves the fallback, not the SDK. It returns the nearest earlier locale in the hierarchy that holds a published version.The response does not report whether a fallback happened. Compare the returned locale against the one you asked for when that difference matters.ExampleBasic usage: accept an earlier locale when the French version is missingimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').locale('fr-fr').include_fallback().fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('name:', result.get('name'))Edge case: detect a fallbackimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

requested = 'fr-fr'

try:
    result = stack.taxonomy('regions').locale(requested).include_fallback().fetch()

    # The response carries the locale it actually served, so compare the two.
    served = result.get('locale')
    if served and served != requested:
        print(f'no {requested} version, served {served} instead')
except Exception as error:
    print('Request failed:', error)
```

## limit

limit caps the number of taxonomies the response contains.

```
The same query, for chaining.
ValidationThere is no client-side validation. The SDK stores and sends a negative or non-integer value as given.Omitting the argument raises TypeError immediately, because limit is a positional parameter with no default.Errors that do occur come from the find() call that follows, not from limit().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, an invalid limit value) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. Sets the limit query parameter and makes no request. find sends the value on that call.Omitting limit does not return every taxonomy. The API applies its own page size instead. See Pagination on the Taxonomy class page for how to detect a truncated list and page through the rest.Calling limit twice replaces the first value. The SDK stores it under a single key.Chaining a filter such as in_ silently drops the limit.ExampleBasic usage: return at most ten taxonomiesimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().limit(10).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('returned', len(result.get('taxonomies', [])), 'taxonomies')Edge case: chaining a filter ignores the limitimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # This lists at most 5 taxonomies.
    capped = stack.taxonomy().limit(5).find()

    # This returns entries, and the limit below has no effect.
    # Use Query.limit on a content type query to cap entry results instead.
    entries = stack.taxonomy().limit(5).in_('taxonomies.colors', ['red']).find()
except Exception as error:
    print('Request failed:', error)
```

Maximum number of taxonomies to return.

## locale

locale sets the language the API returns the taxonomy in.

```
The same taxonomy, for chaining.
ValidationThere is no client-side validation. locale accepts an empty string or a code that names no locale and stores it as given.Omitting the argument raises TypeError immediately, because locale is a positional parameter with no default.Errors that do occur come from the fetch() call that follows, not from locale().fetch() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. locale sets the locale query parameter and makes no request. fetch sends the value on that call.The SDK sets no default. Omitting locale sends no locale parameter, and the API returns the stack's master locale.Calling locale twice replaces the first value. The SDK stores it under a single key.A taxonomy that has no localization in the requested locale comes back empty unless you also chain the include_fallback method.Taxonomy.locale and Term.locale are separate methods on separate objects. Setting the locale on the taxonomy does not carry it down to a term you reach through the term method.ExampleBasic usage: read a taxonomy in Frenchimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').locale('fr-fr').fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('localized name:', result.get('name'))Edge case: the locale does not carry down to termsimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    taxonomy = stack.taxonomy('regions').locale('fr-fr')

    # This term request has no locale, so it returns the master locale.
    term = taxonomy.term('paris').fetch()

    # Set the locale again on the term to get the French version.
    localized_term = stack.taxonomy('regions').term('paris').locale('fr-fr').fetch()
except Exception as error:
    print('Request failed:', error)
```

Locale code to request, for example fr-fr.

## or_

or\_ matches entries satisfying any one of the given conditions.

```
The same query, for chaining.
ValidationThere is no client-side validation. or_ accepts any object as a condition, including a value that is not a dictionary, and stores it as given.Calling or_() with no arguments is valid and stores an empty condition list. The API then receives {"$or": []}, which matches nothing rather than everything.Errors that do occur come from the find() call that follows, not from or_().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection (for example, a malformed condition) returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. or_ collects its arguments into a list and records them under the single $or key. It makes no request.Pass each condition as a separate argument, not as one list. See How filters combine on the Taxonomy class page. or_([cond_a, cond_b]) produces the nested structure {"$or": [[cond_a, cond_b]]}.Calling or_ twice replaces the whole condition set, because both calls own the same $or key.Chaining or_ routes the following find to GET /taxonomies/entries, so find returns entries rather than taxonomies.Write the condition dictionaries in the Delivery API taxonomy query syntax. or_ does not build them for you, so an operator such as $in or $eq_below appears verbatim in the dictionary you pass.ExampleBasic usage: match entries in either of two taxonomiesimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().or_(
        {'taxonomies.regions': {'$in': ['europe']}},
        {'taxonomies.products': {'$in': ['laptops']}}
    ).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('matched', len(result.get('entries', [])), 'entries')Two conditions on one field, which a repeated filter cannot expressimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Two in_ calls on one field would collide. or_ keeps both conditions.
    result = stack.taxonomy().or_(
        {'taxonomies.regions': {'$eq_below': 'europe', 'levels': 2}},
        {'taxonomies.regions': {'$in': ['antarctica']}}
    ).find()
except Exception as error:
    print('Request failed:', error)Error handling: a list instead of separate argumentsimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

conditions = [
    {'taxonomies.regions': {'$in': ['europe']}},
    {'taxonomies.products': {'$in': ['laptops']}}
]

try:
    # Unpack the list. Passing `conditions` directly nests it one level too deep.
    result = stack.taxonomy().or_(*conditions).find()
    if 'error' in result:
        print('Delivery API error:', result['error'])
except Exception as error:
    print('Request failed:', error)
```

Condition dictionaries, passed as separate arguments.

## param

param adds an arbitrary query parameter to the request.

```
The same object, for chaining.
ValidationPassing None as either argument raises KeyError with the message "Invalid key or value arguments. Provide valid values and try again." A null key or value would produce a malformed query string. This is the only method on this class that rejects its own arguments.The raise happens on the call itself, not on the terminal call that follows. Wrap param in its own try when the key or value comes from user input.An empty string passes the check. None is the only rejected value, so param('', '') stores a parameter with no name.Omitting either argument raises TypeError immediately, because both are positional parameters with no default.Any remaining errors come from the terminal call, find() on a TaxonomyQuery or fetch() on a Taxonomy.Those calls raise an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. param records the pair in the query parameters and makes no request.This is the only method available on both objects stack.taxonomy() can return. Everything else belongs to one branch or the other.The key shares one namespace with the dedicated modifiers. param('limit', 5) and limit(5) write to the same place, so whichever call comes last wins.Use param to reach a Delivery API query parameter the SDK exposes no method for. Prefer the dedicated method when one exists, because it documents the intent.On a TaxonomyQuery, chaining a filter routes find to the entry endpoint, which never reads these stored parameters, so find drops them along with the pagination values.The SDK encodes the parameters before sending them, so a value containing a space or an ampersand needs no encoding from you.ExampleBasic usage: send a query parameter the SDK has no method forimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().param('include_terms_count', 'true').find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('taxonomies:', len(result.get('taxonomies', [])))All parameters: both arguments on a single-taxonomy fetchimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # param works the same on the Taxonomy branch, where fetch is terminal.
    result = stack.taxonomy('regions').param('locale', 'fr-fr').fetch()
    print('name:', result.get('name'))
except Exception as error:
    print('Request failed:', error)Error handling: a null key raises at the call siteimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

user_supplied_key = None

try:
    result = stack.taxonomy().param(user_supplied_key, 'true').find()
except KeyError as error:
    # Fires on param itself, before any request goes out.
    print('Invalid query parameter:', error)Edge case: a dedicated method and param collideimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Both write the 'limit' key, so the later call wins and this sends limit=5.
    result = stack.taxonomy().limit(10).param('limit', 5).find()
except Exception as error:
    print('Request failed:', error)
```

Query parameter name to send.

Value for that query parameter.

## skip

skip omits a number of taxonomies from the start of the response.

```
The same query, for chaining.
ValidationThere is no client-side validation. The SDK stores and sends a negative or non-integer value as given.Omitting the argument raises TypeError immediately, because skip is a positional parameter with no default.Errors that do occur come from the find() call that follows, not from skip().find() raises an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. Sets the skip query parameter and makes no request. find sends the value on that call.The SDK sets no default. Omitting skip sends no skip parameter, and the API starts from the first taxonomy.Calling skip twice replaces the first value. The SDK stores it under a single key.Chaining a filter such as in_ silently drops the offset.Pair skip with limit to page through the full list. The SDK does not page automatically.ExampleBasic usage: read the second page of ten taxonomiesimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy().skip(10).limit(10).find()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print('page 2 holds', len(result.get('taxonomies', [])), 'taxonomies')Pagination: read every page in orderimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

page_size = 10
offset = 0

try:
    while True:
        result = stack.taxonomy().skip(offset).limit(page_size).include_count().find()
        batch = result.get('taxonomies', [])
        for taxonomy in batch:
            print(taxonomy['uid'])
        offset += page_size
        # count is the total, not the page length, so compare against the offset.
        if offset >= result.get('count', 0):
            break
except Exception as error:
    print('Request failed:', error)
```

Number of taxonomies to omit from the start.

## term

term moves down from a taxonomy to its terms.

```
A single term, or a query across the taxonomy's terms.
Validationterm itself validates nothing. It tests term_uid for truthiness and hands the value to the object it builds.Passing a non-empty UID builds a Term, whose constructor raises KeyError only when the UID is falsy. That branch is unreachable through this method.term('') is not the same as term('<TERM_UID>'). The empty string is falsy, so it takes the no-UID branch and returns a TermQuery. Calling fetch on that object raises AttributeError, and calling find returns every term instead of the one you meant.Errors that do occur come from the terminal call on the returned object, fetch() or find(), not from term().Those calls raise an exception only for network failures (timeout, DNS error, dropped connection).An API-level rejection returns as a normal result with an error key. It does not raise an exception.Check the result for an error key even inside a try block.Additional Resource: Refer to Delivery API Errors for the full error code list.
BehaviorClient-side only. term constructs an object and makes no request.Which class you get back decides which methods are available.term('<TERM_UID>') returns a Term, which reads one term (fetch) and traverses the hierarchy (ancestors, descendants, locales).term() returns a TermQuery, which lists the taxonomy's terms (find) with pagination and locale modifiers.The new object carries none of the taxonomy's chained modifiers. Locale, fallback, and branch settings made on the taxonomy do not reach the term, so set them again on the returned object.The taxonomy UID is the only state that carries over. term reads it from the instance to build the term URL.ExampleBasic usage: read one term by UIDimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    result = stack.taxonomy('regions').term('paris').fetch()
except Exception as error:
    # Raised only for network failures (timeout, DNS error, dropped connection)
    print('Request failed:', error)
else:
    if 'error' in result:
        # The Delivery API rejected the request and returned the error body
        print('Delivery API error:', result['error'])
    else:
        print(result['uid'], result['name'])No UID: list every term in the taxonomyimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

try:
    # Omitting the UID returns a TermQuery, so the terminal call is find.
    result = stack.taxonomy('regions').term().locale('en-us').depth(3).limit(50).find()
    for term in result.get('terms', []):
        print(term['uid'])
except Exception as error:
    print('Request failed:', error)Edge case: an empty UID returns the wrong objectimport contentstack

stack = contentstack.Stack('<API_KEY>', '<DELIVERY_TOKEN>', '<ENVIRONMENT>')

term_uid = ''

try:
    result = stack.taxonomy('regions').term(term_uid).fetch()
except AttributeError as error:
    # Fires because the empty string returned a TermQuery, which has no fetch.
    print('Guard the term UID before calling fetch:', error)
```

UID of one term. Omit it to reach all terms.

## Taxonomy | Python Delivery SDK | Contentstack

The Taxonomy class in the Python Delivery SDK lists published taxonomies, fetches a single taxonomy, and filters entries by taxonomy terms.