> ## Documentation Index
> Fetch the complete documentation index at: https://docs.keeps.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Annotations

> Add application-owned values to an asset or generation when they become known.

Use `properties` for values known during capture. Use `annotate()` for values
learned later, such as review state, workflow labels, or pipeline versions.

<CodeGroup>
  ```ts Node theme={null}
  keeps.annotate(
    { asset: outputRow.id },
    {
      review_status: "approved",
      reviewed_at: keeps.timestamp(new Date()),
    },
    { userId, sessionId },
  );
  ```

  ```python Python theme={null}
  from datetime import datetime, timezone
  from keeps import timestamp

  keeps.annotate(
      {"asset": output_row.id},
      {
          "review_status": "approved",
          "reviewed_at": timestamp(datetime.now(timezone.utc)),
      },
      user_id=user_id,
      session_id=session_id,
  )
  ```
</CodeGroup>

An annotation targets exactly one asset or one generation. Sending `null`
clears that key for the same source.

Normal strings, numbers, booleans, lists, objects, and nulls need no wrapper.
Use `timestamp()` only when the value should be interpreted as time.

The catalog is advisory: a single odd value does not block capture. Analysis
reports values that cannot be read as the field's selected type.
