/api/v1/schema
The schema endpoint exposes the JSON-Schema view of a datamodel version — the structural description that /api/db and /api/search validate against. The same datamodel can also be rendered as a diagram via ?format=svg / ?format=png.
version can be:
HEAD— the working copy (uncommitted edits).CURRENT— the most recently committed version. Resolved server-side; equivalent to the highest committed number.a positive integer pointing at a specific committed version.
Reading requires only an authenticated user; no system.datamodel right is needed.
GET /schema/user/{version} — Retrieve a datamodel snapshot.
Returns the datamodel either as a SchemaApi JSON object
(default) or as an image of its objecttype graph.
Access token in the Authorization header:
Authorization: Bearer <token>.
Datamodel version. HEAD returns the working copy;
CURRENT resolves to the most recently committed version;
numeric ids return a specific committed snapshot.
^(HEAD|CURRENT|[1-9][0-9]*)$When set, returns a rendered graph of the schema instead of
the JSON representation. The response is
image/svg+xml / image/png with
Content-Disposition: inline; filename="fylr-schema-<instance>-<version>-v<n>.<ext>".
Any other value (or no value) returns the JSON form.
Differs from easydb 5: the default (no format) response is the
JSON SchemaApi, and there is no XML form. easydb 5 documented
format=xml as the default representation.
The datamodel snapshot. By default a JSON SchemaApi
document; when format=svg / format=png, the rendered
graph image.
A fylr datamodel snapshot at a specific version — the JSON-Schema
view that /api/db and /api/search validate against.
This is the shape GET /api/v1/schema/user/{version} returns when
the format query parameter is unset (or any value other than svg
/ png).
The datamodel version this snapshot represents. Every datamodel
record carries a version — HEAD's version equals the version a
future commit would produce. To distinguish HEAD from a committed
snapshot, check committed_at (null on HEAD).
The committed datamodel version this snapshot derives from. For
a committed version, equals version - 1. For HEAD, the last
committed version this working copy was forked off.
The base-version (pre-customisation) the snapshot derives from. Used by upgrades to track the upstream baseline separately from per-instance edits.
Highest table_id used in this snapshot. New tables added in a
subsequent edit start at max_table_id + 1.
Highest column id used in this snapshot. New columns added in a
subsequent edit start at max_column_id + 1.
Always user — the user-defined datamodel. (fylr also has a
system datamodel; that one is not exposed through /schema.)
The version in the URL does not resolve to an existing
datamodel — a numeric version that matches no datamodel row
(the lookup is by version number, independent of whether that
version was committed), or a non-positive value. The body
carries code DatamodelVersionNotFound. Note this is a 400,
not a 404.
Differs from easydb 5: an unknown schema version is reported as
400 DatamodelVersionNotFound, not the 404 easydb 5
documented for a "Requested schema version not found".
No authenticated user. The request must carry a valid access token.
{
"version": 1,
"based_on_version": 1,
"based_on_base_version": 1,
"max_table_id": 1,
"max_column_id": 1,
"type": "user",
"tables": [
{
"name": "text",
"table_id": 1,
"pool_link": true,
"owned_by": {
"other_table_id": 1,
"other_table_name_hint": "text"
},
"acl_table": true,
"has_tags": true,
"is_hierarchical": true,
"polyhierarchical": true,
"in_main_search": true,
"comment": "text",
"columns": [
{
"kind": "text",
"name": "text",
"type": "text",
"not_null": true,
"column_id": 1,
"reverse_edit": true,
"is_hierarchical": true,
"check": "text",
"check_regexp": "text",
"check_regexp_flags": "text",
"check_range_lower": null,
"check_range_upper": null,
"check_range_lower_open": null,
"check_range_upper_open": null,
"check_range_not_empty": true,
"length_min": 1,
"length_max": 1,
"other_table_id": 1,
"other_table_name_hint": "text",
"other_column_id": 1,
"other_column_name_hint": "text",
"bidirectional_reverse": true,
"custom_settings": {
"ANY_ADDITIONAL_PROPERTY": "text"
},
"name_localized": {
"de-DE": "Deutscher text",
"en-US": "English text"
}
}
],
"foreign_keys": [
{
"name": "text",
"on_delete": "text",
"on_update": "text",
"columns": [
{
"column_id": 1,
"column_name_hint": "text"
}
],
"referenced_table": {
"table_id": 1,
"name_hint": "text",
"columns": [
{
"auto_column_primary_key": true
}
]
}
}
],
"unique_keys": [
{
"group": "text",
"columns": [
{
"auto_column_parent": true,
"auto_column_uplink": true,
"column_id": 1,
"column_name_hint": "text"
}
]
}
],
"bidirectional": [
{
"columns": [
{
"auto_column_uplink": true,
"column_id": 1,
"column_name_hint": "text"
}
]
}
]
}
]
}POST /schema/user/HEAD — Update the working datamodel (HEAD).
Writes the supplied SchemaApi document into the working copy.
The change is only visible to other readers after a commit via
POST /schema/commit. Requires
system.datamodel[level=development] (or [level=commit]).
Access token in the Authorization header:
Authorization: Bearer <token>.
A fylr datamodel snapshot at a specific version — the JSON-Schema
view that /api/db and /api/search validate against.
This is the shape GET /api/v1/schema/user/{version} returns when
the format query parameter is unset (or any value other than svg
/ png).
The datamodel version this snapshot represents. Every datamodel
record carries a version — HEAD's version equals the version a
future commit would produce. To distinguish HEAD from a committed
snapshot, check committed_at (null on HEAD).
The committed datamodel version this snapshot derives from. For
a committed version, equals version - 1. For HEAD, the last
committed version this working copy was forked off.
The base-version (pre-customisation) the snapshot derives from. Used by upgrades to track the upstream baseline separately from per-instance edits.
Highest table_id used in this snapshot. New tables added in a
subsequent edit start at max_table_id + 1.
Highest column id used in this snapshot. New columns added in a
subsequent edit start at max_column_id + 1.
Always user — the user-defined datamodel. (fylr also has a
system datamodel; that one is not exposed through /schema.)
The HEAD datamodel was updated. The response returns the
stored SchemaApi (with any server-applied normalisations
and the bumped max_table_id / max_column_id).
A fylr datamodel snapshot at a specific version — the JSON-Schema
view that /api/db and /api/search validate against.
This is the shape GET /api/v1/schema/user/{version} returns when
the format query parameter is unset (or any value other than svg
/ png).
The datamodel version this snapshot represents. Every datamodel
record carries a version — HEAD's version equals the version a
future commit would produce. To distinguish HEAD from a committed
snapshot, check committed_at (null on HEAD).
The committed datamodel version this snapshot derives from. For
a committed version, equals version - 1. For HEAD, the last
committed version this working copy was forked off.
The base-version (pre-customisation) the snapshot derives from. Used by upgrades to track the upstream baseline separately from per-instance edits.
Highest table_id used in this snapshot. New tables added in a
subsequent edit start at max_table_id + 1.
Highest column id used in this snapshot. New columns added in a
subsequent edit start at max_column_id + 1.
Always user — the user-defined datamodel. (fylr also has a
system datamodel; that one is not exposed through /schema.)
The submitted document is malformed or inconsistent with
the current objecttypes / masks: unknown column reference,
duplicate names, a max_table_id / max_column_id smaller
than the stored value, or a version / based_on_version
that is not the expected next version. A column type change
that cannot be migrated because the column already holds data
is rejected with code TypeChangeUnsupported. A deleted
objecttype that still holds objects is rejected with code
ObjecttypeNotEmpty (parameters.stats names them). May also
return code ReadOnlyMode when the instance is in read-only
mode.
No authenticated user. The request must carry a valid access token.
The authenticated user holds none of the system rights this
write needs: system.datamodel[level=development],
system.datamodel[level=commit], or system.root. The body
carries code SystemRightRequired; parameters.rights lists
the accepted rights.
{
"version": 1,
"based_on_version": 1,
"based_on_base_version": 1,
"max_table_id": 1,
"max_column_id": 1,
"type": "user",
"tables": [
{
"name": "text",
"table_id": 1,
"pool_link": true,
"owned_by": {
"other_table_id": 1,
"other_table_name_hint": "text"
},
"acl_table": true,
"has_tags": true,
"is_hierarchical": true,
"polyhierarchical": true,
"in_main_search": true,
"comment": "text",
"columns": [
{
"kind": "text",
"name": "text",
"type": "text",
"not_null": true,
"column_id": 1,
"reverse_edit": true,
"is_hierarchical": true,
"check": "text",
"check_regexp": "text",
"check_regexp_flags": "text",
"check_range_lower": null,
"check_range_upper": null,
"check_range_lower_open": null,
"check_range_upper_open": null,
"check_range_not_empty": true,
"length_min": 1,
"length_max": 1,
"other_table_id": 1,
"other_table_name_hint": "text",
"other_column_id": 1,
"other_column_name_hint": "text",
"bidirectional_reverse": true,
"custom_settings": {
"ANY_ADDITIONAL_PROPERTY": "text"
},
"name_localized": {
"de-DE": "Deutscher text",
"en-US": "English text"
}
}
],
"foreign_keys": [
{
"name": "text",
"on_delete": "text",
"on_update": "text",
"columns": [
{
"column_id": 1,
"column_name_hint": "text"
}
],
"referenced_table": {
"table_id": 1,
"name_hint": "text",
"columns": [
{
"auto_column_primary_key": true
}
]
}
}
],
"unique_keys": [
{
"group": "text",
"columns": [
{
"auto_column_parent": true,
"auto_column_uplink": true,
"column_id": 1,
"column_name_hint": "text"
}
]
}
],
"bidirectional": [
{
"columns": [
{
"auto_column_uplink": true,
"column_id": 1,
"column_name_hint": "text"
}
]
}
]
}
]
}POST /schema/commit — Commit the working datamodel (HEAD).
Promotes the working copy to a committed datamodel — sets its
committed_at timestamp and makes its version visible to readers
that don't hold system.datamodel. HEAD already has a version
number before the commit (it's the version a future commit would
produce); the commit just freezes it.
Requires system.datamodel[level=commit] (or system.root).
Commit options are query parameters:
reindex—skip(no reindex),reindex(reindex in the background), orreindex_block(reindex in the background and temporarily lock the frontend). If a change needs a reindex andreindexis absent, the call returns202asking which to use.confirm=yes— acknowledge the202confirm task (reindex and/or changed constraints) and proceed with the commit.
There is no destructive-change toggle: unsupported type changes
are rejected with code TypeChangeUnsupported, not opted into.
Differs from easydb 5: reindexing is controlled by reindex
(skip / reindex / reindex_block) plus a 202/confirm=yes
handshake. easydb 5 had no such handshake and instead took a
reindex_generate_events=1 flag to emit OBJECT_INDEX events
during reindex jobs; fylr has no equivalent parameter here.
Access token in the Authorization header:
Authorization: Bearer <token>.
Reindex behaviour for changes that need it. skip = none;
reindex = background; reindex_block = background plus a
temporary frontend lock. Omit to be prompted via a 202.
Set to yes to acknowledge the 202 confirm task (reindex
and/or changed constraints) and run the commit.
The commit succeeded. The response is a fixed
{ "status": "ok" } object — the new version number is not
in the body (read it via GET /schema/user/CURRENT or the
DATAMODEL_COMMIT event).
Always ok on success.
The commit needs confirmation before it runs. Returned when
the change requires a reindex and/or changes constraints and
the request did not already carry confirm=yes. Resend
POST /schema/commit?confirm=yes (optionally with
reindex=skip / reindex / reindex_block) to proceed.
The HEAD datamodel is inconsistent and cannot be committed: a
column type change that cannot be migrated because the column
already holds data is rejected with code
TypeChangeUnsupported, and a deleted objecttype that still
holds objects is rejected with code ObjecttypeNotEmpty
(parameters.stats names them). May also return code
ReadOnlyMode when the instance is in read-only mode.
No authenticated user. The request must carry a valid access token.
The authenticated user holds neither
system.datamodel[level=commit] nor system.root. The body
carries code SystemRightRequired; parameters.rights lists
the accepted rights.
{
"status": "ok"
}Last updated