Reference

Semantic Types

Choose a column type and check which inputs it accepts.

A semantic type tells Silo how to check a value and store it in SQLite. For example, text/datetime accepts a timestamp with a time zone and converts it to UTC. text/enum accepts only the strings listed in the column definition.

Each type uses one SQLite storage class: TEXT, INTEGER, REAL, BLOB, or ANY. Some types also add SQLite constraints or format values for row output.

Use this page to choose a type or understand a rejected value. Column examples below belong in a table definition's columns array. See Design a schema for a complete table.

Use the column comment to explain what the value means. For example, say which currency an amount uses and whether null means “unknown” or “not applicable.”

Choose a type quickly

Value you need Type to consider
Unstructured text text
Native JSON object or array text/json
Timestamp with a time zone text/datetime
Calendar date text/date
UUID or ULID identity text/uuid or text/ulid
Exact amount integer/money-minor or configured text/decimal
Boolean flag integer/boolean
Fraction from 0 to 1 real/percentage
Arbitrary SQLite scalar any

Null, defaults, and canonical values

JSON null becomes SQL NULL only when the column is nullable. Non-nullable columns reject it. Literal defaults go through the same checks and conversion as values in a write request.

For example, this default is stored as a UTC instant rather than preserving its input offset:

{
  "name": "observed_at",
  "type": "text/datetime",
  "nullable": false,
  "default": { "literal": "2026-07-11T09:30:00-04:00" },
  "comment": "UTC instant represented by this observation."
}

The example default becomes 2026-07-11T13:30:00.000Z.

Base storage types

Type Accepted JSON value Stored behavior
text String Stores the string unchanged.
integer Safe integer Stores the integer unchanged.
real Finite number Stores the number unchanged.
blob Base64 string Decodes and stores bytes.
any String, finite number, boolean, or nullable null Stores a SQLite scalar; booleans become 0 or 1. Objects and arrays are rejected.

Text types

Type Accepted form Normalization or options
text/uuid UUID with a version digit from 1 through 8 and RFC variant bits Lowercase.
text/ulid 26-character ULID Uppercase.
text/slug Lowercase letters and digits separated by single hyphens None.
text/git-oid Hexadecimal object ID Lowercase; set type_options.length explicitly to 40 or 64.
text/date Valid YYYY-MM-DD calendar date Rejects rollover dates such as 2025-02-30.
text/time HH:MM:SS, optional fractional seconds, optional Z or numeric offset None.
text/datetime ISO-like instant with Z or numeric offset Converts to a UTC ISO string.
text/json JSON object, array, string, finite number, or boolean Stores compact JSON text.
text/markdown String No content transformation.
text/html String No content transformation.
text/url URL with a protocol and hostname None.
text/uri String beginning with a URI scheme None.
text/email Basic local-part, @, and dotted-domain form None.
text/ip IPv4 or IPv6 address None.
text/cidr IP address plus valid prefix length None.
text/hostname DNS-style hostname up to 253 characters Lowercase.
text/path String without a null byte Platform-neutral validation only.
text/path-posix String without a null byte or backslash None.
text/path-relative String that does not start with / or contain a slash-separated .. segment None.
text/git-ref String excluding Git's forbidden ref patterns None.
text/semver Semantic version with optional prerelease and build suffixes None.
text/base64 Valid padded base64 text Stores text rather than decoded bytes.
text/hex Even-length hexadecimal text Lowercase.
text/sha256 64 hexadecimal characters Lowercase.
text/sha512 128 hexadecimal characters Lowercase.
text/decimal Signed decimal string without exponent notation Requires integer precision and scale; pads fractional digits to scale.
text/enum One configured string Requires type_options.values.

Git object IDs

Set type_options.length explicitly for text/git-oid. The current default validator rejects ordinary Git hashes when the option is omitted.

For a SHA-1 repository, this column accepts a 40-character hexadecimal ID and stores it in lowercase:

{
  "name": "commit_id",
  "type": "text/git-oid",
  "type_options": { "length": 40 },
  "nullable": false,
  "comment": "Git commit containing the change."
}

Use 64 for a SHA-256 repository.

Exact decimals

Configure an exact decimal with six total digits and two fractional digits:

{
  "name": "amount",
  "type": "text/decimal",
  "type_options": { "precision": 6, "scale": 2 },
  "nullable": false,
  "comment": "Exact transaction amount in account currency."
}

An input of "12.5" is stored as "12.50"; exponent notation and values exceeding the configured precision or scale are rejected.

Allowed strings

Use an enum when only a known set of strings is valid:

{
  "name": "state",
  "type": "text/enum",
  "type_options": { "values": ["open", "closed"] },
  "nullable": false,
  "comment": "Whether the issue still needs work."
}

The column accepts "open" and "closed". It rejects other strings and null.

Integer, real, and blob types

Type Accepted form Additional behavior
integer/boolean JSON boolean or integer 0 or 1 Stores 0 or 1; row output renders a boolean.
integer/positive Safe integer greater than zero Adds a physical check.
integer/nonnegative Safe integer zero or greater Adds a physical check.
integer/port Safe integer from 0 through 65535 Adds a physical check.
integer/unix-seconds Safe integer Unit meaning is documented, not range-limited.
integer/unix-milliseconds Safe integer Unit meaning is documented, not range-limited.
integer/duration-ms Nonnegative safe integer Adds a physical check.
integer/money-minor Safe integer Unit meaning is documented by the column comment.
real/percentage Finite number from 0 through 1 Adds a physical check.
blob/bytes Base64 JSON string Decodes and stores bytes.

real/percentage uses fractions: 0.25 means 25%; 25 is rejected. For integer/money-minor, document the unit, such as cents, in the column comment. The type does not choose a currency for you.

Text validation checks form, not whether a resource exists or is safe to use. For example, text/url does not fetch the URL, and text/path-relative does not make a path safe for every operating system. text/html stores its input without sanitizing it.