# Annotations

## [](#_introduction)Introduction

Annotations are useful language constructs that begin with an `@`. They can be used to enforce constraints on definitions.

## [](#_syntax)Syntax

Annotations are applied to the latest statement before their declaration:

A type’s annotation

```typeql
<type label> @annotation;
```

A type value’s annotation

```typeql
<type label> value <value type> @annotation;
```

A type plays' annotation

```typeql
<type label> plays <role type label> @annotation;
```

### [](#_arguments)Arguments

Some annotations accept arguments of different types:

Annotations with a single scalar argument

```typeql
@annotation(5)
@annotation("TypeDB!")
```

Annotations with multiple arguments

```typeql
@annotation(0, 1, 2, 3, 4, 5)
@annotation("Welcome", "to", "TypeDB", "!")
```

Annotations with a range argument

```typeql
@annotation(0..10)
@annotation("a".."z")
@annotation(1..)
```

### [](#_combining_with_other_statements)Combining with other statements

Annotation definition is a regular statement and can be followed by other statements after a comma:

```typeql
<type label> @annotation, value <value type> @annotation, plays <role type label> @annotation;
```

However, it is possible to chain multiple annotations for a single statement:

```typeql
<type label> @annotation1 @annotation2 @annotation3;
```

Which is an equivalent of:

```typeql
<type label> @annotation1;
<type label> @annotation2;
<type label> @annotation3;
```

## [](#_behavior)Behavior

It is possible to define an unlimited number of annotations of different kinds for a type. However, only one definition of a specific kind of annotation can exist for a type at a time (e.g., `@a(X)` and `@a(Y)` cannot co-exist in the schema).

*   Defining `@a` while `@b` is already defined results in both `@a` and `@b` being defined (with a couple of exceptions like `@key` and `@unique`).
    
*   Defining `@a` when `@a` is already defined makes no changes.
    
*   Defining `@a(x)` when `@a(y)` is already defined replaces `@a(y)` with `@a(x)`.
    

## [](#_cardinality_constraints)Cardinality constraints

[`@card` annotation](card/index.md)

Used to specify cardinality ranges for roles and ownerships.

[`@cascade` annotation](cascade/index.md)

Used to specify behavior when deleting a relation’s role players.

[`@independent` annotation](independent/index.md)

Used to prevent attributes without owners from being deleted automatically.

## [](#_modality_constraints)Modality constraints

[`@abstract` annotation](abstract/index.md)

Used to specify that a type is abstract.

[`@key` annotation](key/index.md)

Used to specify key attributes for entities and relations.

[`@subkey` annotation](subkey/index.md)

Used to specify composite keys built from multiple attributes.

[`@unique` annotation](unique/index.md)

Used to specify unique attributes for entities and relations.

## [](#_value_constraints)Value constraints

[`@values` annotation](values/index.md)

Used to specify a set of permitted values for attributes.

[`@range` annotation](range/index.md)

Used to specify a range of permitted values for attributes.

[`@regex` annotation](regex/index.md)

Used to specify a regex pattern for permitted values of attributes.

[`@distinct` annotation](distinct/index.md)

Used to restrict an owned list of attributes to distinct values.

## [](#_metadata_annotations)Metadata annotations

[`@doc` annotation](doc/index.md)

Used to add a description to a schema concept.

[`@meta` annotation](meta/index.md)

Used to add metadata to a schema concept.

[Comparisons](../statements/comparisons/index.md) [@card](card/index.md)

[Edit on GitHub](https://github.com/typedb/typedb-docs/edit/3.x-development/typeql-reference/modules/ROOT/pages/annotations/index.adoc) Edit this page on GitHub.