Version: 2.0.0
On this page
The Spacetime Algebraic Type Notation binary (BSATN) format defines how
Spacetime AlgebraicValues and friends are encoded as byte strings.
Algebraic values and product values are BSATN-encoded for e.g., module-host communication and for storing row data in the database.
Notes on notation
In this reference, we give a formal definition of the format. To do this, we use inductive definitions, and define the following notation:
bsatn(x)denotes a function converting some valuexto a list of bytes.a: Bmeans thatais of typeB.Foo(x)denotes extractingxout of some variant or typeFoo.a ++ bdenotes concatenating two byte listsaandb.bsatn(A) = bsatn(B) | ... | bsatn(Z)whereBtoZare variants ofAmeans thatbsatn(A)is defined as e.g.,bsatn(B),bsatn(C), ..,bsatn(Z)depending on what variant ofAit was.[]denotes the empty list of bytes.
Values
At a glance
| Type | Description |
|---|---|
AlgebraicValue | A value of any type. |
SumValue | A value of a sum type, i.e. an enum or tagged union. |
ProductValue | A value of a product type, i.e. a struct or tuple. |
AlgebraicValue
The BSATN encoding of an AlgebraicValue defers to the encoding of each
variant:
bsatn(AlgebraicValue)
= bsatn(SumValue)
| bsatn(ProductValue)
| bsatn(ArrayValue)
| bsatn(String)
| bsatn(Bool)
| bsatn(U8) | bsatn(U16) | bsatn(U32) | bsatn(U64) | bsatn(U128) | bsatn(U256)
| bsatn(I8) | bsatn(I16) | bsatn(I32) | bsatn(I64) | bsatn(I128) | bsatn(I256)
| bsatn(F32) | bsatn(F64)
Algebraic values include sums, products, arrays, strings, and primitives types. The primitive types include booleans, unsigned and signed integers up to 256-bits, and floats, both single and double precision.
SumValue
An instance of a sum type, i.e. an enum or tagged union. SumValues are
binary-encoded as bsatn(tag) ++ bsatn(variant_data) where tag: u8 is
an index into the SumType.variants array of the value’s SumType, and
where variant_data is the data of the variant. For variants holding no
data, i.e., of some zero sized type, bsatn(variant_data) = [].
ProductValue
An instance of a product type, i.e. a struct or tuple. ProductValues
are binary encoded as:
bsatn(elems) = bsatn(elem_0) ++ .. ++ bsatn(elem_n)
Field names are not encoded.
ArrayValue
The encoding of an ArrayValue is:
bsatn(ArrayValue(a))
= bsatn(len(a) as u32)
++ bsatn(normalize(a)_0)
++ ..
++ bsatn(normalize(a)_n)
where normalize(a) for a: ArrayValue converts a to a list of
AlgebraicValues.
Strings
For strings, the encoding is defined as:
bsatn(String(s)) = bsatn(len(s) as u32) ++ bsatn(utf8_to_bytes(s))
That is, the BSATN encoding is the concatenation of
- the bsatn of the string’s length as a
u32integer byte - the utf8 representation of the string as a byte array
Primitives
For the primitive variants of AlgebraicValue, the BSATN encodings
are:s
bsatn(Bool(false)) = [0]
bsatn(Bool(true)) = [1]
bsatn(U8(x)) = [x]
bsatn(U16(x: u16)) = to_little_endian_bytes(x)
bsatn(U32(x: u32)) = to_little_endian_bytes(x)
bsatn(U64(x: u64)) = to_little_endian_bytes(x)
bsatn(U128(x: u128)) = to_little_endian_bytes(x)
bsatn(U256(x: u256)) = to_little_endian_bytes(x)
bsatn(I8(x: i8)) = to_little_endian_bytes(x)
bsatn(I16(x: i16)) = to_little_endian_bytes(x)
bsatn(I32(x: i32)) = to_little_endian_bytes(x)
bsatn(I64(x: i64)) = to_little_endian_bytes(x)
bsatn(I128(x: i128)) = to_little_endian_bytes(x)
bsatn(I256(x: i256)) = to_little_endian_bytes(x)
bsatn(F32(x: f32)) = bsatn(f32_to_raw_bits(x)) // lossless conversion
bsatn(F64(x: f64)) = bsatn(f64_to_raw_bits(x)) // lossless conversion
bsatn(String(s)) = bsatn(len(s) as u32) ++ bsatn(bytes(s))
Where
f32_to_raw_bits(x)extracts the raw bits ofx: f32tou32f64_to_raw_bits(x)extracts the raw bits ofx: f64tou64
Types
All SATS types are BSATN-encoded by converting them to an
AlgebraicValue, then BSATN-encoding that meta-value.
See the SATN JSON Format for more details of the conversion to meta values. Note that these meta values are converted to BSATN and not JSON.
Last updated Oct 08, 2026