diff --git a/docs/index.rst b/docs/index.rst
index 4596d815ec4be501451d8ec46f550ab1c31bbbf2..74fac5e5f733dead348b6ceb7ce9c898301448ea 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -8,5 +8,6 @@ Python library for filtering, querying or inspecting almost arbitrary data struc
    :maxdepth: 1
    :caption: Contents:
 
+   language
    api
 
diff --git a/docs/language.rst b/docs/language.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5e0c8eab03520725114ea0edd2dee3f1261cbd53
--- /dev/null
+++ b/docs/language.rst
@@ -0,0 +1,137 @@
+Language reference
+==================
+
+This document describes the syntax and semantics of the custom language used in ransack.
+
+.. contents:: Table of Contents
+   :depth: 2
+   :local:
+
+Basic Data Types
+----------------
+
+- **Number**: Decimal or scientific notation.
+
+  - ``42``, ``3.14``, ``1e-5``
+
+- **String**: Enclosed in single or double quotes.
+
+  - ``"hello"``, ``'world'``
+
+- **Variable**: Alphanumeric with optional dots, underscores, or hyphens.
+
+  - ``Source.IP4``, ``.Description``
+
+- **Datetime**: Combination of date and time, optionally joined by "T".
+
+    - Full: ``2025-04-11T14:30:00``, ``2025-04-11 14:30:00Z``
+    - Date only: ``2025-04-11`` (interpreted as datetime with zeroed time)
+
+- **Timedelta**: Duration formatted as ``[D]HH:MM:SS``
+
+  - ``1D12:00:00``, ``23:59:59``
+
+- **IPv4**:
+
+  - Single: ``192.168.1.1``
+  - Range: ``192.168.1.1-192.168.1.100``
+  - CIDR: ``192.168.1.0/24``
+
+- **IPv6**:
+
+  - Single: ``2001:db8::1``
+  - Range: ``2001:db8::1-2001:db8::ff``
+  - CIDR: ``2001:db8::/64``
+
+Collections
+-----------
+
+- **List**: Comma-separated values in square brackets.
+
+  - ``[1, 2, 3.0]``, ``[192.168.0.1, 192.168.0.0/24]``
+
+- **Range**:
+
+  - ``1..1024``, ``1.0 .. 0``, ``2025-01-01 .. 2025-12-31``
+
+Arithmetic Operators
+--------------------
+
+- ``+`` : Addition
+- ``-`` : Subtraction / Negation (unary)
+- ``*`` : Multiplication
+- ``/`` : Division
+- ``%`` : Modulo
+
+Logical Operators
+-----------------
+
+- ``and`` / ``&&`` : Logical AND
+- ``or`` / ``||`` : Logical OR
+- ``not`` / ``!`` : Logical NOT
+
+Comparison Operators
+--------------------
+
+- ``=`` : Loose equality
+- ``==`` : Strict equality
+- ``>`` / ``>=`` : Greater than / Greater than or equal
+- ``<`` / ``<=`` : Less than / Less than or equal
+- ``like`` / ``LIKE`` : Pattern matching
+- ``in`` / ``IN`` : Membership test
+- ``contains`` / ``CONTAINS`` : Collection containment
+
+Special Operators
+-----------------
+
+- ``??`` : Existence check or default fallback
+
+  - ``foo ?? "default"``, ``Source.Port??[]``, ``Description??``
+
+- ``.`` : Concatenation
+
+  - ``'abc'.'def'`` , ``[1, 2, 3] . [4, 5, 6]``
+
+Functions
+---------
+
+Functions are called with parentheses. Arguments are comma-separated:
+
+.. code-block:: text
+
+    func_name(arg1, arg2)
+
+Examples:
+
+.. code-block:: text
+
+    len(Source.IP4)
+    now()
+
+
+Evaluation Order (Precedence)
+-----------------------------
+
+From highest to lowest:
+
+1. Parentheses ``()``
+2. Unary minus ``-``
+3. Existence ``??``
+4. Multiplicative: ``*``, ``/``, ``%``
+5. Additive: ``+``, ``-``
+6. Concatenation: ``.`` and Ranges: ``..``
+7. Comparison: ``=, ==, >, <, >=, <=, like, in, contains``
+8. Logical NOT: ``!``, ``not``
+9. Logical AND: ``&&``, ``and``
+10. Logical OR: ``||``, ``or``
+
+Examples
+--------
+
+.. code-block:: text
+
+    (3 + 4) * 2
+    "tcp" in Source.Proto??[]
+    not (Format == "IDEA0")
+    Source.IP4 = 192.168.0.1 or 10.0.0.0/8 in Source.IP4
+