Skip to content

Schema overview

A schema is where you tell Tickmarks two things: which values to pull out of a document, and which rules those values have to obey. The rules do most of the work. They let Tickmarks fill in values the document leaves out, choose between candidates when the model isn’t sure, and catch values that can’t all be true together.

Here is a schema for a residential lease. It asks for six fields and states three rules:

{
"hydra_schema": "1.0",
"name": "lease",
"defaults": { "locales": ["en-GB", "nl-NL"], "eom": "clamp", "end": "exclusive" },
"fields": [
{ "name": "startDate", "type": "date" },
{ "name": "endDate", "type": "date" },
{ "name": "duration", "type": "duration", "basis": "calendar" },
{ "name": "rent", "type": "money", "currency": "EUR", "scale": 2 },
{ "name": "status", "type": "enum", "values": ["active", "terminated", "draft"] },
{
"name": "terminationDate",
"type": "date",
"nullable": true,
"applicable_when": "status == 'terminated'"
}
],
"relations": [
{ "id": "term", "expr": "endDate == startDate + duration" },
{ "id": "order", "expr": "startDate < endDate" },
{ "id": "cut", "expr": "when(status == 'terminated', terminationDate <= endDate)" }
]
}

Each field has a name and a type, and some add constraints: rent must be in euros with at most two decimal places, and status must be one of three labels. terminationDate only matters for a terminated lease, which is what applicable_when says, and nullable lets a document state outright that there isn’t one. Field types covers every type and key.

The relations say how the fields fit together. term ties the three dates together so that any one can be computed from the other two, order makes sure the lease ends after it starts, and cut checks the termination date, but only when the lease is terminated. Relations explains how Tickmarks uses them.

Key Required Description
hydra_schema yes Schema language version. Always "1.0". The key is named after Hydra, the engine behind Tickmarks.
name yes A name for the schema.
defaults no Settings that apply to every field and relation unless they override them.
fields yes The values to extract. The API accepts 1 to 32 fields. See field types.
relations no Rules between fields. See relations.

Tickmarks rejects any key it doesn’t know, at every level of the schema. A typo such as "nulable" fails with an error instead of being silently ignored, which would leave the field non-nullable without your noticing.

Key Values Default Description
locales list of locale tags, such as ["en-GB", "nl-NL"] none How dates and numbers in the document are read. With several locales, an ambiguous date such as 10/03/2027 is kept as two weighted candidates and the relations decide between them.
eom "clamp" | "strict" "clamp" End-of-month rule for date arithmetic. See calendar and money.
end "exclusive" | "inclusive" "exclusive" Whether an end date is the first day after a period or its last day.
currency ISO 4217 code "EUR" Currency of money fields that don’t declare one.

Field names start with an ASCII letter or underscore, followed by letters, digits or underscores, and they’re case-sensitive. Because field names appear in expressions, the words of the expression language are reserved and can’t be used: and, or, not, when, round, is_null, is_present, true, false, null, date and dur.

Each field name must be unique, and so must each relation id.

Every response carries a schema_hash, which changes whenever the schema does. That includes small edits that only tighten a constraint, such as a new pattern, so you can always tell which version of a schema produced a given result.