Skip to content

anytype.Object

Templates and custom properties

Pass the selected type and template when constructing the object. Properties linked to that type are available by their API key or by their normalized display name:

obj = Object("Test", type=quote_type, template=template)
obj.date = "02/06/2026"
obj.people = [person]

created = space.create_object(obj)

date must be the key of a date property. people must be the key of an objects property; it accepts object instances or object IDs. A multi-select property instead accepts tag names or Tag instances.

Properties selected from the space can also be assigned explicitly:

properties = {prop.key: prop for prop in space.get_properties()}
properties["date"].value = "02/06/2026"
properties["people"].value = [person]

obj.properties["date"] = properties["date"]
obj.properties["people"] = properties["people"]

Bases: APIWrapper

Represents an object within a specific space, allowing creation and manipulation of its properties. The object can be customized with various attributes such as name, icon, body, description, and more. This class provides methods to export objects and add different content types to the object body, such as titles, text, code blocks, checkboxes, and bullet points.

IMPORTANT

Certain properties of an object, such as:

  • DOI in a collection of articles;
  • Release Year in albums;
  • Genre in music collections;
  • Author in book collections;
  • Publication Date in documents;
  • Rating in review-based objects;
  • Tags in categorized objects;

are accessible through the class properties. For example, if an object is created with a Type (e.g., anytype.Type) that includes a DOI property, the DOI URL can be set during the object creation using Object.doi.

You can also provide a Template for this object.

Note that these property names are derived from the corresponding name in the Anytype GUI. They are all lowercase with spaces replaced by underscores. For instance, a property called Release Year in the Anytype GUI will be accessed as release_year in the object, and a property called Publication Date will be accessed as publication_date.

Source code in anytype/object.py
class Object(APIWrapper):
    """
    Represents an object within a specific space, allowing creation and manipulation of its properties. The object can be customized with various attributes such as `name`, `icon`, `body`, `description`, and more. This class provides methods to export objects and add different content types to the object body, such as titles, text, code blocks, checkboxes, and bullet points.

    ### IMPORTANT

    Certain properties of an object, such as:

    - `DOI` in a collection of articles;
    - `Release Year` in albums;
    - `Genre` in music collections;
    - `Author` in book collections;
    - `Publication Date` in documents;
    - `Rating` in review-based objects;
    - `Tags` in categorized objects;

    are accessible through the class properties. For example, if an object is created with a `Type` (e.g., `anytype.Type`) that includes a `DOI` property, the DOI URL can be set during the object creation using `Object.doi`.

    You can also provide a Template for this object.

    Note that these property names are derived from the corresponding name in the Anytype GUI. They are all lowercase with spaces replaced by underscores. For instance, a property called `Release Year` in the Anytype GUI will be accessed as `release_year` in the object, and a property called `Publication Date` will be accessed as `publication_date`.

    """

    def __init__(self, name: str = "", type: Type | None = None, template: Template | None = None):
        self._apiEndpoints: apiEndpoints | None = None
        self._icon: Icon = Icon()
        self._values: dict = {}
        self.type: None | Type = None
        self.type_key: str = ""
        self.id: str = ""
        self.source: str = ""
        self.name: str = name
        self._markdown: str = ""
        self.archived: bool = False
        self.description: str = ""
        self.layout: str = "basic"
        self.root_id: str = ""
        self.space_id: str = ""
        self.template_id: str = template.id if template is not None else ""

        self.properties: dict = {}
        if type is not None:
            self.add_type(type)

    @staticmethod
    def _normalize_property_name(name: str) -> str:
        return re.sub(r"[^a-z0-9]+", "_", name.lower()).strip("_")

    def _property_for_attribute(self, name: str) -> Property | None:
        properties = self.__dict__.get("properties")
        if not isinstance(properties, dict):
            return None

        for prop in properties.values():
            if isinstance(prop, Property) and prop.key == name:
                return prop
        for prop in properties.values():
            if isinstance(prop, Property) and self._normalize_property_name(prop.name) == name:
                return prop
        return None

    def __getattr__(self, name):
        prop = self._property_for_attribute(name)
        if prop is not None:
            return prop.value
        raise AttributeError(f"{type(self).__name__!s} has no attribute {name!r}")

    def __setattr__(self, name, value):
        if not name.startswith("_"):
            prop = self._property_for_attribute(name)
            if prop is not None:
                prop.value = value
                return
        object.__setattr__(self, name, value)

    @property
    def icon(self):
        return self._icon

    @icon.setter
    def icon(self, value):
        if isinstance(value, dict):
            new_icon = Icon()
            new_icon._update_with_json(value)
            self._icon = new_icon
        elif isinstance(value, str):
            # This is from chatgpt, please report is you know about emoji encode
            emoji_pattern = re.compile(
                "[\U0001f600-\U0001f64f"  # Emoticons
                "\U0001f300-\U0001f5ff"  # Misc Symbols and Pictographs
                "\U0001f680-\U0001f6ff"  # Transport & Map Symbols
                "\U0001f1e0-\U0001f1ff"  # Regional Indicator Symbols
                "\U00002702-\U000027b0"  # Dingbats
                "\U000024c2-\U0001f251"  # Enclosed characters and others
                "\U0001f900-\U0001f9ff"  # Supplemental Symbols and Pictographs (includes 🤯)
                "]+",
                flags=re.UNICODE,
            )

            if bool(emoji_pattern.fullmatch(value)):
                self._icon.emoji = value
            else:
                raise Exception(f"Invalid icon format {value}")
        elif isinstance(value, Icon):
            self._icon = value
        elif value is None:
            self._icon = Icon("")
        else:
            raise Exception("Invalid icon format")

    @icon.getter
    def icon(self):
        return self._icon

    @property
    def markdown(self):
        pass

    @markdown.setter
    def markdown(self, text: str):
        self._markdown = text

    @markdown.getter
    def markdown(self):
        if self._markdown == "" and self.id and self._apiEndpoints is not None:
            data = self._apiEndpoints.getObject(self.space_id, self.id)
            self._markdown = data["object"]["markdown"]
            if isinstance(self._markdown, (list, tuple)):
                self._markdown = "".join(self._markdown)
        return self._markdown

    def add_type(self, type: Type):
        """
        Adds a type for an Object.

        Parameters:
            type (anytype.Type): Type from the space retrieved using `space.get_types()[0]`, `space.get_type(type)`, `space.get_type_byname("Articles")`

        """
        if not isinstance(type, Type) or not type.id:
            raise ValueError("Type must be retrieved from or created in the Anytype API")

        existing_properties = self.__dict__.get("properties", {})
        properties = {}
        for prop in type.properties.values():
            if isinstance(prop, Property) and prop.key not in _ANYTYPE_SYSTEM_RELATIONS:
                cloned = copy.copy(prop)
                for value_attribute in ("multi_select", "files", "objects"):
                    value = getattr(cloned, value_attribute, None)
                    if isinstance(value, list):
                        setattr(cloned, value_attribute, list(value))
                cloned._is_set = False
                properties[prop.name] = cloned

        for existing_name, existing in existing_properties.items():
            if not isinstance(existing, Property) or not existing.is_set:
                continue
            matching_name = next(
                (
                    name
                    for name, prop in properties.items()
                    if prop.key and prop.key == existing.key
                ),
                existing_name,
            )
            properties[matching_name] = existing

        self.type = type
        self.type_key = type.key
        self.properties = properties
        if not self.template_id and type.template_id:
            self.template_id = type.template_id

    def add_title1(self, text) -> None:
        """
        Adds a level 1 title to the object's body.

        Parameters:
            text (str): The text to be added as a level 1 title.

        """
        self.markdown += f"# {text}\n"

    def add_title2(self, text) -> None:
        """
        Adds a level 2 title to the object's body.

        Parameters:
            text (str): The text to be added as a level 2 title.

        """
        self.markdown += f"## {text}\n"

    def add_title3(self, text) -> None:
        """
        Adds a level 3 title to the object's body.

        Parameters:
            text (str): The text to be added as a level 3 title.

        """
        self.markdown += f"### {text}\n"

    def add_text(self, text) -> None:
        """
        Adds plain text to the object's body.

        Parameters:
            text (str): The text to be added.

        """
        self.markdown += f"{text}\n"

    def add_codeblock(self, code, language="") -> None:
        """
        Adds a code block to the object's body.

        Parameters:
            code (str): The code to be added.
            language (str, optional): The programming language of the code block. Default is an empty string.

        """
        self.markdown += f"``` {language}\n{code}\n```\n"

    def add_bullet(self, text) -> None:
        """
        Adds a bullet point to the object's body.

        Parameters:
            text (str): The text to be added as a bullet point.

        """
        self.markdown += f"- {text}\n"

    def add_checkbox(self, text, checked=False) -> None:
        """
        Adds a checkbox to the object's body.

        Parameters:
            text (str): The text to be added next to the checkbox.
            checked (bool, optional): Whether the checkbox is checked. Default is False.

        """
        self.markdown += f"- [x] {text}\n" if checked else f"- [ ] {text}\n"

    def add_quote(self, text: str) -> None:
        self.markdown += f'" {text}'

    def add_image(self, image_url: str, alt: str = "", title: str = "") -> None:
        """
        Adds an image to the object's body.

        Parameters:
            image_url (str): The URL of the image.
            alt (str, optional): The alternative text for the image. Default is an empty string.
            title (str, optional): The title of the image. Default is an empty string.

        """
        if title:
            self.markdown += f'![{alt}]({image_url} "{title}")\n'
        else:
            self.markdown += f"![{alt}]({image_url})\n"

    def __repr__(self):
        return f"<Object(name={self.name})>"

add_bullet(text)

Adds a bullet point to the object's body.

Parameters:

Name Type Description Default
text str

The text to be added as a bullet point.

required
Source code in anytype/object.py
def add_bullet(self, text) -> None:
    """
    Adds a bullet point to the object's body.

    Parameters:
        text (str): The text to be added as a bullet point.

    """
    self.markdown += f"- {text}\n"

add_checkbox(text, checked=False)

Adds a checkbox to the object's body.

Parameters:

Name Type Description Default
text str

The text to be added next to the checkbox.

required
checked bool

Whether the checkbox is checked. Default is False.

False
Source code in anytype/object.py
def add_checkbox(self, text, checked=False) -> None:
    """
    Adds a checkbox to the object's body.

    Parameters:
        text (str): The text to be added next to the checkbox.
        checked (bool, optional): Whether the checkbox is checked. Default is False.

    """
    self.markdown += f"- [x] {text}\n" if checked else f"- [ ] {text}\n"

add_codeblock(code, language='')

Adds a code block to the object's body.

Parameters:

Name Type Description Default
code str

The code to be added.

required
language str

The programming language of the code block. Default is an empty string.

''
Source code in anytype/object.py
def add_codeblock(self, code, language="") -> None:
    """
    Adds a code block to the object's body.

    Parameters:
        code (str): The code to be added.
        language (str, optional): The programming language of the code block. Default is an empty string.

    """
    self.markdown += f"``` {language}\n{code}\n```\n"

add_image(image_url, alt='', title='')

Adds an image to the object's body.

Parameters:

Name Type Description Default
image_url str

The URL of the image.

required
alt str

The alternative text for the image. Default is an empty string.

''
title str

The title of the image. Default is an empty string.

''
Source code in anytype/object.py
def add_image(self, image_url: str, alt: str = "", title: str = "") -> None:
    """
    Adds an image to the object's body.

    Parameters:
        image_url (str): The URL of the image.
        alt (str, optional): The alternative text for the image. Default is an empty string.
        title (str, optional): The title of the image. Default is an empty string.

    """
    if title:
        self.markdown += f'![{alt}]({image_url} "{title}")\n'
    else:
        self.markdown += f"![{alt}]({image_url})\n"

add_text(text)

Adds plain text to the object's body.

Parameters:

Name Type Description Default
text str

The text to be added.

required
Source code in anytype/object.py
def add_text(self, text) -> None:
    """
    Adds plain text to the object's body.

    Parameters:
        text (str): The text to be added.

    """
    self.markdown += f"{text}\n"

add_title1(text)

Adds a level 1 title to the object's body.

Parameters:

Name Type Description Default
text str

The text to be added as a level 1 title.

required
Source code in anytype/object.py
def add_title1(self, text) -> None:
    """
    Adds a level 1 title to the object's body.

    Parameters:
        text (str): The text to be added as a level 1 title.

    """
    self.markdown += f"# {text}\n"

add_title2(text)

Adds a level 2 title to the object's body.

Parameters:

Name Type Description Default
text str

The text to be added as a level 2 title.

required
Source code in anytype/object.py
def add_title2(self, text) -> None:
    """
    Adds a level 2 title to the object's body.

    Parameters:
        text (str): The text to be added as a level 2 title.

    """
    self.markdown += f"## {text}\n"

add_title3(text)

Adds a level 3 title to the object's body.

Parameters:

Name Type Description Default
text str

The text to be added as a level 3 title.

required
Source code in anytype/object.py
def add_title3(self, text) -> None:
    """
    Adds a level 3 title to the object's body.

    Parameters:
        text (str): The text to be added as a level 3 title.

    """
    self.markdown += f"### {text}\n"

add_type(type)

Adds a type for an Object.

Parameters:

Name Type Description Default
type Type

Type from the space retrieved using space.get_types()[0], space.get_type(type), space.get_type_byname("Articles")

required
Source code in anytype/object.py
def add_type(self, type: Type):
    """
    Adds a type for an Object.

    Parameters:
        type (anytype.Type): Type from the space retrieved using `space.get_types()[0]`, `space.get_type(type)`, `space.get_type_byname("Articles")`

    """
    if not isinstance(type, Type) or not type.id:
        raise ValueError("Type must be retrieved from or created in the Anytype API")

    existing_properties = self.__dict__.get("properties", {})
    properties = {}
    for prop in type.properties.values():
        if isinstance(prop, Property) and prop.key not in _ANYTYPE_SYSTEM_RELATIONS:
            cloned = copy.copy(prop)
            for value_attribute in ("multi_select", "files", "objects"):
                value = getattr(cloned, value_attribute, None)
                if isinstance(value, list):
                    setattr(cloned, value_attribute, list(value))
            cloned._is_set = False
            properties[prop.name] = cloned

    for existing_name, existing in existing_properties.items():
        if not isinstance(existing, Property) or not existing.is_set:
            continue
        matching_name = next(
            (
                name
                for name, prop in properties.items()
                if prop.key and prop.key == existing.key
            ),
            existing_name,
        )
        properties[matching_name] = existing

    self.type = type
    self.type_key = type.key
    self.properties = properties
    if not self.template_id and type.template_id:
        self.template_id = type.template_id