Skip to content

Fairspec Table Schema

Authors Evgeny Karev
Profile https://fairspec.org/profiles/latest/table-schema.json

Fairspec Table Schema is a simple JSON based format that defines Table Schema to describe a class of tabular data resources. Table Schema structuraly compatible with JSON Schema but it doesn’t support all the JSON Schema features. It adapts some features for tabular context, and extend JSON Schema with additional tabular features.

The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in RFC 2119.

A Fairspec Table Schema is a JSON resource that MUST be an object compatible with the Table Schema structure outlined below.

A top-level descriptor object defining a schema of tabular data resources. It MIGHT have the following properties (all optional unless otherwise stated):

External Path to one of the officially published Fairspec Table Schema profiles with default value https://fairspec.org/profiles/latest/table-schema.json.

For example for version X.Y.Z of the profile:

{
"$schema": "https://fairspec.org/profiles/X.Y.Z/table-schema.json"
}

An optional human-readable title for the table schema. It MUST be a string.

For example:

{
"title": "Experimental Measurements Dataset"
}

An optional detailed description explaining the purpose and contents of the table schema. It MUST be a string.

For example:

{
"title": "Experimental Measurements Dataset",
"description": "Temperature and pressure measurements collected during chemical reaction experiments performed in laboratory conditions."
}

An optional list of column names that are required to present. Each item MUST be a string matching a key in the properties object.

For example, to require specific columns:

{
"required": ["experiment_id", "temperature", "pressure"],
"properties": {
"experiment_id": {
"type": "integer"
},
"temperature": {
"type": "number"
},
"pressure": {
"type": "number"
},
"notes": {
"type": "string"
}
}
}

An object defining the schema for table columns. Each key represents a column name, and its value MUST be a valid Column definition.

For example, for a simple table with different column types:

{
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"active": {
"type": "boolean"
}
}
}

An optional array of column names that form the table’s primary key. The combination of values in these columns MUST uniquely identify each row. At least one column name MUST be specified if this property is present.

For example, with a single-column primary key:

{
"primaryKey": ["experiment_id"],
"properties": {
"experiment_id": {
"type": "integer"
},
"measurement": {
"type": "number"
}
}
}

For example, with a composite primary key:

{
"primaryKey": ["sample_id", "timestamp"],
"properties": {
"sample_id": {
"type": "string"
},
"timestamp": {
"type": "string",
"format": "date-time"
},
"value": {
"type": "number"
}
}
}

An optional array of unique key constraints. Each unique key is an array of column names whose combined values MUST be unique across all rows in the table. Each unique key array MUST contain at least one column name.

For example, with multiple unique constraints:

{
"uniqueKeys": [
["email"],
["username"],
["department", "employee_number"]
],
"properties": {
"email": {
"type": "string",
"format": "email"
},
"username": {
"type": "string"
},
"department": {
"type": "string"
},
"employee_number": {
"type": "integer"
}
}
}

An optional array of foreign key constraints that define relationships between this table and other tables. Each foreign key specifies local columns and their reference to columns in another resource (identified by resource name in the dataset context).

For example, referencing another resource:

{
"foreignKeys": [
{
"columns": ["customer_id"],
"reference": {
"resource": "customers",
"columns": ["id"]
}
}
],
"properties": {
"order_id": {
"type": "integer"
},
"customer_id": {
"type": "integer"
},
"amount": {
"type": "number"
}
}
}

For example, with a self-reference (omitting resource):

{
"foreignKeys": [
{
"columns": ["parent_id"],
"reference": {
"columns": ["id"]
}
}
],
"properties": {
"id": {
"type": "integer"
},
"parent_id": {
"type": "integer"
},
"name": {
"type": "string"
}
}
}

For example, with a composite foreign key:

{
"foreignKeys": [
{
"columns": ["supplier_id", "product_code"],
"reference": {
"resource": "catalog",
"columns": ["supplier_id", "code"]
}
}
]
}

An optional list of values that represent missing or null data across all columns in the table. Each item can be either a simple value or an object with value and label properties for documentation purposes. The values type MUST be "string" or "integer".

For example, with simple values:

{
"missingValues": ["NA", "N/A", "", -999]
}

For example, with labeled values:

{
"missingValues": [
{ "value": "NA", "label": "Not Available" },
{ "value": "NR", "label": "Not Recorded" },
{ "value": -999, "label": "Sensor Error" }
]
}

For example, with mixed values:

{
"missingValues": [
'NA',
{ "value": -999, "label": "Sensor Error" }
]
}

A column definition that specifies the data type, constraints, and metadata for a table column. The schema is routed based on the type property and optionally the format property to determine which specific column type applies.

The data type of the column. It MUST be one of the following values:

  • boolean - True/false values
  • integer - Whole numbers
  • number - Numeric values
  • string - Text values
  • array - Array/list values
  • object - Object/dictionary values

If a column allows missing values the type can include null (order insensitive):

  • ["boolean", "null"] - True/false values or missing values
  • ["integer", "null"] - Whole numbers or missing values
  • ["number", "null"] - Numeric values or missing values
  • ["string", "null"] - Text values or missing values
  • ["array", "null"] - Array/list values or missing values
  • ["object", "null"] - Object/dictionary values or missing values

Any other value of the type property indicates that the column type is Unknown.

Metadata example:

{
"properties": {
"age": {
"type": "integer"
},
"title": {
"type": ["string", "null"]
},
}
}

Data example:

age
25
32
18

An optional human-readable title for the column. It MUST be a string.

Metadata example:

{
"properties": {
"temp_c": {
"type": "number",
"title": "Temperature (Celsius)"
}
}
}

Data example:

temp_c
23.5
-10.2
98.6

An optional detailed description of the column. It MUST be a string.

Metadata example:

{
"properties": {
"pressure": {
"type": "number",
"description": "Atmospheric pressure measured in hectopascals (hPa) at the time of observation."
}
}
}

Data example:

pressure
1013.25
1020.50
995.30

An optional property that provides a richer, “semantic” description of the type of data in a column. The value MUST be the URI of a RDF Class, that is an instance or subclass of RDF Schema Class object.

Metadata example:

{
"properties": {
"country": {
"type": "string",
"rdfType": "http://schema.org/Country"
}
}
}

Data example:

country
US
UK
DE
FR

An optional array of allowed values for the column. The values MUST match the column’s type.

For example, with string values:

{
"properties": {
"status": {
"type": "string",
"enum": ["pending", "active", "completed", "cancelled"]
}
}
}

For example, with integer values:

{
"properties": {
"priority": {
"type": "integer",
"enum": [1, 2, 3, 4, 5]
}
}
}

Data example:

status
pending
active
completed
cancelled

An optional constant value for the column. The value MUST match the column’s type.

For example, with string values:

{
"properties": {
"status": {
"type": "string",
"const": "pending"
}
}
}

For example, with integer values:

{
"properties": {
"priority": {
"type": "integer",
"const": 1
}
}
}

Data example:

status
pending
pending

An optional default value for the column. The value MUST match the column’s type. This property is for documentation purpose and it is not used to fill missing values.

Metadata example:

{
"properties": {
"status": {
"type": "string",
"default": "pending"
"missingValues": ["N/A"]
}
}
}

Data example:

status
done
N/A

An optional array of example values for the column. The values MUST match the column’s type and can be used for documentation, testing, or generating sample data.

Metadata example:

{
"properties": {
"temperature": {
"type": "number",
"examples": [20.5, 25.3, 18.7]
}
}
}

Data example:

temperature
20.5
25.3
18.7

An optional column-level list of values that represent missing or null data for this column. Each item can be either a simple value or an object with value and label properties for documentation purposes. The missing values type MUST be:

  • "string" or "integer" for boolean, integer, and number columns
  • "string" for all other columns

If table-level missing values are provided, the effective missing values MUST include all the column-level values and all the compatible table-level values.

Metadata example:

{
"properties": {
"measurement": {
"type": "number",
"missingValues": [
{ "value": -999, "label": "Sensor malfunction" },
{ "value": "NA", "label": "Not measured" }
]
}
}
}

Data example:

measurement
25.3
-999
NA
42.1

A column for true/false values. It MUST have type set to "boolean" and MUST NOT have a format property.

Metadata example:

{
"properties": {
"is_active": {
"type": "boolean"
}
}
}

Data example:

is_active
true
false
true

Type properties:

A column for categorical values. It MUST have type set to "integer" or "string" and format set to "categorical".

Metadata example:

{
"properties": {
"severity": {
"type": "integer",
"categories": [
{ "value": 1, "label": "Low" },
{ "value": 2, "label": "Medium" },
{ "value": 3, "label": "High" }
]
}
}
}

Data example:

severity
1
2
3
1

Type properties:

In addition, type properties if type is "integer":

In addition, type properties if type is "string":

A column for whole number values. It MUST have type set to "integer" and MUST NOT have a format property.

Metadata example:

{
"properties": {
"age": {
"type": "integer"
}
}
}

Data example:

age
25
32
18

Type properties:

A column for numeric values including decimals. It MUST have type set to "number" and MUST NOT have a format property.

Metadata example:

{
"properties": {
"temperature": {
"type": "number"
}
}
}

Data example:

temperature
23.5
-10.2
98.6

Type properties:

A column for decimal values. It MUST have type set to "string" and format set to "decimal".

Metadata example:

{
"properties": {
"price": {
"type": "string",
"format": "decimal"
}
}
}

Data example:

price
19.99
5.50
123.45

Type properties:

A column for text values. It MUST have type set to "string" and MUST NOT have a format property.

Metadata example:

{
"properties": {
"name": {
"type": "string"
}
}
}

Data example:

name
Alice
Bob
Charlie

Type properties:

A column for delimited list values stored as strings. It MUST have type set to "string" and format set to "list".

Metadata example:

{
"properties": {
"tags": {
"type": "string",
"format": "list"
}
}
}

Data example:

tags
"red,blue,green"
"small,compact"
"new,sale,featured"

Type properties:

A column for URLs with HTTP/HTTPS protocol. It MUST have type set to "string" and format set to "url".

Metadata example:

{
"properties": {
"homepage": {
"type": "string",
"format": "url"
}
}
}

Data example:

homepage
https://example.com
https://example.org/page
https://domain.net/path/to/resource

Type properties:

A column for email addresses. It MUST have type set to "string" and format set to "email".

Metadata example:

{
"properties": {
"contact_email": {
"type": "string",
"format": "email"
}
}
}

Data example:

contact_email
alice@example.com
bob@company.org
charlie@domain.net

Type properties:

A column for ISO 8601 date values. It MUST have type set to "string" and format set to "date".

Metadata example:

{
"properties": {
"birth_date": {
"type": "string",
"format": "date"
}
}
}

Data example:

birth_date
2023-12-01
1990-06-15
2005-03-20

Type properties:

A column for ISO 8601 time values. It MUST have type set to "string" and format set to "time".

Metadata example:

{
"properties": {
"start_time": {
"type": "string",
"format": "time"
}
}
}

Data example:

start_time
14:30:00
09:45:30
18:00:00

Type properties:

A column for ISO 8601 date with time values. It MUST have type set to "string" and format set to "date-time".

Metadata example:

{
"properties": {
"created_at": {
"type": "string",
"format": "date-time"
}
}
}

Data example:

created_at
2023-12-01T14:30:00Z
2024-01-15T09:45:30+00:00
2024-03-20T18:00:00-05:00

Type properties:

A column for ISO 8601 duration values. It MUST have type set to "string" and format set to "duration".

Metadata example:

{
"properties": {
"elapsed_time": {
"type": "string",
"format": "duration"
}
}
}

Data example:

elapsed_time
PT1H30M
P1DT12H
PT45M30S

Type properties:

A column for Well-Known Text (WKT) geometry data. It MUST have type set to "string" and format set to "wkt".

Metadata example:

{
"properties": {
"geometry": {
"type": "string",
"format": "wkt"
}
}
}

Data example:

geometry
"POINT (30 10)"
"LINESTRING (30 10, 10 30, 40 40)"
"POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))"

Type properties:

A column for Well-Known Binary (WKB) geometry data. It MUST have type set to "string" and format set to "wkb".

Metadata example:

{
"properties": {
"geometry": {
"type": "string",
"format": "wkb"
}
}
}

Data example:

geometry
0101000000000000000000000000000000000024400000000000003E40
0102000000030000000000000000003E400000000000002440
0103000000010000000500000000000000000024400000000000003E40

Type properties:

A column for hexadecimal encoded data. It MUST have type set to "string" and format set to "hex".

Metadata example:

{
"properties": {
"color": {
"type": "string",
"format": "hex"
}
}
}

Data example:

color
FF5733
00BFFF
32CD32

Type properties:

A column for Base64 encoded binary data. It MUST have type set to "string" and format set to "base64".

Metadata example:

{
"properties": {
"thumbnail": {
"type": "string",
"format": "base64"
}
}
}

Data example:

thumbnail
iVBORw0KGgoAAAANSUhEUgAAAAUA
R0lGODlhAQABAIAAAAAAAP///yH5
aGVsbG8gd29ybGQ=

Type properties:

A column for array/list values. It MUST have type set to "array" and MUST NOT have a format property.

Metadata example:

{
"properties": {
"coordinates": {
"type": "array"
}
}
}

Data example:

coordinates
"[1.5, 2.3]"
"[10, 20, 30]"
"[-5.2, 8.9, 12.1]"

Type properties:

A column for object/dictionary values. It MUST have type set to "object" and MUST NOT have a format property.

Metadata example:

{
"properties": {
"metadata": {
"type": "object"
}
}
}

Data example:

metadata
"{""author"": ""John"", ""version"": 1}"
"{""author"": ""Jane"", ""version"": 2}"
"{""author"": ""Bob"", ""version"": 1}"

Type properties:

A column for GeoJSON geometry objects. It MUST have type set to "object" and format set to "geojson".

Metadata example:

{
"properties": {
"location": {
"type": "object",
"format": "geojson"
}
}
}

Data example:

location
"{""type"": ""Point"", ""coordinates"": [30, 10]}"
"{""type"": ""LineString"", ""coordinates"": [[30, 10], [10, 30], [40, 40]]}"
"{""type"": ""Polygon"", ""coordinates"": [[[30, 10], [40, 40], [20, 40], [10, 20], [30, 10]]]}"

Type properties:

A column for TopoJSON geometry objects. It MUST have type set to "object" and format set to "topojson".

Metadata example:

{
"properties": {
"topology": {
"type": "object",
"format": "topojson"
}
}
}

Data example:

topology
"{""type"": ""Topology"", ""objects"": {""example"": {""type"": ""Point"", ""coordinates"": [0, 0]}}}"
"{""type"": ""Topology"", ""arcs"": [[[0, 0], [1, 1]]], ""objects"": {""line"": {""type"": ""LineString"", ""arcs"": [0]}}}"
"{""type"": ""Topology"", ""objects"": {""polygon"": {""type"": ""Polygon"", ""arcs"": [[0]]}}}"

Type properties:

A column for values of unknown type. It MUST have type not supported by the types above.

Metadata example:

{
"properties": {
"column": {
"title": "Column",
"description": "Column description",
}
}
}

Data example:

column
a
1
false

An optional format qualifier that specifies a more specific subtype of the base type.

Metadata example:

{
"properties": {
"email": {
"type": "string",
"format": "email"
}
}
}

Data example:

email
alice@example.com
bob@company.org
charlie@domain.net

An optional array of string values that SHOULD be interpreted as true when parsing data. It MUST be an array of strings.

Metadata example:

{
"properties": {
"is_active": {
"type": "boolean",
"trueValues": ["yes", "true", "1", "Y"]
}
}
}

Data example:

is_active
yes
true
1
Y

An optional array of string values that SHOULD be interpreted as false when parsing data. It MUST be an array of strings.

Metadata example:

{
"properties": {
"is_active": {
"type": "boolean",
"falseValues": ["no", "false", "0", "N"]
}
}
}

Data example:

is_active
no
false
0
N

An optional minimum value constraint (inclusive). The type MUST match the column type.

Metadata example:

{
"properties": {
"temperature": {
"type": "number",
"minimum": -273.15
}
}
}

Data example:

temperature
-200.5
25.3
100.0

An optional maximum value constraint (inclusive). The type MUST match the column type.

Metadata example:

{
"properties": {
"temperature": {
"type": "number",
"maximum": 1000
}
}
}

Data example:

temperature
25.5
100.0
999.9

An optional minimum value constraint (exclusive). The type MUST match the column type.

Metadata example:

{
"properties": {
"probability": {
"type": "number",
"exclusiveMinimum": 0
}
}
}

Data example:

probability
0.1
0.5
0.999

An optional maximum value constraint (exclusive). The type MUST match the column type.

Metadata example:

{
"properties": {
"probability": {
"type": "number",
"exclusiveMaximum": 1
}
}
}

Data example:

probability
0.001
0.5
0.999

An optional constraint that values MUST be a multiple of this number. For integers, it MUST be a positive integer. For numbers, it MUST be a positive number.

Metadata example:

{
"properties": {
"price": {
"type": "number",
"multipleOf": 0.01
}
}
}

Data example:

price
10.00
25.50
99.99

An optional single character used as the decimal separator in the data.

Metadata example:

{
"properties": {
"price": {
"type": "number",
"decimalChar": ","
}
}
}

Data example:

price
19,99
5,50
123,45

An optional single character used as the thousands separator in the data. It MUST be a string of length 1.

Metadata example:

{
"properties": {
"population": {
"type": "integer",
"groupChar": ","
}
}
}

Data example:

population
1,234,567
890,123
45,678

An optional boolean indicating whether numeric values may include non-numeric text that should be stripped during parsing.

Metadata example:

{
"properties": {
"price": {
"type": "number",
"withText": true
}
}
}

Data example:

price
$19.99
€25.50
£12.34

An optional minimum length constraint for string values. It MUST be a non-negative integer.

Metadata example:

{
"properties": {
"username": {
"type": "string",
"minLength": 3
}
}
}

Data example:

username
alice
bob123
charlie

An optional maximum length constraint for string values. It MUST be a non-negative integer.

Metadata example:

{
"properties": {
"username": {
"type": "string",
"maxLength": 20
}
}
}

Data example:

username
alice
bob
charlie

An optional regular expression pattern that values MUST match. It MUST be a valid regex string.

Metadata example:

{
"properties": {
"product_code": {
"type": "string",
"pattern": "^[A-Z]{3}-[0-9]{4}$"
}
}
}

Data example:

product_code
ABC-1234
XYZ-5678
DEF-9012

An optional array of categorical values with optional labels. Each item can be either a simple value or an object with value and label properties. The values MUST have the same type as the containing property i.e. "string" or "integer".

Metadata example:

{
"properties": {
"severity": {
"type": "integer",
"categories": [
{ "value": 1, "label": "Low" },
{ "value": 2, "label": "Medium" },
{ "value": 3, "label": "High" }
]
}
}
}

Data example:

severity
1
2
3
1

An optional boolean indicating that the categorical values in the column have natural order.

Metadata example:

{
"properties": {
"severity": {
"type": "integer",
"categoriesOrdered": true,
"categories": [
{ "value": 1, "label": "Low" },
{ "value": 2, "label": "Medium" },
{ "value": 3, "label": "High" }
]
}
}
}

Data example:

severity
1
2
3
1

An optional single character used to delimit items in a list column.

Metadata example:

{
"properties": {
"tags": {
"type": "string",
"format": "list",
"delimiter": ";"
}
}
}

Data example:

tags
red;green;blue
alpha;beta
gamma;delta;epsilon

An optional type for items in a list column. It MUST be one of: string, integer, number, boolean, date-time, date, time.

Metadata example:

{
"properties": {
"measurements": {
"type": "string",
"format": "list",
"itemType": "number"
}
}
}

Data example:

measurements
"1.5,2.3,4.7"
"10.2,15.8"
"3.14,2.71,1.41"

An optional minimum number of items for the column. It MUST be a non-negative integer.

Metadata example:

{
"properties": {
"tags": {
"type": "string",
"format": "list",
"minItems": 1
}
}
}

Data example:

tags
"red,blue,green"
"small,compact"
"new,sale,featured"

An optional maximum number of items for the column. It MUST be a non-negative integer.

Metadata example:

{
"properties": {
"tags": {
"type": "string",
"format": "list",
"maxItems": 3
}
}
}

Data example:

tags
"red,blue,green"
"small,compact"
"new,sale,featured"

An optional string specifying the temporal format pattern as per the Strftime specification.

Metadata example:

{
"properties": {
"collection_date": {
"type": "string",
"format": "date",
"temporalFormat": "%m/%d/%Y"
}
}
}

Data example:

collection_date
01/15/2024
03/22/2024
12/31/2023

For array and object column types, all properties from JSON Schema Draft 2020-12 are supported to define the structure and validation rules.

For example, with an array column:

{
"properties": {
"coordinates": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 3
}
}
}

Data example:

coordinates
"[1.5, 2.3]"
"[10.2, 15.8, 20.5]"
"[3.14, 2.71]"

For example, with an object column:

{
"properties": {
"metadata": {
"type": "object",
"properties": {
"author": { "type": "string" },
"version": { "type": "integer" }
},
"required": ["author"]
}
}
}

Data example:

metadata
"{""author"": ""Alice"", ""version"": 1}"
"{""author"": ""Bob"", ""version"": 2}"
"{""author"": ""Charlie""}"

Common properties shared by multiple entities in the descriptor.

It MUST be a string representing an HTTP or HTTPS URL to a remote file.

For example:

{
"data": "https://example.com/datasets/measurements.csv"
}

Fairspec Table Schema does not support extension.