Skip to content

Public API v2 write operations

The write endpoints of public API v2 create, replace, update and delete RMD content and data-model objects, and manage project access, version transfer and Git connections. Base path, authentication, pagination and the error format are the same as for the read endpoints (the Public API v2 page).

1 Write API — conventions

v2 write endpoints create, replace, update, and delete RMD and data-model entities. Every write is audited (section 7 of the API page) and returns the standard error shape (section 4 of the Public API v2 page); the complete code catalogue is in section 9.11. The conventions below apply to every endpoint of section 2 and are not repeated there.

HTTP verb semantics:

Verb Meaning
POST (collection) Create a new resource; returns the created resource with 201 Created
POST (…/bulk) Bulk create/update a set of RMD rows in one call. All rows applied — 201; some rows rejected — 207 Multi-Status with the succeeded and failed arrays; none applied — 422 DF_API.BULK_REJECTED
POST (membership, e.g. …/fact-tables/{id}/measures) Assign existing elements to a parent; returns 201 with the summary { timestamp, succeeded: [{ id }], failed: [{ index, id, error: { code, message, details } }] } (207 when some elements were rejected; an already-assigned element lands in failed with constraint_violation, a non-existent one with resource_not_found; none succeeded — 422 DF_API.BULK_REJECTED). Adding dimensions to a group (…/dimension-groups/{id}/dimensions) answers 200 with the group object; a non-existent dimension — 404 DF_API.RESOURCE_NOT_FOUND
PUT Full replacement — required fields must be present (400 DF_API.MISSING_REQUIRED_FIELD otherwise); any optional field not supplied is reset to its default/empty value
PATCH Partial update — only the supplied fields change
DELETE Remove the resource; returns 204 No Content

Effective access. RMD and data-model writes require the API-key owner to resolve to an effective project role of developer or higher for the target project (the same per-project access model as section 2.2 of the API page). If the owner has no access to the project the API returns 404 DF_API.PROJECT_NOT_FOUND (existence is not disclosed); if the owner has access below developer (analyst or viewer) it returns 403 DF_API.WRITE_ACCESS_DENIED. Creating a project requires the key owner to belong to a company.

Idempotency. A POST request may carry an Idempotency-Key header (UUID v4). The key is scoped per (API-key hash, HTTP method, path, key) and kept for 24 hours. A completed response is replayed verbatim for a repeated key; a still-in-flight duplicate returns 409 DF_API.IDEMPOTENCY_IN_PROGRESS; a malformed key returns 400 DF_API.INVALID_IDEMPOTENCY_KEY. PUT, PATCH and DELETE do not use the header — repeating them brings the resource to the same state.

Body validation. Bodies are strict: an unknown field answers 400 DF_API.VALIDATION_FAILED with details[].code = unknown_field; a value of the wrong type answers the same code with invalid_value. The read-only fields id, timestamp, created_at, updated_at are tolerated in write bodies (so a read result can be sent back) and ignored — except id, which must match the path identifier when present (400 DF_API.ID_MISMATCH).

Validation and referential integrity. Names must match the allowed pattern and be unique within their scope (409 DF_API.DUPLICATE_NAME). Measure formulas are parsed and their references resolved. The parser accepts the same syntax as the formula editor — including the NULL literal, IS [NOT] NULL, [NOT] IN (…) and [NOT] BETWEEN (a, b) with value lists in parentheses, and unary minus — so a formula read through the API can be written back unchanged. A syntax error returns 422 DF_API.INVALID_FORMULA_SYNTAX, an unknown reference 422 DF_API.FORMULA_REFERENCE_NOT_FOUND, and a cycle 422 DF_API.CIRCULAR_DEPENDENCY. Deleting an element referenced by another element's formula, a dimension that belongs to a dimension group, or a dimension group assigned to a fact table returns 409 DF_API.CONSTRAINT_VIOLATION; a measure that is merely assigned to a fact table is deleted together with the assignment (204). Every create and update response carries the created/updated object plus a timestamp field (the moment of the operation).

Select-type RMD fields. measure_type, dimension_type, fact_type, display_data_type, status, relevance, required, visibility and the other select columns accept either the English or the Russian label of an option (Base / Базовый, Number / Число); the comparison ignores case and surrounding whitespace, and the response echoes the labels in the language the request used. A value matching no option of a required select (measure_type, dimension_type, fact_type) answers 400 DF_API.INVALID_ENUM_VALUE; for optional selects a non-matching value is dropped. Flag columns (relevance, required, visibility) take the strings "true" / "false".

Version fields. A version has only name, is_global, and (on create) an optional clone_from_version. The version write API does not accept a description field.

Source objects in write requests. connected_source (dimensions, facts), primary_key (dimension groups, relationships) and foreign_key (relationships) accept the object of section 3.6 of the API page, in single-item and bulk requests alike. db and table are required; schema and column accept the empty string, null, or absence. connection is optional, and its presence selects which of the two contracts applies:

connection Behaviour
supplied The connection is resolved by name only, matched exactly (names are unique per version, and Prod is not prod). db, table, column, and — for relationships — the connection itself are validated; see the table below
omitted The pre-existing behaviour is kept unchanged: db is resolved leniently as a connection id, a database name, or a connection name, and nothing is validated

Validation applied when connection is supplied:

Field Rule Error
connection Must name a connection of the project version DF_API.INVALID_SOURCE_CONNECTION
db Required, as before; must be that connection's database name — a connection name is no longer accepted here DF_API.INVALID_SOURCE_DB
schema Optional, PostgreSQL only; when given and non-empty, must be that connection's own schema DF_API.INVALID_SOURCE_SCHEMA
table Must exist in the connection's cached schema DF_API.INVALID_SOURCE_TABLE
table (MS SQL) May be given either as schema + short name or as the single schema.table form the read endpoints return. A short name with no schema, where a table of that name exists under some schema, is reported as the schema being absent rather than the table being wrong DF_API.MISSING_REQUIRED_FIELD on …schema
column Optional; when given, must exist in that table DF_API.INVALID_SOURCE_COLUMN
foreign_key.connection / primary_key.connection Must be the connection the source fact table / target dimension group already uses DF_API.CONNECTION_MISMATCH
foreign_key vs primary_key Both keys of one relationship must name the same connection — a join cannot span two databases. Checked against the stored value of whichever key a PATCH does not send DF_API.CONNECTION_MISMATCH

Three deliberate exemptions:

  • schema is validated for PostgreSQL only. There the schema is a property of the connection, so a value that disagrees with it asks for something the API cannot store — selecting another schema means naming another connection. MS SQL Server keeps its schema inside table (dbo.orders), where the table check already covers it, and ClickHouse has no schemas, so for both the field is ignored. An empty schema asserts nothing and is treated as not supplied.
  • table / column are checked against the cached schema snapshot, the same list the product's source picker is built from. When the snapshot has never been refreshed or cannot be read, the check is skipped rather than failed — an unreadable snapshot is not evidence that the table is wrong.
  • CONNECTION_MISMATCH is only raised when the other side's connection is known. A fact table created through the API has no base table of its own, and a dimension group has no primary key until the first relationship sets one; in both cases there is nothing to compare against and the request is accepted.

Errors shared by every write endpoint. Beyond the common errors of section 4 of the API page: 403 DF_API.WRITE_ACCESS_DENIED (role below developer), 400 DF_API.VALIDATION_FAILED (body does not match the schema), 400 DF_API.INVALID_IDEMPOTENCY_KEY and 409 DF_API.IDEMPOTENCY_IN_PROGRESS (POST with Idempotency-Key). The per-endpoint "Errors" blocks of section 2 list only what is specific to the endpoint.

2 Write API — endpoints

Every endpoint of this section follows the conventions of section 1 (developer role, idempotency, strict bodies, timestamp in every create/update response, shared error codes). {v} abbreviates /df-api/v2/projects/{project_id}/versions/{version_id}.

Index:

Group Endpoints Sections
Projects and versions POST /projects; PATCH, DELETE /projects/{project_id}; POST /projects/{project_id}/versions; PATCH, DELETE …/versions/{version_id} 2.1–2.6
Measures POST {v}/measures, POST {v}/measures/bulk, PUT, PATCH, DELETE {v}/measures/{measure_id} 2.7–2.11
Dimensions POST {v}/dimensions, POST {v}/dimensions/bulk, PUT, PATCH, DELETE {v}/dimensions/{dimension_id} 2.12–2.16
Facts POST {v}/facts, POST {v}/facts/bulk, PUT, PATCH, DELETE {v}/facts/{fact_id} 2.17–2.21
Dimension groups POST {v}/dimension-groups; PUT, PATCH, DELETE …/{dimension_group_id}; POST …/dimensions; PATCH, DELETE …/dimensions/{dimension_id} 2.22–2.28
Fact tables POST {v}/fact-tables; PUT, PATCH, DELETE …/{fact_table_id}; membership POST / DELETE for measures, dimensions, facts, dimension-groups; per-fact-table verification-filters POST, PUT, PATCH, DELETE 2.29–2.44
Verification filters (version scope) POST {v}/verification-filters; PUT, PATCH, DELETE …/{filter_id} 2.45–2.48
Relationships POST {v}/relationships; PUT, PATCH, DELETE …/{relationship_id} 2.49–2.52
Project access POST /projects/{projectId}/access, DELETE …/access/{userId}, PUT /projects/{projectId}/owner 3
Version transfer POST {v}/export/git, export/file, import/validate, import/preview, import/git, import/file 4
Git connections POST /git-connections; PUT, DELETE /git-connections/{connection_id}; POST …/test 5

2.1 Create project

Request

POST /df-api/v2/projects

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection (section 1)
name body string yes 1–128 characters; letters, digits, _, ., -, space; must start with a letter or digit
description body string no Up to 255 characters
color body string no HEX colour, e.g. #FF8000
{ "name": "Sales Analytics", "description": "Production sales warehouse", "color": "#2479BC" }

Details

The key owner must belong to a company (otherwise 403 DF_API.WRITE_ACCESS_DENIED); the project is created in that company with the key owner as its owner and an initial version named Version 1. The name must be unique among the company's projects.

Response

201 Created

{
  "id": "12",
  "name": "Sales Analytics",
  "description": "Production sales warehouse",
  "color": "#2479BC",
  "created_at": "2026-05-05T08:30:00.000Z",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Project identifier
name, description string / string | null As stored
color string | null HEX colour
created_at string | null Creation timestamp
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 A project with this name already exists
DF_API.WRITE_ACCESS_DENIED 403 The key owner has no company, or the license project limit is reached (the internal LICENSE.CREATE_PROJECT_ACCESS_DENIED has no dedicated public code and degrades to the generic 403)

2.2 Update project

Request

PATCH /df-api/v2/projects/{project_id}

Parameter In Type Required Description
project_id path integer yes Project identifier
name body string no Same rules as on create
description body string no Up to 255 characters
color body string no HEX colour

Details

Partial update: only the supplied fields change. Requires developer or higher on the project.

Response

200 OK

{
  "id": "12",
  "name": "Sales Analytics",
  "description": "Production sales warehouse",
  "color": "#2479BC",
  "created_at": "2026-05-05T08:30:00.000Z",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Project identifier
name, description string / string | null As stored
color string | null HEX colour
created_at string | null Creation timestamp
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 Another project already has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.3 Delete project

Request

DELETE /df-api/v2/projects/{project_id}

Parameter In Type Required Description
project_id path integer yes Project identifier

Details

Deletes the project with all its versions and contents. The before snapshot of the project is written to the audit log (section 7 of the API page).

Response

204 No Content

Errors. Shared write errors only (section 1).

2.4 Create version

Request

POST /df-api/v2/projects/{project_id}/versions

Parameter In Type Required Description
project_id path integer yes Project identifier
Idempotency-Key header UUID v4 no Replay protection
name body string yes 1–64 characters; letters, digits, _, ., -, space
is_global body boolean no Make the new version the project's published (global) version
clone_from_version body string no Identifier of a version to copy the content from. When omitted, the content is copied from the current global version
{ "name": "Q1 2027", "is_global": false, "clone_from_version": "33" }

Details

A version has no description field. Creating a version counts against the license version limit.

Response

201 Created

{ "id": "34", "name": "Q1 2027", "is_global": false, "timestamp": "2026-05-05T08:30:00.120Z" }
Field Type Description
id string Version identifier
name string | null Version name
is_global boolean Whether this is the project's global version
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 A live version with this name exists in the project
DF_API.VERSION_NOT_FOUND 404 clone_from_version does not exist in the project
DF_API.LICENSE_LIMIT_REACHED 403 The license version limit is reached
DF_API.GLOBAL_VERSION_CONFLICT 422 is_global cannot be set

2.5 Update version

Request

PATCH /df-api/v2/projects/{project_id}/versions/{version_id}

Parameter In Type Required Description
project_id, version_id path integer yes Identifiers
name body string no Same rules as on create
is_global body boolean no true makes this version the global one (the previous global version loses the flag)

Response

200 OK

{ "id": "34", "name": "Q1 2027", "is_global": false, "timestamp": "2026-05-05T08:30:00.120Z" }
Field Type Description
id string Version identifier
name string | null Version name
is_global boolean Whether this is the project's global version
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 Another live version already has the new name
DF_API.GLOBAL_VERSION_CONFLICT 422 is_global cannot be set — it conflicts with another global version

2.6 Delete version

Request

DELETE /df-api/v2/projects/{project_id}/versions/{version_id}

Parameter In Type Required Description
project_id, version_id path integer yes Identifiers

Details

Deletes the version and all its contents (soft delete, subject to the retention cleanup). The current global version cannot be deleted.

Response

204 No Content

Errors

Code HTTP Condition
DF_API.GLOBAL_VERSION_CONFLICT 422 The version is the project's global version

2.7 Create measure

Request

POST {v}/measures

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
measure_name body string yes Measure name; unique within the version's measures
measure_type body string yes Label of the "Measure type" select: Base / Calculated (or the Russian label)
group, block body string no RMD grouping columns
measure_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns (free text)
display_data_type body string no Label of the "Display data type" select (Number, Text, Date, …)
restrictions body string no Restrictions column
formula body string no Formula of a calculated measure; references as [Measure name]
report_for_verification, comment, responsible_for_data, variation body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns
{ "measure_name": "Total revenue", "measure_type": "base", "group": "Revenue", "display_data_type": "Number" }

Details

The formula is parsed and its references resolved to existing measures of the version (section 1). The response mirrors the row of GET {v}/measures without row_number: id first, then every writable column (unset ones as null) and timestamp last; select labels are echoed in the language of the request.

Response

201 Created

{
  "id": "1000",
  "group": "Revenue",
  "block": null,
  "measure_name": "Total revenue",
  "measure_description": null,
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "display_data_type": "Number",
  "measure_type": "Base",
  "restrictions": null,
  "formula": null,
  "report_for_verification": null,
  "comment": null,
  "status": null,
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "variation": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new measure — the {measure_id} of the other endpoints
group, block string | null Grouping columns of the RMD
measure_name string Measure name
measure_description string | null Description
original_source_type, original_source, original_object string | null Provenance columns; free text
display_data_type string | null Localized data type label (Number, Text, Date, …)
measure_type string Localized label: Base or Calculated
restrictions string | null Restrictions column
formula string | null Formula of a calculated measure with references rendered as [Name]
report_for_verification, comment, responsible_for_data, variation string | null Free-text columns
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 A measure with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 measure_type matches no option
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.8 Bulk create/update measures

Request

POST {v}/measures/bulk

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
measures body array yes At least one item
measures[].id body string no Present — the existing measure is updated (partial, as PATCH); absent — a measure is created
measures[].measure_name body string no Measure name; unique within the version's measures
measures[].measure_type body string no Label of the "Measure type" select: Base / Calculated (or the Russian label)
measures[].group, measures[].block body string no RMD grouping columns
measures[].measure_description body string no Up to 255 characters
measures[].original_source_type, measures[].original_source, measures[].original_object body string no Provenance columns (free text)
measures[].display_data_type body string no Label of the "Display data type" select (Number, Text, Date, …)
measures[].restrictions body string no Restrictions column
measures[].formula body string no Formula of a calculated measure; references as [Measure name]
measures[].report_for_verification, measures[].comment, measures[].responsible_for_data, measures[].variation body string no Free-text columns
measures[].status body string no Label of the "Status" select
measures[].relevance, measures[].required, measures[].visibility body "true" | "false" no Flag columns
{
  "measures": [
    { "measure_name": "Total revenue", "measure_type": "base", "group": "Revenue" },
    { "id": "1000", "measure_description": "Gross revenue across all channels" }
  ]
}

Details

Items are processed in order, each in its own transaction: a failing item leaves nothing behind and does not stop the others. failed[].index is the item's position in the request. One consolidated audit entry is written for the request.

Response

201 Created when every item was applied; 207 Multi-Status when some items failed:

{
  "timestamp": "2026-05-05T08:30:00.120Z",
  "succeeded": [
    { "id": "1000", "measure_name": "Total revenue", "measure_type": "Base", "…": "…" }
  ],
  "failed": [
    {
      "index": 1,
      "error": { "code": "duplicate_name", "message": "Measure name already exists", "details": [{ "field": "measure_name", "code": "invalid_value" }] }
    }
  ]
}
Field Type Description
succeeded[] array Measure objects (the object of a single create response, without timestamp)
failed[].index integer Position of the rejected item in measures
failed[].error object code, message, details of section 4 of the Public API v2 page

Errors

Code HTTP Condition
DF_API.VALIDATION_FAILED 400 measures is empty or an item is malformed
DF_API.BULK_REJECTED 422 No item was applied; details[] addresses every item (measures.<index>)
Per-item codes in failed[] duplicate_name, missing_required_field, invalid_enum_value, resource_not_found (unknown id), invalid_formula_syntax, formula_reference_not_found, circular_dependency, invalid_parameter_type

2.9 Replace measure

Request

PUT {v}/measures/{measure_id}

Parameter In Type Required Description
measure_id path integer yes Measure identifier
measure_name body string yes Measure name; unique within the version's measures
measure_type body string yes Label of the "Measure type" select: Base / Calculated (or the Russian label)
group, block body string no RMD grouping columns
measure_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns (free text)
display_data_type body string no Label of the "Display data type" select (Number, Text, Date, …)
restrictions body string no Restrictions column
formula body string no Formula of a calculated measure; references as [Measure name]
report_for_verification, comment, responsible_for_data, variation body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns

Details

measure_name and measure_type are required; every omitted optional column is reset to empty.

Response

200 OK

{
  "id": "1000",
  "group": "Revenue",
  "block": null,
  "measure_name": "Total revenue",
  "measure_description": null,
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "display_data_type": "Number",
  "measure_type": "Base",
  "restrictions": null,
  "formula": null,
  "report_for_verification": null,
  "comment": null,
  "status": null,
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "variation": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new measure — the {measure_id} of the other endpoints
group, block string | null Grouping columns of the RMD
measure_name string Measure name
measure_description string | null Description
original_source_type, original_source, original_object string | null Provenance columns; free text
display_data_type string | null Localized data type label (Number, Text, Date, …)
measure_type string Localized label: Base or Calculated
restrictions string | null Restrictions column
formula string | null Formula of a calculated measure with references rendered as [Name]
report_for_verification, comment, responsible_for_data, variation string | null Free-text columns
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The measure does not exist in the version
DF_API.MISSING_REQUIRED_FIELD 400 measure_name or measure_type missing
DF_API.ID_MISMATCH 400 Body id differs from the path
DF_API.DUPLICATE_NAME 409 A measure with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 measure_type matches no option
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.10 Update measure

Request

PATCH {v}/measures/{measure_id}

Parameter In Type Required Description
measure_id path integer yes Measure identifier
measure_name body string no Measure name; unique within the version's measures
measure_type body string no Label of the "Measure type" select: Base / Calculated (or the Russian label)
group, block body string no RMD grouping columns
measure_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns (free text)
display_data_type body string no Label of the "Display data type" select (Number, Text, Date, …)
restrictions body string no Restrictions column
formula body string no Formula of a calculated measure; references as [Measure name]
report_for_verification, comment, responsible_for_data, variation body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns

Details

Only the supplied fields change.

Response

200 OK

{
  "id": "1000",
  "group": "Revenue",
  "block": null,
  "measure_name": "Total revenue",
  "measure_description": null,
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "display_data_type": "Number",
  "measure_type": "Base",
  "restrictions": null,
  "formula": null,
  "report_for_verification": null,
  "comment": null,
  "status": null,
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "variation": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new measure — the {measure_id} of the other endpoints
group, block string | null Grouping columns of the RMD
measure_name string Measure name
measure_description string | null Description
original_source_type, original_source, original_object string | null Provenance columns; free text
display_data_type string | null Localized data type label (Number, Text, Date, …)
measure_type string Localized label: Base or Calculated
restrictions string | null Restrictions column
formula string | null Formula of a calculated measure with references rendered as [Name]
report_for_verification, comment, responsible_for_data, variation string | null Free-text columns
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The measure does not exist in the version
DF_API.ID_MISMATCH 400 Body id differs from the path
DF_API.DUPLICATE_NAME 409 A measure with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 measure_type matches no option
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.11 Delete measure

Request

DELETE {v}/measures/{measure_id}

Parameter In Type Required Description
measure_id path integer yes Measure identifier

Details

A measure referenced by another element's formula cannot be deleted. A measure merely assigned to a fact table is deleted together with the assignment.

Response

204 No Content

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The measure does not exist in the version
DF_API.CONSTRAINT_VIOLATION 409 The measure is referenced by a formula

2.12 Create dimension

Request

POST {v}/dimensions

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
dimension_name body string yes Dimension name; unique within the version's dimensions
dimension_type body string yes Label of the "Dimension type" select: Primary / Derived
group, block body string no RMD grouping columns
dimension_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns
dimension_group body string no Name of an existing dimension group; the dimension becomes its member
display_data_type body string no Label of the "Display data type" select
source_data_type body string no Accepted and ignored — derived from connected_source
formula body string no Formula of a derived dimension
connected_source body object no Source object (section 3.6 of the API page): connection (optional), db (required), schema, table (required), column
comment, value_options, responsible_for_data body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns
{
  "dimension_name": "Region",
  "dimension_type": "primary",
  "dimension_group": "Geography",
  "display_data_type": "Text",
  "connected_source": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_name" }
}

Details

connected_source is validated according to section 1 when connection is supplied. Naming a dimension_group adds the dimension to that group.

Response

201 Created

{
  "id": "2000",
  "group": "Customer",
  "block": "Profile",
  "dimension_name": "Customer name",
  "dimension_description": "Full customer name",
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "dimension_group": "Customers",
  "display_data_type": "Text",
  "source_data_type": "VARCHAR(255)",
  "dimension_type": "Primary",
  "formula": null,
  "connected_source": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_customer", "column": "customer_name" },
  "comment": null,
  "value_options": null,
  "status": "Active",
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new dimension — the {dimension_id} of the other endpoints
group, block string | null Grouping columns of the RMD
dimension_name, dimension_description string / string | null Name and description
original_source_type, original_source, original_object string | null Provenance columns; free text
dimension_group string | null Name of the dimension group the dimension belongs to
display_data_type string | null Localized data type label
source_data_type string | null Physical column type resolved from the connection's cached schema
dimension_type string Localized label: Primary or Derived
formula string | null Formula of a derived dimension
connected_source object | null Source object { db, schema, table, column } (section 3.6 of the API page)
comment, responsible_for_data string | null Free-text columns
value_options string | null Allowed values column
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 A dimension with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 dimension_type matches no option
DF_API.INVALID_SOURCE_*, DF_API.MISSING_REQUIRED_FIELD 400 connected_source validation (section 1)
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.13 Bulk create/update dimensions

Request

POST {v}/dimensions/bulk

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
dimensions body array yes At least one item
dimensions[].dimension_name body string no Dimension name; unique within the version's dimensions
dimensions[].dimension_type body string no Label of the "Dimension type" select: Primary / Derived
dimensions[].group, dimensions[].block body string no RMD grouping columns
dimensions[].dimension_description body string no Up to 255 characters
dimensions[].original_source_type, dimensions[].original_source, dimensions[].original_object body string no Provenance columns
dimensions[].dimension_group body string no Name of an existing dimension group; the dimension becomes its member
dimensions[].display_data_type body string no Label of the "Display data type" select
dimensions[].source_data_type body string no Accepted and ignored — derived from connected_source
dimensions[].formula body string no Formula of a derived dimension
dimensions[].connected_source body object no Source object (section 3.6 of the API page): connection (optional), db (required), schema, table (required), column
dimensions[].comment, dimensions[].value_options, dimensions[].responsible_for_data body string no Free-text columns
dimensions[].status body string no Label of the "Status" select
dimensions[].relevance, dimensions[].required, dimensions[].visibility body "true" | "false" no Flag columns
{
  "dimensions": [
    { "dimension_name": "Region", "dimension_type": "primary", "dimension_group": "Geography" },
    { "id": "2000", "dimension_description": "Sales region" }
  ]
}

Details

Items are processed in order, each in its own transaction: a failing item leaves nothing behind and does not stop the others. failed[].index is the item's position in the request. One consolidated audit entry is written for the request.

Response

201 Created when every item was applied; 207 Multi-Status when some items failed:

{
  "timestamp": "2026-05-05T08:30:00.120Z",
  "succeeded": [
    { "id": "2000", "dimension_name": "Region", "dimension_type": "Primary", "…": "…" }
  ],
  "failed": [
    {
      "index": 1,
      "error": { "code": "duplicate_name", "message": "Dimension name already exists", "details": [{ "field": "dimension_name", "code": "invalid_value" }] }
    }
  ]
}
Field Type Description
succeeded[] array Dimension objects (the object of a single create response, without timestamp)
failed[].index integer Position of the rejected item in dimensions
failed[].error object code, message, details of section 4 of the Public API v2 page

Errors

Code HTTP Condition
DF_API.VALIDATION_FAILED 400 dimensions is empty or an item is malformed
DF_API.BULK_REJECTED 422 No item was applied; details[] addresses every item (dimensions.<index>)
Per-item codes in failed[] duplicate_name, missing_required_field, invalid_enum_value, resource_not_found (unknown id), invalid_formula_syntax, formula_reference_not_found, circular_dependency, invalid_parameter_type
DF_API.INVALID_SOURCE_*, DF_API.MISSING_REQUIRED_FIELD in failed[] connected_source validation of an item (section 1)

2.14 Replace dimension

Request

PUT {v}/dimensions/{dimension_id}

Parameter In Type Required Description
dimension_id path integer yes Dimension identifier
dimension_name body string yes Dimension name; unique within the version's dimensions
dimension_type body string yes Label of the "Dimension type" select: Primary / Derived
group, block body string no RMD grouping columns
dimension_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns
dimension_group body string no Name of an existing dimension group; the dimension becomes its member
display_data_type body string no Label of the "Display data type" select
source_data_type body string no Accepted and ignored — derived from connected_source
formula body string no Formula of a derived dimension
connected_source body object no Source object (section 3.6 of the API page): connection (optional), db (required), schema, table (required), column
comment, value_options, responsible_for_data body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns

Details

dimension_name and dimension_type are required; every omitted optional column is reset to empty. An omitted dimension_group removes the dimension from its group.

Response

200 OK

{
  "id": "2000",
  "group": "Customer",
  "block": "Profile",
  "dimension_name": "Customer name",
  "dimension_description": "Full customer name",
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "dimension_group": "Customers",
  "display_data_type": "Text",
  "source_data_type": "VARCHAR(255)",
  "dimension_type": "Primary",
  "formula": null,
  "connected_source": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_customer", "column": "customer_name" },
  "comment": null,
  "value_options": null,
  "status": "Active",
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new dimension — the {dimension_id} of the other endpoints
group, block string | null Grouping columns of the RMD
dimension_name, dimension_description string / string | null Name and description
original_source_type, original_source, original_object string | null Provenance columns; free text
dimension_group string | null Name of the dimension group the dimension belongs to
display_data_type string | null Localized data type label
source_data_type string | null Physical column type resolved from the connection's cached schema
dimension_type string Localized label: Primary or Derived
formula string | null Formula of a derived dimension
connected_source object | null Source object { db, schema, table, column } (section 3.6 of the API page)
comment, responsible_for_data string | null Free-text columns
value_options string | null Allowed values column
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The dimension does not exist in the version
DF_API.MISSING_REQUIRED_FIELD 400 dimension_name or dimension_type missing
DF_API.ID_MISMATCH 400 Body id differs from the path
DF_API.DUPLICATE_NAME 409 A dimension with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 dimension_type matches no option
DF_API.INVALID_SOURCE_*, DF_API.MISSING_REQUIRED_FIELD 400 connected_source validation (section 1)
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.15 Update dimension

Request

PATCH {v}/dimensions/{dimension_id}

Parameter In Type Required Description
dimension_id path integer yes Dimension identifier
dimension_name body string no Dimension name; unique within the version's dimensions
dimension_type body string no Label of the "Dimension type" select: Primary / Derived
group, block body string no RMD grouping columns
dimension_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns
dimension_group body string no Name of an existing dimension group; the dimension becomes its member
display_data_type body string no Label of the "Display data type" select
source_data_type body string no Accepted and ignored — derived from connected_source
formula body string no Formula of a derived dimension
connected_source body object no Source object (section 3.6 of the API page): connection (optional), db (required), schema, table (required), column
comment, value_options, responsible_for_data body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns

Details

Only the supplied fields change.

Response

200 OK

{
  "id": "2000",
  "group": "Customer",
  "block": "Profile",
  "dimension_name": "Customer name",
  "dimension_description": "Full customer name",
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "dimension_group": "Customers",
  "display_data_type": "Text",
  "source_data_type": "VARCHAR(255)",
  "dimension_type": "Primary",
  "formula": null,
  "connected_source": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_customer", "column": "customer_name" },
  "comment": null,
  "value_options": null,
  "status": "Active",
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new dimension — the {dimension_id} of the other endpoints
group, block string | null Grouping columns of the RMD
dimension_name, dimension_description string / string | null Name and description
original_source_type, original_source, original_object string | null Provenance columns; free text
dimension_group string | null Name of the dimension group the dimension belongs to
display_data_type string | null Localized data type label
source_data_type string | null Physical column type resolved from the connection's cached schema
dimension_type string Localized label: Primary or Derived
formula string | null Formula of a derived dimension
connected_source object | null Source object { db, schema, table, column } (section 3.6 of the API page)
comment, responsible_for_data string | null Free-text columns
value_options string | null Allowed values column
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The dimension does not exist in the version
DF_API.ID_MISMATCH 400 Body id differs from the path
DF_API.DUPLICATE_NAME 409 A dimension with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 dimension_type matches no option
DF_API.INVALID_SOURCE_*, DF_API.MISSING_REQUIRED_FIELD 400 connected_source validation (section 1)
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.16 Delete dimension

Request

DELETE {v}/dimensions/{dimension_id}

Parameter In Type Required Description
dimension_id path integer yes Dimension identifier

Details

A dimension that belongs to a dimension group, or is referenced by a formula, cannot be deleted — remove it from the group first (DELETE {v}/dimension-groups/{dimension_group_id}/dimensions/{dimension_id}).

Response

204 No Content

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The dimension does not exist in the version
DF_API.CONSTRAINT_VIOLATION 409 The dimension is a member of a dimension group or is referenced by a formula

2.17 Create fact

Request

POST {v}/facts

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
fact_name body string yes Fact name; unique within the version's facts
fact_type body string yes Label of the "Fact type" select: Primary / Derived
group, block body string no RMD grouping columns
fact_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns
source_data_type body string no Accepted and ignored — derived from connected_source
formula body string no Formula of a derived fact
connected_source body object no Source object (section 3.6 of the API page)
report_for_verification, comment, responsible_for_data body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns
{
  "fact_name": "Order line",
  "fact_type": "primary",
  "connected_source": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_order_line", "column": "amount" }
}

Response

201 Created

{
  "id": "3000",
  "group": "Sales",
  "block": "Orders",
  "fact_name": "Order line",
  "fact_description": "An individual line item on a sales order",
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "source_data_type": "DECIMAL(18,2)",
  "fact_type": "Primary",
  "formula": null,
  "connected_source": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_order_line", "column": "amount" },
  "report_for_verification": null,
  "comment": null,
  "status": null,
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new fact — the {fact_id} of the other endpoints
group, block string | null Grouping columns of the RMD
fact_name, fact_description string / string | null Name and description
original_source_type, original_source, original_object string | null Provenance columns; free text
source_data_type string | null Physical column type resolved from the connection's cached schema
fact_type string Localized label: Primary or Derived
formula string | null Formula of a derived fact
connected_source object | null Source object { db, schema, table, column } (section 3.6 of the API page)
report_for_verification, comment, responsible_for_data string | null Free-text columns
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 A fact with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 fact_type matches no option
DF_API.INVALID_SOURCE_*, DF_API.MISSING_REQUIRED_FIELD 400 connected_source validation (section 1)
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.18 Bulk create/update facts

Request

POST {v}/facts/bulk

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
facts body array yes At least one item
facts[].fact_name body string no Fact name; unique within the version's facts
facts[].fact_type body string no Label of the "Fact type" select: Primary / Derived
facts[].group, facts[].block body string no RMD grouping columns
facts[].fact_description body string no Up to 255 characters
facts[].original_source_type, facts[].original_source, facts[].original_object body string no Provenance columns
facts[].source_data_type body string no Accepted and ignored — derived from connected_source
facts[].formula body string no Formula of a derived fact
facts[].connected_source body object no Source object (section 3.6 of the API page)
facts[].report_for_verification, facts[].comment, facts[].responsible_for_data body string no Free-text columns
facts[].status body string no Label of the "Status" select
facts[].relevance, facts[].required, facts[].visibility body "true" | "false" no Flag columns
{
  "facts": [
    { "fact_name": "Order line", "fact_type": "primary" },
    { "id": "3000", "fact_description": "An individual line item on a sales order" }
  ]
}

Details

Items are processed in order, each in its own transaction: a failing item leaves nothing behind and does not stop the others. failed[].index is the item's position in the request. One consolidated audit entry is written for the request.

Response

201 Created when every item was applied; 207 Multi-Status when some items failed:

{
  "timestamp": "2026-05-05T08:30:00.120Z",
  "succeeded": [
    { "id": "3000", "fact_name": "Order line", "fact_type": "Primary", "…": "…" }
  ],
  "failed": [
    {
      "index": 1,
      "error": { "code": "duplicate_name", "message": "Fact name already exists", "details": [{ "field": "fact_name", "code": "invalid_value" }] }
    }
  ]
}
Field Type Description
succeeded[] array Fact objects (the object of a single create response, without timestamp)
failed[].index integer Position of the rejected item in facts
failed[].error object code, message, details of section 4 of the Public API v2 page

Errors

Code HTTP Condition
DF_API.VALIDATION_FAILED 400 facts is empty or an item is malformed
DF_API.BULK_REJECTED 422 No item was applied; details[] addresses every item (facts.<index>)
Per-item codes in failed[] duplicate_name, missing_required_field, invalid_enum_value, resource_not_found (unknown id), invalid_formula_syntax, formula_reference_not_found, circular_dependency, invalid_parameter_type
DF_API.INVALID_SOURCE_*, DF_API.MISSING_REQUIRED_FIELD in failed[] connected_source validation of an item (section 1)

2.19 Replace fact

Request

PUT {v}/facts/{fact_id}

Parameter In Type Required Description
fact_id path integer yes Fact identifier
fact_name body string yes Fact name; unique within the version's facts
fact_type body string yes Label of the "Fact type" select: Primary / Derived
group, block body string no RMD grouping columns
fact_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns
source_data_type body string no Accepted and ignored — derived from connected_source
formula body string no Formula of a derived fact
connected_source body object no Source object (section 3.6 of the API page)
report_for_verification, comment, responsible_for_data body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns

Details

fact_name and fact_type are required; every omitted optional column is reset to empty.

Response

200 OK

{
  "id": "3000",
  "group": "Sales",
  "block": "Orders",
  "fact_name": "Order line",
  "fact_description": "An individual line item on a sales order",
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "source_data_type": "DECIMAL(18,2)",
  "fact_type": "Primary",
  "formula": null,
  "connected_source": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_order_line", "column": "amount" },
  "report_for_verification": null,
  "comment": null,
  "status": null,
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new fact — the {fact_id} of the other endpoints
group, block string | null Grouping columns of the RMD
fact_name, fact_description string / string | null Name and description
original_source_type, original_source, original_object string | null Provenance columns; free text
source_data_type string | null Physical column type resolved from the connection's cached schema
fact_type string Localized label: Primary or Derived
formula string | null Formula of a derived fact
connected_source object | null Source object { db, schema, table, column } (section 3.6 of the API page)
report_for_verification, comment, responsible_for_data string | null Free-text columns
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The fact does not exist in the version
DF_API.MISSING_REQUIRED_FIELD 400 fact_name or fact_type missing
DF_API.ID_MISMATCH 400 Body id differs from the path
DF_API.DUPLICATE_NAME 409 A fact with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 fact_type matches no option
DF_API.INVALID_SOURCE_*, DF_API.MISSING_REQUIRED_FIELD 400 connected_source validation (section 1)
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.20 Update fact

Request

PATCH {v}/facts/{fact_id}

Parameter In Type Required Description
fact_id path integer yes Fact identifier
fact_name body string no Fact name; unique within the version's facts
fact_type body string no Label of the "Fact type" select: Primary / Derived
group, block body string no RMD grouping columns
fact_description body string no Up to 255 characters
original_source_type, original_source, original_object body string no Provenance columns
source_data_type body string no Accepted and ignored — derived from connected_source
formula body string no Formula of a derived fact
connected_source body object no Source object (section 3.6 of the API page)
report_for_verification, comment, responsible_for_data body string no Free-text columns
status body string no Label of the "Status" select
relevance, required, visibility body "true" | "false" no Flag columns

Details

Only the supplied fields change.

Response

200 OK

{
  "id": "3000",
  "group": "Sales",
  "block": "Orders",
  "fact_name": "Order line",
  "fact_description": "An individual line item on a sales order",
  "original_source_type": null,
  "original_source": null,
  "original_object": null,
  "source_data_type": "DECIMAL(18,2)",
  "fact_type": "Primary",
  "formula": null,
  "connected_source": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_order_line", "column": "amount" },
  "report_for_verification": null,
  "comment": null,
  "status": null,
  "relevance": null,
  "required": null,
  "visibility": null,
  "responsible_for_data": null,
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Identifier of the new fact — the {fact_id} of the other endpoints
group, block string | null Grouping columns of the RMD
fact_name, fact_description string / string | null Name and description
original_source_type, original_source, original_object string | null Provenance columns; free text
source_data_type string | null Physical column type resolved from the connection's cached schema
fact_type string Localized label: Primary or Derived
formula string | null Formula of a derived fact
connected_source object | null Source object { db, schema, table, column } (section 3.6 of the API page)
report_for_verification, comment, responsible_for_data string | null Free-text columns
status string | null Localized label of the "Status" select
relevance, required, visibility boolean | null Flag columns; booleans in write responses, null when unset
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The fact does not exist in the version
DF_API.ID_MISMATCH 400 Body id differs from the path
DF_API.DUPLICATE_NAME 409 A fact with this name exists in the version
DF_API.INVALID_ENUM_VALUE 400 fact_type matches no option
DF_API.INVALID_SOURCE_*, DF_API.MISSING_REQUIRED_FIELD 400 connected_source validation (section 1)
DF_API.INVALID_FORMULA_SYNTAX 422 The formula failed to parse
DF_API.FORMULA_REFERENCE_NOT_FOUND 422 The formula references an unknown element
DF_API.CIRCULAR_DEPENDENCY 422 The formula introduces a cycle
DF_API.INVALID_PARAMETER_TYPE 422 A dimension passed to a period function is not bound to a date/time column

2.21 Delete fact

Request

DELETE {v}/facts/{fact_id}

Parameter In Type Required Description
fact_id path integer yes Fact identifier

Response

204 No Content

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The fact does not exist in the version
DF_API.CONSTRAINT_VIOLATION 409 The fact is referenced by a formula

2.22 Create dimension group

Request

POST {v}/dimension-groups

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
name body string yes 1–64 characters; letters, digits, space, ., -, _; must start with a letter or digit; unique among the version's groups
description body string no Up to 255 characters
primary_key body object yes Source object of the group's key (section 3.6 of the API page): connection (optional), db, table required, schema, column optional
dimensions body array no Initial members: { "id": "<dimension id>", "level": <integer ≥ 1> }; levels must be unique
{
  "name": "Geography",
  "description": "Geographic regions and countries",
  "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" },
  "dimensions": [ { "id": "722", "level": 1 }, { "id": "723", "level": 2 } ]
}

Details

level is the hierarchy level of the member inside the group and is stored verbatim (not renumbered).

Response

201 Created

{
  "id": "9",
  "name": "Geography",
  "description": "Geographic regions and countries",
  "primary_key": {
    "connection": "Production PostgreSQL",
    "db": "analytics_db",
    "schema": "public",
    "table": "dim_geography",
    "column": "region_id"
  },
  "dimensions": [
    { "id": "722", "name": "Region", "description": "Sales region", "level": 1, "display_data_type": "Text", "physical_column": "region_name" }
  ],
  "related_fact_tables": [
    { "fact_table_id": "11", "fact_table_name": "fact_sales", "foreign_key_column": "region_id" }
  ],
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
dimensions[] array Members with id, name, description, level, display_data_type, physical_column
related_fact_tables[] array fact_table_id, fact_table_name, foreign_key_column
id, name, description string / string / string | null Identity
primary_key object | null Source object with connection (section 3.6 of the API page); null when the group has no key yet
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 A group with this name exists in the version
DF_API.DUPLICATE_LEVEL 409 Two members share a level
DF_API.RESOURCE_NOT_FOUND 404 A member id is not a dimension of the version
DF_API.INVALID_SOURCE_* 400 primary_key validation (section 1)

2.23 Replace dimension group

Request

PUT {v}/dimension-groups/{dimension_group_id}

Parameter In Type Required Description
dimension_group_id path integer yes Group identifier
name body string yes As on create
primary_key body object yes As on create
description body string no Omitted — reset to empty

Details

Replaces the group's metadata only; membership is managed through …/dimension-groups/{dimension_group_id}/dimensions and is not touched.

Response

200 OK

{
  "id": "9",
  "name": "Geography",
  "description": "Geographic regions and countries",
  "primary_key": {
    "connection": "Production PostgreSQL",
    "db": "analytics_db",
    "schema": "public",
    "table": "dim_geography",
    "column": "region_id"
  },
  "dimensions": [
    { "id": "722", "name": "Region", "description": "Sales region", "level": 1, "display_data_type": "Text", "physical_column": "region_name" }
  ],
  "related_fact_tables": [
    { "fact_table_id": "11", "fact_table_name": "fact_sales", "foreign_key_column": "region_id" }
  ],
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
dimensions[] array Members with id, name, description, level, display_data_type, physical_column
related_fact_tables[] array fact_table_id, fact_table_name, foreign_key_column
id, name, description string / string / string | null Identity
primary_key object | null Source object with connection (section 3.6 of the API page); null when the group has no key yet
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DIMENSION_GROUP_NOT_FOUND 404 The group does not exist in the version
DF_API.MISSING_REQUIRED_FIELD 400 name or primary_key missing
DF_API.DUPLICATE_NAME 409 Another group has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.24 Update dimension group

Request

PATCH {v}/dimension-groups/{dimension_group_id}

Parameter In Type Required Description
dimension_group_id path integer yes Dimension group identifier
name body string no As on create
primary_key body object no As on create
description body string no Omitted — reset to empty

Details

Only the supplied fields change; membership is not touched.

Response

200 OK

{
  "id": "9",
  "name": "Geography",
  "description": "Geographic regions and countries",
  "primary_key": {
    "connection": "Production PostgreSQL",
    "db": "analytics_db",
    "schema": "public",
    "table": "dim_geography",
    "column": "region_id"
  },
  "dimensions": [
    { "id": "722", "name": "Region", "description": "Sales region", "level": 1, "display_data_type": "Text", "physical_column": "region_name" }
  ],
  "related_fact_tables": [
    { "fact_table_id": "11", "fact_table_name": "fact_sales", "foreign_key_column": "region_id" }
  ],
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
dimensions[] array Members with id, name, description, level, display_data_type, physical_column
related_fact_tables[] array fact_table_id, fact_table_name, foreign_key_column
id, name, description string / string / string | null Identity
primary_key object | null Source object with connection (section 3.6 of the API page); null when the group has no key yet
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DIMENSION_GROUP_NOT_FOUND 404 The group does not exist in the version
DF_API.DUPLICATE_NAME 409 Another group has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.25 Delete dimension group

Request

DELETE {v}/dimension-groups/{dimension_group_id}

Parameter In Type Required Description
dimension_group_id path integer yes Dimension group identifier

Details

A group assigned to any fact table — whether merely assigned or joined through a relationship — cannot be deleted; unassign it first (DELETE {v}/fact-tables/{fact_table_id}/dimension-groups/{dimension_group_id}).

Response

204 No Content

Errors

Code HTTP Condition
DF_API.DIMENSION_GROUP_NOT_FOUND 404 The group does not exist in the version
DF_API.CONSTRAINT_VIOLATION 409 The group is assigned to a fact table

2.26 Add dimensions to a group

Request

POST {v}/dimension-groups/{dimension_group_id}/dimensions

Parameter In Type Required Description
dimension_group_id path integer yes Group identifier
Idempotency-Key header UUID v4 no Replay protection
dimensions body array yes At least one { "id": "<dimension id>", "level": <integer ≥ 1> }
{ "dimensions": [ { "id": "724", "level": 3 } ] }

Details

Members already in the group keep their place; a listed member that is already present gets the new level. A level the request assigns — to a new member or to one it moves — must not be held by another member and must not repeat within the request; members that already share a level (a group created in the UI keeps all its dimensions on level 1) are not checked against each other and do not block the request. Unlike the fact-table membership endpoints, this call is all-or-nothing and answers 200 with the group object (no succeeded / failed summary).

Response

200 OK

{
  "id": "9",
  "name": "Geography",
  "description": "Geographic regions and countries",
  "primary_key": {
    "connection": "Production PostgreSQL",
    "db": "analytics_db",
    "schema": "public",
    "table": "dim_geography",
    "column": "region_id"
  },
  "dimensions": [
    { "id": "722", "name": "Region", "description": "Sales region", "level": 1, "display_data_type": "Text", "physical_column": "region_name" }
  ],
  "related_fact_tables": [
    { "fact_table_id": "11", "fact_table_name": "fact_sales", "foreign_key_column": "region_id" }
  ],
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
dimensions[] array Members with id, name, description, level, display_data_type, physical_column
related_fact_tables[] array fact_table_id, fact_table_name, foreign_key_column
id, name, description string / string / string | null Identity
primary_key object | null Source object with connection (section 3.6 of the API page); null when the group has no key yet
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DIMENSION_GROUP_NOT_FOUND 404 The group does not exist in the version
DF_API.RESOURCE_NOT_FOUND 404 A dimension id does not exist in the version
DF_API.DUPLICATE_LEVEL 409 A requested level is already held by another member or repeats in the request; the message names the level

2.27 Change a member's hierarchy level

Request

PATCH {v}/dimension-groups/{dimension_group_id}/dimensions/{dimension_id}

Parameter In Type Required Description
dimension_group_id, dimension_id path integer yes Identifiers
level body integer ≥ 1 yes New hierarchy level

Response

200 OK

{
  "id": "9",
  "name": "Geography",
  "description": "Geographic regions and countries",
  "primary_key": {
    "connection": "Production PostgreSQL",
    "db": "analytics_db",
    "schema": "public",
    "table": "dim_geography",
    "column": "region_id"
  },
  "dimensions": [
    { "id": "722", "name": "Region", "description": "Sales region", "level": 1, "display_data_type": "Text", "physical_column": "region_name" }
  ],
  "related_fact_tables": [
    { "fact_table_id": "11", "fact_table_name": "fact_sales", "foreign_key_column": "region_id" }
  ],
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
dimensions[] array Members with id, name, description, level, display_data_type, physical_column
related_fact_tables[] array fact_table_id, fact_table_name, foreign_key_column
id, name, description string / string / string | null Identity
primary_key object | null Source object with connection (section 3.6 of the API page); null when the group has no key yet
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The dimension is not a member of the group
DF_API.DUPLICATE_LEVEL 409 Another member already has that level

2.28 Remove a dimension from a group

Request

DELETE {v}/dimension-groups/{dimension_group_id}/dimensions/{dimension_id}

Parameter In Type Required Description
dimension_group_id path integer yes Dimension group identifier
dimension_id path integer yes Dimension identifier

Details

The remaining members keep their levels; they are not renumbered.

Response

204 No Content

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The dimension is not a member of the group (a repeated delete is not a silent no-op)

2.29 Create fact table

Request

POST {v}/fact-tables

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
name body string yes 1–64 characters; letters, digits, _, ., -, space; must start with a letter or digit; unique among the version's fact tables
description body string no Up to 255 characters
owner body string no Accepted and ignored — the key owner becomes the owner
{ "name": "fact_sales", "description": "Primary sales facts" }

Details

A fact table created through the API has no base physical table of its own; elements are attached through the membership endpoints (POST {v}/fact-tables/{fact_table_id}/measures, …/dimensions, …/facts, …/dimension-groups).

Response

201 Created

{
  "id": "11",
  "name": "fact_sales",
  "description": "Primary sales facts",
  "owner": "Pavel Shalavin",
  "created_at": "2026-05-05T08:30:00.000Z",
  "measures": [],
  "dimensions": [],
  "facts": [],
  "dimension_groups": [],
  "verification_filters": [],
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
measures[].display_data_type string | null Localized data type label
measures[].measure_type string | null base or calculated
dimensions[].dimension_type string | null primary or derived
dimensions[].formula string | null Formula of a derived dimension
facts[].fact_type string | null primary, derived, or constant
measures[].dependencies array | null Present and populated only when include_dependencies=true; each node has id, name, type, formula and a recursive dependencies array
dimensions[].is_from_dimension_group boolean true for dimensions inherited from a linked dimension group; false for dimensions defined directly on the fact table
dimensions[].dimension_group_id string | null The group an inherited dimension comes from
…physical_column string | null Column bound to the element in the source table
dimension_groups[].primary_key, foreign_key object | null Source objects of the join (section 3.6 of the API page)
verification_filters[].is_valid boolean false when the filter expression cannot be resolved (missing reference, syntax error); invalid_reason carries the localized explanation
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.DUPLICATE_NAME 409 A fact table with this name exists in the version

2.30 Replace fact table

Request

PUT {v}/fact-tables/{fact_table_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
name body string yes 1–64 characters; letters, digits, _, ., -, space; must start with a letter or digit; unique among the version's fact tables
description body string no Up to 255 characters
owner body string no Accepted and ignored — the key owner becomes the owner

Details

name is required; an omitted description is reset to empty. Element assignments are not touched.

Response

200 OK

{
  "id": "11",
  "name": "fact_sales",
  "description": "Primary sales facts",
  "owner": "Pavel Shalavin",
  "created_at": "2026-04-15T08:30:00Z",
  "measures": [
    { "id": "501", "name": "Total revenue", "description": "Gross revenue", "formula": "SUM([Amount])", "display_data_type": "Number", "measure_type": "base", "dependencies": null }
  ],
  "dimensions": [
    { "id": "801", "name": "Sale date", "description": "Calendar date of the sale", "display_data_type": "Date", "dimension_type": "primary", "formula": null, "physical_column": "sale_date", "is_from_dimension_group": false, "dimension_group_id": null }
  ],
  "facts": [
    { "id": "611", "name": "Order line", "description": null, "fact_type": "primary", "formula": null, "physical_column": "amount" }
  ],
  "dimension_groups": [
    {
      "id": "9", "name": "Geography", "description": "Geographic regions and countries",
      "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" },
      "foreign_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_sales", "column": "region_id" }
    }
  ],
  "verification_filters": [
    { "id": "301", "name": "Valid sales only", "description": "Excludes test and cancelled orders", "conditions": "[Status] != 'cancelled'", "is_valid": true, "invalid_reason": null }
  ],
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
measures[].display_data_type string | null Localized data type label
measures[].measure_type string | null base or calculated
dimensions[].dimension_type string | null primary or derived
dimensions[].formula string | null Formula of a derived dimension
facts[].fact_type string | null primary, derived, or constant
measures[].dependencies array | null Present and populated only when include_dependencies=true; each node has id, name, type, formula and a recursive dependencies array
dimensions[].is_from_dimension_group boolean true for dimensions inherited from a linked dimension group; false for dimensions defined directly on the fact table
dimensions[].dimension_group_id string | null The group an inherited dimension comes from
…physical_column string | null Column bound to the element in the source table
dimension_groups[].primary_key, foreign_key object | null Source objects of the join (section 3.6 of the API page)
verification_filters[].is_valid boolean false when the filter expression cannot be resolved (missing reference, syntax error); invalid_reason carries the localized explanation
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.MISSING_REQUIRED_FIELD 400 name missing
DF_API.DUPLICATE_NAME 409 Another fact table has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.31 Update fact table

Request

PATCH {v}/fact-tables/{fact_table_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
name body string no 1–64 characters; letters, digits, _, ., -, space; must start with a letter or digit; unique among the version's fact tables
description body string no Up to 255 characters
owner body string no Accepted and ignored — the key owner becomes the owner

Details

Only the supplied fields change.

Response

200 OK

{
  "id": "11",
  "name": "fact_sales",
  "description": "Primary sales facts",
  "owner": "Pavel Shalavin",
  "created_at": "2026-04-15T08:30:00Z",
  "measures": [
    { "id": "501", "name": "Total revenue", "description": "Gross revenue", "formula": "SUM([Amount])", "display_data_type": "Number", "measure_type": "base", "dependencies": null }
  ],
  "dimensions": [
    { "id": "801", "name": "Sale date", "description": "Calendar date of the sale", "display_data_type": "Date", "dimension_type": "primary", "formula": null, "physical_column": "sale_date", "is_from_dimension_group": false, "dimension_group_id": null }
  ],
  "facts": [
    { "id": "611", "name": "Order line", "description": null, "fact_type": "primary", "formula": null, "physical_column": "amount" }
  ],
  "dimension_groups": [
    {
      "id": "9", "name": "Geography", "description": "Geographic regions and countries",
      "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" },
      "foreign_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_sales", "column": "region_id" }
    }
  ],
  "verification_filters": [
    { "id": "301", "name": "Valid sales only", "description": "Excludes test and cancelled orders", "conditions": "[Status] != 'cancelled'", "is_valid": true, "invalid_reason": null }
  ],
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
measures[].display_data_type string | null Localized data type label
measures[].measure_type string | null base or calculated
dimensions[].dimension_type string | null primary or derived
dimensions[].formula string | null Formula of a derived dimension
facts[].fact_type string | null primary, derived, or constant
measures[].dependencies array | null Present and populated only when include_dependencies=true; each node has id, name, type, formula and a recursive dependencies array
dimensions[].is_from_dimension_group boolean true for dimensions inherited from a linked dimension group; false for dimensions defined directly on the fact table
dimensions[].dimension_group_id string | null The group an inherited dimension comes from
…physical_column string | null Column bound to the element in the source table
dimension_groups[].primary_key, foreign_key object | null Source objects of the join (section 3.6 of the API page)
verification_filters[].is_valid boolean false when the filter expression cannot be resolved (missing reference, syntax error); invalid_reason carries the localized explanation
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.DUPLICATE_NAME 409 Another fact table has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.32 Delete fact table

Request

DELETE {v}/fact-tables/{fact_table_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier

Details

A fact table with an active relationship (a dimension group joined through a foreign key) cannot be deleted — delete the relationships first (DELETE {v}/relationships/{relationship_id}). Plain assignments (measures, dimensions, facts, groups without a key, verification filters) are removed together with the table, atomically.

Response

204 No Content

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.CONSTRAINT_VIOLATION 409 The fact table has active relationships

2.33 Assign measures to a fact table

Request

POST {v}/fact-tables/{fact_table_id}/measures

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
Idempotency-Key header UUID v4 no Replay protection
measure_ids body array of string yes At least one measure identifier
{ "measure_ids": ["501", "502"] }

Details

Identifiers are partitioned into assignable and rejected ones, in request order; the assignable ones are attached and the rest reported in failed[] — the request never fails as a whole while at least one identifier was applied. An identifier already assigned lands in failed[] with constraint_violation, an identifier that is not a measure of the version with resource_not_found. A measure whose overall health status is error (see the Measure health cards page) cannot be assigned and lands in failed[] with measure_health_error ("A measure with Error health status can't be added"); a measure already assigned stays and is reported as already assigned.

Response

201 Created when every identifier was applied; 207 Multi-Status when some were rejected:

{
  "timestamp": "2026-05-05T08:30:00.120Z",
  "succeeded": [ { "id": "501" } ],
  "failed": [
    { "index": 1, "id": "502", "error": { "code": "constraint_violation", "message": "Element is already assigned", "details": [] } }
  ]
}
Field Type Description
succeeded[].id string Applied identifiers
failed[].index, id integer / string Position and value of the rejected identifier
failed[].error object code, message, details (empty — the item is addressed by index / id)

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.VALIDATION_FAILED 400 measure_ids empty or malformed
DF_API.BULK_REJECTED 422 No identifier was applied; details[] addresses measure_ids.<index>

2.34 Unassign a measure from a fact table

Request

DELETE {v}/fact-tables/{fact_table_id}/measures/{measure_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
measure_id path integer yes Measure identifier

Details

Removes the assignment only; the measure stays in the RMD.

Response

204 No Content

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.RESOURCE_NOT_FOUND 404 The measure is not assigned to the fact table

2.35 Assign dimensions to a fact table

Request

POST {v}/fact-tables/{fact_table_id}/dimensions

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
Idempotency-Key header UUID v4 no Replay protection
dimension_ids body array of string yes At least one dimension identifier
{ "dimension_ids": ["801", "802"] }

Details

Identifiers are partitioned into assignable and rejected ones, in request order; the assignable ones are attached and the rest reported in failed[] — the request never fails as a whole while at least one identifier was applied. An identifier already assigned lands in failed[] with constraint_violation, an identifier that is not a dimension of the version with resource_not_found. A dimension that belongs to a dimension group is rejected with constraint_violation — it reaches the fact table through its group.

Response

201 Created when every identifier was applied; 207 Multi-Status when some were rejected:

{
  "timestamp": "2026-05-05T08:30:00.120Z",
  "succeeded": [ { "id": "501" } ],
  "failed": [
    { "index": 1, "id": "502", "error": { "code": "constraint_violation", "message": "Element is already assigned", "details": [] } }
  ]
}
Field Type Description
succeeded[].id string Applied identifiers
failed[].index, id integer / string Position and value of the rejected identifier
failed[].error object code, message, details (empty — the item is addressed by index / id)

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.VALIDATION_FAILED 400 dimension_ids empty or malformed
DF_API.BULK_REJECTED 422 No identifier was applied; details[] addresses dimension_ids.<index>

2.36 Unassign a dimension from a fact table

Request

DELETE {v}/fact-tables/{fact_table_id}/dimensions/{dimension_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
dimension_id path integer yes Dimension identifier

Response

204 No Content

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.RESOURCE_NOT_FOUND 404 The dimension is not assigned to the fact table

2.37 Assign facts to a fact table

Request

POST {v}/fact-tables/{fact_table_id}/facts

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
Idempotency-Key header UUID v4 no Replay protection
fact_ids body array of string yes At least one fact identifier
{ "fact_ids": ["611", "612"] }

Details

Identifiers are partitioned into assignable and rejected ones, in request order; the assignable ones are attached and the rest reported in failed[] — the request never fails as a whole while at least one identifier was applied. An identifier already assigned lands in failed[] with constraint_violation, an identifier that is not a fact of the version with resource_not_found.

Response

201 Created when every identifier was applied; 207 Multi-Status when some were rejected:

{
  "timestamp": "2026-05-05T08:30:00.120Z",
  "succeeded": [ { "id": "501" } ],
  "failed": [
    { "index": 1, "id": "502", "error": { "code": "constraint_violation", "message": "Element is already assigned", "details": [] } }
  ]
}
Field Type Description
succeeded[].id string Applied identifiers
failed[].index, id integer / string Position and value of the rejected identifier
failed[].error object code, message, details (empty — the item is addressed by index / id)

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.VALIDATION_FAILED 400 fact_ids empty or malformed
DF_API.BULK_REJECTED 422 No identifier was applied; details[] addresses fact_ids.<index>

2.38 Unassign a fact from a fact table

Request

DELETE {v}/fact-tables/{fact_table_id}/facts/{fact_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
fact_id path integer yes Fact identifier

Response

204 No Content

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.RESOURCE_NOT_FOUND 404 The fact is not assigned to the fact table

2.39 Assign dimension groups to a fact table

Request

POST {v}/fact-tables/{fact_table_id}/dimension-groups

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
Idempotency-Key header UUID v4 no Replay protection
dimension_group_ids body array of string yes At least one dimension group identifier
{ "dimension_group_ids": ["9", "10"] }

Details

Identifiers are partitioned into assignable and rejected ones, in request order; the assignable ones are attached and the rest reported in failed[] — the request never fails as a whole while at least one identifier was applied. An identifier already assigned lands in failed[] with constraint_violation, an identifier that is not a dimension group of the version with resource_not_found. Assigning a group makes its dimensions available to the fact table (is_from_dimension_group: true in the fact table details). The assignment carries no foreign key until a relationship is created for it (POST {v}/relationships).

Response

201 Created when every identifier was applied; 207 Multi-Status when some were rejected:

{
  "timestamp": "2026-05-05T08:30:00.120Z",
  "succeeded": [ { "id": "501" } ],
  "failed": [
    { "index": 1, "id": "502", "error": { "code": "constraint_violation", "message": "Element is already assigned", "details": [] } }
  ]
}
Field Type Description
succeeded[].id string Applied identifiers
failed[].index, id integer / string Position and value of the rejected identifier
failed[].error object code, message, details (empty — the item is addressed by index / id)

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.VALIDATION_FAILED 400 dimension_group_ids empty or malformed
DF_API.BULK_REJECTED 422 No identifier was applied; details[] addresses dimension_group_ids.<index>

2.40 Unassign a dimension group from a fact table

Request

DELETE {v}/fact-tables/{fact_table_id}/dimension-groups/{dimension_group_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
dimension_group_id path integer yes Dimension group identifier

Details

A group joined through an active relationship cannot be unassigned — delete the relationship first (DELETE {v}/relationships/{relationship_id}).

Response

204 No Content

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.RESOURCE_NOT_FOUND 404 The group is not assigned to the fact table
DF_API.CONSTRAINT_VIOLATION 409 The group is joined through a relationship

2.41 Create a per-fact-table verification filter

Request

POST {v}/fact-tables/{fact_table_id}/verification-filters

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
Idempotency-Key header UUID v4 no Replay protection
name body string yes 1–64 characters; unique among the fact table's filters
description body string no Up to 255 characters
conditions body string yes Filter expression; element references as [Element name]
{ "name": "Valid sales only", "description": "Excludes test and cancelled orders", "conditions": "[Status] != 'cancelled'" }

Details

Element references in conditions — written as [Element name] or as bare element names outside string literals — are resolved to the version's elements on write and rendered back as [Name] in responses; a name that matches no element is left as written and is reported by the read endpoints as is_valid: false in the fact table details.

Response

201 Created

{
  "id": "301",
  "name": "Valid sales only",
  "description": "Excludes test and cancelled orders",
  "conditions": "[Status] != 'cancelled'",
  "created_at": "2026-05-05T08:30:00.000Z",
  "updated_at": "2026-05-05T08:30:00.000Z",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Filter identifier
name, description, conditions string / string | null / string | null As stored
created_at, updated_at string | null Filter timestamps
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.DUPLICATE_NAME 409 A filter with this name exists on the fact table

2.42 Replace a per-fact-table verification filter

Request

PUT {v}/fact-tables/{fact_table_id}/verification-filters/{filter_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
filter_id path integer yes Filter identifier
name body string yes 1–64 characters; unique among the fact table's filters
description body string no Up to 255 characters
conditions body string yes Filter expression; element references as [Element name]

Details

name and conditions are required; an omitted description is reset to null. Element references in conditions are resolved and rendered back as [Name].

Response

200 OK

{
  "id": "301",
  "name": "Valid sales only",
  "description": "Excludes test and cancelled orders",
  "conditions": "[Status] != 'cancelled'",
  "created_at": "2026-05-05T08:30:00.000Z",
  "updated_at": "2026-05-05T08:30:00.000Z",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Filter identifier
name, description, conditions string / string | null / string | null As stored
created_at, updated_at string | null Filter timestamps
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.RESOURCE_NOT_FOUND 404 The filter does not belong to the fact table
DF_API.MISSING_REQUIRED_FIELD 400 name or conditions missing
DF_API.DUPLICATE_NAME 409 Another filter of the fact table has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.43 Update a per-fact-table verification filter

Request

PATCH {v}/fact-tables/{fact_table_id}/verification-filters/{filter_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
filter_id path integer yes Filter identifier
name body string no 1–64 characters; unique among the fact table's filters
description body string no Up to 255 characters
conditions body string no Filter expression; element references as [Element name]

Details

Only the supplied fields change.

Response

200 OK

{
  "id": "301",
  "name": "Valid sales only",
  "description": "Excludes test and cancelled orders",
  "conditions": "[Status] != 'cancelled'",
  "created_at": "2026-05-05T08:30:00.000Z",
  "updated_at": "2026-05-05T08:30:00.000Z",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Filter identifier
name, description, conditions string / string | null / string | null As stored
created_at, updated_at string | null Filter timestamps
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 The fact table does not exist in the version
DF_API.RESOURCE_NOT_FOUND 404 The filter does not belong to the fact table
DF_API.DUPLICATE_NAME 409 Another filter of the fact table has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.44 Delete a per-fact-table verification filter

Request

DELETE {v}/fact-tables/{fact_table_id}/verification-filters/{filter_id}

Parameter In Type Required Description
fact_table_id path integer yes Fact table identifier
filter_id path integer yes Filter identifier

Response

204 No Content

Errors. 404 DF_API.FACT_TABLE_NOT_FOUND, 404 DF_API.RESOURCE_NOT_FOUND.

2.45 Create a version-scoped verification filter

Request

POST {v}/verification-filters

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
name body string yes 1–64 characters; unique among the version's global filters
description body string no Up to 255 characters
conditions body string yes Filter expression

Details

A version-scoped ("global") filter is bound to no fact table and applies to global measures. Element references in conditions — written as [Element name] or as bare element names outside string literals — are resolved to the version's elements on write and rendered back as [Name] in responses; a name that matches no element is left as written and is reported by the read endpoints as is_valid: false in the fact table details.

Response

201 Created

{
  "id": "301",
  "name": "Valid sales only",
  "description": "Excludes test and cancelled orders",
  "conditions": "[Status] != 'cancelled'",
  "created_at": "2026-05-05T08:30:00.000Z",
  "updated_at": "2026-05-05T08:30:00.000Z",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Filter identifier
name, description, conditions string / string | null / string | null As stored
created_at, updated_at string | null Filter timestamps
timestamp string Moment of the operation

Errors. 409 DF_API.DUPLICATE_NAME.

2.46 Replace a version-scoped verification filter

Request

PUT {v}/verification-filters/{filter_id}

Parameter In Type Required Description
filter_id path integer yes Filter identifier
name body string yes 1–64 characters; unique among the version's global filters
description body string no Up to 255 characters
conditions body string yes Filter expression

Details

name and conditions are required; an omitted description is reset to null.

Response

200 OK

{
  "id": "301",
  "name": "Valid sales only",
  "description": "Excludes test and cancelled orders",
  "conditions": "[Status] != 'cancelled'",
  "created_at": "2026-05-05T08:30:00.000Z",
  "updated_at": "2026-05-05T08:30:00.000Z",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Filter identifier
name, description, conditions string / string | null / string | null As stored
created_at, updated_at string | null Filter timestamps
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The filter does not exist in the version
DF_API.MISSING_REQUIRED_FIELD 400 name or conditions missing
DF_API.DUPLICATE_NAME 409 Another global filter of the version has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.47 Update a version-scoped verification filter

Request

PATCH {v}/verification-filters/{filter_id}

Parameter In Type Required Description
filter_id path integer yes Filter identifier
name body string no 1–64 characters; unique among the version's global filters
description body string no Up to 255 characters
conditions body string no Filter expression

Details

Only the supplied fields change.

Response

200 OK

{
  "id": "301",
  "name": "Valid sales only",
  "description": "Excludes test and cancelled orders",
  "conditions": "[Status] != 'cancelled'",
  "created_at": "2026-05-05T08:30:00.000Z",
  "updated_at": "2026-05-05T08:30:00.000Z",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Filter identifier
name, description, conditions string / string | null / string | null As stored
created_at, updated_at string | null Filter timestamps
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The filter does not exist in the version
DF_API.DUPLICATE_NAME 409 Another global filter of the version has the new name
DF_API.ID_MISMATCH 400 Body id differs from the path

2.48 Delete a version-scoped verification filter

Request

DELETE {v}/verification-filters/{filter_id}

Parameter In Type Required Description
filter_id path integer yes Filter identifier

Response

204 No Content

Errors. 404 DF_API.RESOURCE_NOT_FOUND.

2.49 Create relationship

Request

POST {v}/relationships

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
source_fact_table_id body string yes Fact table holding the foreign key
target_dimension_group_id body string yes Dimension group holding the primary key
foreign_key body object yes Source object on the fact table side (section 3.6 of the API page)
primary_key body object yes Source object on the dimension group side; becomes the group's primary key
relationship_type body string yes Must be many_to_one
{
  "source_fact_table_id": "11",
  "target_dimension_group_id": "9",
  "foreign_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_sales", "column": "region_id" },
  "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" },
  "relationship_type": "many_to_one"
}

Details

If the group is not yet assigned to the fact table, the assignment is created together with the relationship. Both keys are validated (section 1): with connection supplied, each key must name the connection its side already uses, and both keys must name the same connection.

Response

201 Created

{
  "id": "1101",
  "source_fact_table": { "id": "11", "name": "fact_sales", "description": "Primary sales facts" },
  "target_dimension_group": {
    "id": "9", "name": "Geography", "description": "Geographic regions and countries",
    "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" }
  },
  "foreign_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_sales", "column": "region_id" },
  "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" },
  "relationship_type": "many_to_one",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Relationship identifier
source_fact_table, target_dimension_group object Both sides with description; the group side repeats its primary_key
foreign_key, primary_key object | null Source objects with connection; null when the mapping is incomplete
relationship_type string Slug many_to_one (the only cardinality the model supports)
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.FACT_TABLE_NOT_FOUND 404 source_fact_table_id does not exist in the version
DF_API.RESOURCE_NOT_FOUND 404 target_dimension_group_id does not exist in the version
DF_API.INVALID_RELATIONSHIP_TYPE 400 relationship_type is not many_to_one
DF_API.DUPLICATE_RELATIONSHIP 409 A relationship between this fact table and group already exists
DF_API.INVALID_SOURCE_*, DF_API.CONNECTION_MISMATCH 400 Key validation (section 1)

2.50 Replace relationship

Request

PUT {v}/relationships/{relationship_id}

Parameter In Type Required Description
relationship_id path integer yes Relationship identifier
foreign_key body object yes New foreign key
primary_key body object yes New primary key of the group

Details

Only the key coordinates can be changed; the fact table and the group are fixed. Both keys are validated before either is written.

Response

200 OK

{
  "id": "1101",
  "source_fact_table": { "id": "11", "name": "fact_sales", "description": "Primary sales facts" },
  "target_dimension_group": {
    "id": "9", "name": "Geography", "description": "Geographic regions and countries",
    "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" }
  },
  "foreign_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_sales", "column": "region_id" },
  "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" },
  "relationship_type": "many_to_one",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Relationship identifier
source_fact_table, target_dimension_group object Both sides with description; the group side repeats its primary_key
foreign_key, primary_key object | null Source objects with connection; null when the mapping is incomplete
relationship_type string Slug many_to_one (the only cardinality the model supports)
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RELATIONSHIP_NOT_FOUND 404 The relationship does not exist in the version
DF_API.MISSING_REQUIRED_FIELD 400 foreign_key or primary_key missing
DF_API.ID_MISMATCH 400 Body id differs from the path
DF_API.INVALID_SOURCE_*, DF_API.CONNECTION_MISMATCH 400 Key validation

2.51 Update relationship

Request

PATCH {v}/relationships/{relationship_id}

Parameter In Type Required Description
relationship_id path integer yes Relationship identifier
foreign_key body object no New foreign key
primary_key body object no New primary key of the group

Details

A key that is not sent keeps its stored value and is used for the same-connection check against the one that is sent.

Response

200 OK

{
  "id": "1101",
  "source_fact_table": { "id": "11", "name": "fact_sales", "description": "Primary sales facts" },
  "target_dimension_group": {
    "id": "9", "name": "Geography", "description": "Geographic regions and countries",
    "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" }
  },
  "foreign_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "fact_sales", "column": "region_id" },
  "primary_key": { "connection": "Production PostgreSQL", "db": "analytics_db", "schema": "public", "table": "dim_geography", "column": "region_id" },
  "relationship_type": "many_to_one",
  "timestamp": "2026-05-05T08:30:00.120Z"
}
Field Type Description
id string Relationship identifier
source_fact_table, target_dimension_group object Both sides with description; the group side repeats its primary_key
foreign_key, primary_key object | null Source objects with connection; null when the mapping is incomplete
relationship_type string Slug many_to_one (the only cardinality the model supports)
timestamp string Moment of the operation

Errors

Code HTTP Condition
DF_API.RELATIONSHIP_NOT_FOUND 404 The relationship does not exist in the version
DF_API.ID_MISMATCH 400 Body id differs from the path
DF_API.INVALID_SOURCE_*, DF_API.CONNECTION_MISMATCH 400 Key validation

2.52 Delete relationship

Request

DELETE {v}/relationships/{relationship_id}

Parameter In Type Required Description
relationship_id path integer yes Relationship identifier

Details

Deleting a relationship clears the foreign key only; the dimension group stays assigned to the fact table (unassign it with DELETE {v}/fact-tables/{fact_table_id}/dimension-groups/{dimension_group_id}).

Response

204 No Content

Errors

Code HTTP Condition
DF_API.RELATIONSHIP_NOT_FOUND 404 The relationship does not exist in the version

3 Project access management

These endpoints manage the interactive project access that API keys subsequently inherit (section 2.2 of the API page). Unlike the RMD and data-model write endpoints (sections 1–2, which require an effective project role of developer or higher), the access-management endpoints require the caller (API-key owner) to be the project owner or a user with the Administrator or Super administrator role; otherwise the request is rejected with 403 DF_API.WRITE_ACCESS_DENIED. Path identifiers are projectId and userId (camelCase, as in the internal API).

Method Path Section
GET /projects/{projectId}/access 3.1
POST /projects/{projectId}/access 3.2
DELETE /projects/{projectId}/access/{userId} 3.3
PUT /projects/{projectId}/owner 3.4

The internal keys of these checks (PROJECT.INVALID_ACCESS_LEVEL, PROJECT.ACCESS_LEVEL_NOT_ASSIGNABLE, PROJECT.CANNOT_ELEVATE_ACCESS, PROJECT.INVALID_OWNER, PROJECT.ACCESS_DENIED, USER.NOT_FOUND) never leave the API: like any key outside the DF_API.* catalog they degrade to the generic code of their HTTP status (section 4 of the Public API v2 page); the localized cause stays in message.

3.1 Get access configuration

Request

GET /df-api/v2/projects/{projectId}/access

Parameter In Type Required Description
projectId path integer yes Project identifier
language query ru | en no Language of the role labels

Details

Returns the project owner together with every user that has explicit access. Role labels are localized exactly as in the application's "Project members" table. The internal isAdmin and ownerStatus fields are not exposed. The response is a bare array (no pagination).

Response

200 OK

[
  {
    "id": 7,
    "first_name": "Pavel",
    "last_name": "Shalavin",
    "email": "pavel@example.com",
    "isOwner": true,
    "globalRole": "Administrator",
    "projectRole": "Developer"
  }
]
Field Type Description
id integer User identifier
first_name, last_name, email string User identity
isOwner boolean true for the project owner
globalRole string | null Localized global-role label, or null if not resolvable
projectRole string | null Localized project-role label, or null if the user has no explicit project role

Errors

Code HTTP Condition
DF_API.WRITE_ACCESS_DENIED 403 Caller is neither the owner nor an administrator
DF_API.PROJECT_NOT_FOUND 404 Project does not exist or is not visible

3.2 Add or update access

Request

POST /df-api/v2/projects/{projectId}/access

Parameter In Type Required Description
projectId path integer yes Project identifier
Idempotency-Key header UUID v4 no Replay protection
userId body integer yes Target user; must exist and belong to the project's company
accessLevel body string yes developer, analyst or viewer (project_manager is inherited by the owner and not assignable)
{ "userId": 12, "accessLevel": "developer" }

Details

If the user already has access, the level is updated; otherwise access is granted. The grant is subject to the downgrade-only rule — an access level higher than the user's global role is rejected.

Response

201 Created

{ "success": true }
Field Type Description
success boolean Always true on success

Errors

Code HTTP Condition
DF_API.INVALID_PARAMETER 400 accessLevel missing or not one of developer / analyst / viewer; requested level exceeds the target user's global role
DF_API.RESOURCE_NOT_FOUND 404 Target user does not exist or is outside the project's company
DF_API.WRITE_ACCESS_DENIED 403 Caller is neither the owner nor an administrator

3.3 Remove access

Request

DELETE /df-api/v2/projects/{projectId}/access/{userId}

Parameter In Type Required Description
projectId, userId path integer yes Identifiers

Details

Removes the target user's explicit access. The user must exist.

Response

200 OK

{ "success": true }
Field Type Description
success boolean Always true on success

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 Target user does not exist
DF_API.WRITE_ACCESS_DENIED 403 Caller is neither the owner nor an administrator

3.4 Transfer ownership

Request

PUT /df-api/v2/projects/{projectId}/owner

Parameter In Type Required Description
projectId path integer yes Project identifier
newOwnerId body integer yes The new owner; must exist, belong to the project's company and hold a role eligible for ownership (PROJECT_MANAGER, COMPANY_ADMIN or SUPER_ADMIN)
{ "newOwnerId": 12 }

Response

200 OK

{ "success": true }
Field Type Description
success boolean Always true on success

Errors

Code HTTP Condition
DF_API.RESOURCE_NOT_FOUND 404 The new owner does not exist or is outside the project's company
DF_API.INVALID_PARAMETER 400 The new owner's role is ineligible for ownership
DF_API.WRITE_ACCESS_DENIED 403 Caller is neither the owner nor an administrator

4 Version transfer: export and import (df-api/v2)

The project-version export/import engine is available through the public API, so a CI/CD pipeline can push configuration to Git and roll it out across environments without a browser.

Method Path Role Section
POST {v}/export/git Analyst or higher 4.1
POST {v}/export/file Analyst or higher 4.2
POST {v}/import/validate Analyst or higher 4.3
POST {v}/import/preview Analyst or higher 4.4
POST {v}/import/git Developer or higher 4.5
POST {v}/import/file Developer or higher 4.6

The role is the key owner's effective role in the project (section 2.2 of the API page); an insufficient role answers 403 DF_API.WRITE_ACCESS_DENIED. Export and the dry runs require Analyst or higher (stricter than the internal API, where a viewer may export too); import requires Developer or higher. All six endpoints answer 200 OK on success.

Git credentials travel either in the authentication object as plaintext over TLS (a CI client cannot assemble the browser's encrypted envelope) or by connection_id, referencing a saved Git connection (section 5):

Field Method Description
authentication.method — pat, ssh or password
authentication.token pat Personal Access Token
authentication.private_key, authentication.passphrase ssh SSH private key and its passphrase (optional)
authentication.username, authentication.password password Login and password

The target repository is always the request's repository_url (an internal host is refused); a saved connection contributes only its credentials, and they are accepted only for the connection's own host. A connection with allow_branch_override / allow_path_override switched off refuses a request whose branch or path differs from the stored ones. An omitted path in a request through a connection means the stored one. Credentials embedded into repository_url are stripped from the response, the audit record and the saved connection.

Cloud-deployment constraint. The multipart endpoints (import/file and the file flavor of import/validate / import/preview) work only in on-premises installations; in the cloud the AWS Lambda wrapper does not pass binary bodies, and synchronous clone/push of large repositories may exceed the gateway's 29-second limit.

Shared errors of the group, beyond the common ones: 422 DF_API.GIT_CONNECTION_FAILED (repository unreachable, credentials rejected, insecure transport), 400 DF_API.INVALID_PARAMETER (unknown branch or commit, malformed archive, no or several project roots in the tree), 422 DF_API.UNPROCESSABLE_ENTITY (size or file-count limits exceeded, invalid import source), 404 DF_API.CONNECTION_NOT_FOUND (connection_id names no visible Git connection).

4.1 Export to Git

Request

POST {v}/export/git

Parameter In Type Required Description
Idempotency-Key header UUID v4 no A replayed key returns the original response
repository_url body string yes Target repository URL (up to 2000 characters, no whitespace)
branch body string yes Target branch (created if absent)
path body string no Path within the repository; / or omitted — the root
commit_message body string yes 1–500 characters
connection_id body string one of Saved Git connection supplying the credentials
authentication body object one of Credentials (table above)
options.include_rmd, include_fact_tables, include_data_marts, include_connections body boolean no Which sections the export carries. Default true
options.include_history body boolean no Include the RMD cell change history. Default false
options.encrypt_sensitive body boolean no Default true; the one refused value is false — connection passwords are never exported in cleartext (400)
options.add_gitattributes body boolean no Lay a .gitattributes into the tree. Default true
options.save_connection, options.connection_name body boolean, string no Store the credentials passed in authentication as a new private connection with the given name (visible to its creator and administrators; sharing is an administrator's decision)
{
  "repository_url": "https://gitlab.example.com/analytics/dataforge-config.git",
  "branch": "main",
  "path": "/sales",
  "commit_message": "Export from DataForge, pipeline 4711",
  "authentication": { "method": "pat", "token": "<personal-access-token>" },
  "options": { "include_history": false }
}

Details

Export is deterministic: re-exporting an unchanged version yields the byte-identical tree, so a repeated export creates no commit and answers commit_hash: null (the branch is never overwritten — changes land as ordinary commits on top of its history). The chain "export → import as a new version → re-export" reproduces the tree without a single difference.

Response

200 OK

{
  "success": true,
  "commit_hash": "3f2a9c1e7b0d4a6f8c2e1b9d7a5c3e1f0b8d6a4c",
  "repository_url": "https://gitlab.example.com/analytics/dataforge-config.git",
  "branch": "main",
  "path": "/sales",
  "files_created": 128,
  "timestamp": "2026-05-05T08:30:00.120Z",
  "connection_id": null
}
Field Type Description
success boolean Always true on a 200
commit_hash string | null Hash of the created commit; null when the tree was unchanged
repository_url, branch, path string Where the tree landed; credentials stripped from the URL
files_created integer Files written into the tree
timestamp string Moment of the operation
connection_id string | null The saved connection that was used or created (options.save_connection)

Errors

Code HTTP Condition
DF_API.MISSING_REQUIRED_FIELD 400 Neither connection_id nor authentication given; connection_name missing with save_connection
DF_API.INVALID_PARAMETER 400 encrypt_sensitive: false; branch or path override refused by the connection; unknown branch
DF_API.GIT_PUSH_FAILED 422 The push was rejected: the branch changed during the export or is protected
Shared errors of the group — Above

4.2 Export to a file

Request

POST {v}/export/file

Parameter In Type Required Description
options.include_rmd, include_fact_tables, include_data_marts, include_connections body boolean no Which sections the export carries. Default true
options.include_history body boolean no Include the RMD cell change history. Default false
options.encrypt_sensitive body boolean no Default true; the one refused value is false — connection passwords are never exported in cleartext (400)
options.encryption_password body string no Wrap the archive in an AES-256-GCM envelope with this password
options.use_system_key body boolean no Wrap the archive with the system key instead (the password wins when both are given). Default false
{ "options": { "include_connections": true, "encryption_password": "<password>" } }

Details

Produces a .dfexport.zip archive in object storage and returns a signed download URL; its lifetime is set by the installation and reported in expires_at. Idempotency-Key is deliberately not honoured — a cached response would carry an expired link.

Response

200 OK

{
  "download_url": "https://storage.example.com/exports/…?signature=…",
  "file_name": "Sales Analytics_Q4 2025.dfexport.zip",
  "file_size": 48213,
  "expires_at": "2026-05-05T09:30:00.000Z"
}
Field Type Description
download_url string Signed URL of the archive
file_name string Suggested file name
file_size integer Size in bytes
expires_at string When the URL stops working, ISO 8601

Errors

Code HTTP Condition
DF_API.INVALID_PARAMETER 400 encrypt_sensitive: false
DF_API.UNPROCESSABLE_ENTITY 422 The export exceeds the size limit

4.3 Validate an import source

Request

POST {v}/import/validate — JSON for a Git source, multipart/form-data for a file source.

Parameter In Type Required Description
source_type body git | file yes What the request carries
repository_url, branch body string git Source repository and branch
path, commit_hash body string no Path within the repository; a commit (7–40 hex characters) to pin instead of the branch tip
connection_id / authentication body — git Credentials (one of the two)
file multipart part binary file The .dfexport.zip archive, plain or sealed
encryption_password body string no Password of a sealed archive
conflict_strategy, options body — no Accepted with the same meaning as in an import request (smart_merge / overwrite / skip / manual; the import_*, detect_merges, decrypt_sensitive, encryption_password options), so the documented import body can be sent as is; a dry run does not act on them. In multipart, options is a JSON string

Details

Validates the source without writing anything. The version in the path is only the access anchor. Idempotency-Key is not honoured (a cached verdict could be stale).

Response

200 OK

{
  "valid": false,
  "errors": [
    { "level": "error", "code": "DUPLICATE_ID", "message": "Duplicate element id", "element": "measures/total_revenue.json", "element_type": "measure" }
  ],
  "warnings": [
    { "level": "warning", "code": "REFERENCE_MISSING", "message": "Referenced fact table is not in the export", "element": "data_marts/monthly.json", "element_type": "data_mart" }
  ],
  "summary": { "measures": 42, "dimensions": 18, "facts": 6, "fact_tables": 3, "data_marts": 2 },
  "schema_version": "1.0"
}
Field Type Description
valid boolean false when errors[] is not empty
errors[], warnings[] array Issues with level, machine code (REQUIRED_FILE_MISSING, DUPLICATE_ID, CIRCULAR_DEPENDENCY, REFERENCE_MISSING, …), message, element, element_type
summary object Element counts in the source: measures, dimensions, facts, fact_tables, data_marts
schema_version string Export format version found in the source

Errors. 400 DF_API.MISSING_REQUIRED_FIELD (a field the source_type requires is missing); shared errors of the group.

4.4 Preview an import

Request

POST {v}/import/preview — JSON for a Git source, multipart/form-data for a file source.

Parameter In Type Required Description
source_type body git | file no What the request carries. May be omitted — then read from the request itself: a multipart upload is a file, anything else a Git branch
repository_url, branch body string git Source repository and branch
path, commit_hash body string no Path within the repository; a commit (7–40 hex characters) to pin instead of the branch tip
connection_id / authentication body — git Credentials (one of the two)
file multipart part binary file The .dfexport.zip archive, plain or sealed
encryption_password body string no Password of a sealed archive
conflict_strategy, options body — no Accepted with the same meaning as in an import request (smart_merge / overwrite / skip / manual; the import_*, detect_merges, decrypt_sensitive, encryption_password options), so the documented import body can be sent as is; a dry run does not act on them. In multipart, options is a JSON string

Details

Compares the source against the version in the path and reports what an import would change, without writing anything. Idempotency-Key is not honoured.

Response

200 OK

{
  "preview_id": "0b1d2c3e-4f5a-6789-abcd-ef0123456789",
  "summary": {
    "measures":    { "added": 3, "modified": 5, "deleted": 0, "total": 45 },
    "dimensions":  { "added": 0, "modified": 1, "deleted": 0, "total": 18 },
    "facts":       { "added": 0, "modified": 0, "deleted": 0, "total": 6 },
    "fact_tables": { "added": 0, "modified": 1, "deleted": 0, "total": 3 },
    "data_marts":  { "added": 1, "modified": 0, "deleted": 0, "total": 3 }
  },
  "conflicts": [
    { "element_type": "measure", "element_id": "1000", "element_name": "Total revenue", "field": "formula", "current_value": "SUM([Amount])", "imported_value": "SUM([Net amount])" }
  ],
  "conflict_resolution_required": true
}
Field Type Description
preview_id string Identifier of this preview
summary.<section> object added, modified, deleted, total per section
conflicts[] array Field-level conflicts: element_type, element_id, element_name, field, current_value, imported_value
conflict_resolution_required boolean true when conflicts[] is not empty

Errors. 400 DF_API.MISSING_REQUIRED_FIELD (a field the source_type requires is missing); shared errors of the group.

4.5 Import from Git

Request

POST {v}/import/git

Parameter In Type Required Description
Idempotency-Key header UUID v4 no A CI runner's retry lands on the same version with the same import_id
repository_url, branch body string yes Source repository and branch
path body string no Path within the repository
commit_hash body string no Pin one commit instead of the branch tip
connection_id / authentication body — one of Credentials
target.method body create | replace no create (default) — a new version (the license version limit applies); replace — fully replace the version addressed in the path
target.version_name body string yes The resulting version's name in both modes (the name of the new version, or the new name of the replaced one); up to 64 characters, letters/digits/underscore/space/dot/dash
conflict_strategy body string no smart_merge (default), overwrite, skip, manual
options.import_rmd, import_fact_tables, import_data_marts, import_connections body boolean no Default true; a switched-off section stays as the current version has it
options.import_history body boolean no Import the RMD cell history. Default false
options.detect_merges body boolean no Carry the merge provenance from the manifest. Default true
options.decrypt_sensitive body boolean no Default true; with false connections are imported without passwords, in the "needs refresh" status
options.encryption_password body string no Password of a sealed source
{
  "repository_url": "https://gitlab.example.com/analytics/dataforge-config.git",
  "branch": "main",
  "path": "/sales",
  "target": { "method": "create", "version_name": "staging_4711" },
  "conflict_strategy": "smart_merge",
  "authentication": { "method": "pat", "token": "<personal-access-token>" }
}

Details

In both modes the version in the path is the baseline the conflict strategy compares against. conflict_strategy acts element by element:

Strategy Behavior
smart_merge (default) Additions and modifications from the source land; elements only the current version has survive
overwrite The source lands verbatim, deletions included
skip Conflicting elements keep their current values; additions land, deletions do not
manual With conflicts present nothing is written: the response is success: false with the conflict list

The import is one transaction and creates the resulting version with element uuids preserved, so re-exports stay comparable in Git. Every import is audited with a before/after snapshot (section 7 of the API page).

Response

200 OK

{
  "success": true,
  "import_id": "7c0e4b2a-1d3f-4e5a-9b8c-6d7e8f9a0b1c",
  "target_project_id": "12",
  "target_version_id": "35",
  "target_version_name": "staging_4711",
  "summary": {
    "measures":    { "added": 3, "modified": 5, "deleted": 0, "total": 45 },
    "dimensions":  { "added": 0, "modified": 1, "deleted": 0, "total": 18 },
    "facts":       { "added": 0, "modified": 0, "deleted": 0, "total": 6 },
    "fact_tables": { "added": 0, "modified": 1, "deleted": 0, "total": 3 },
    "data_marts":  { "added": 1, "modified": 0, "deleted": 0, "total": 3 }
  },
  "conflicts": [],
  "conflict_resolution_required": false
}
Field Type Description
success boolean false only with the manual strategy and conflicts present — nothing was written
import_id string Identifier of the import operation; stable across an idempotent retry
target_project_id, target_version_id, target_version_name string / string / string | null Where the import landed (identifiers as strings)
summary.<section> object added, modified, deleted, total per section
conflicts[] array Field-level conflicts: element_type, element_id, element_name, field, current_value, imported_value
conflict_resolution_required boolean true when conflicts[] is not empty

Errors

Code HTTP Condition
DF_API.MISSING_REQUIRED_FIELD 400 target.version_name missing; neither connection_id nor authentication given
DF_API.DUPLICATE_NAME 409 target.version_name is already taken by another live version of the project
DF_API.LICENSE_LIMIT_REACHED 403 target.method: create while the license version limit is reached
DF_API.UNPROCESSABLE_ENTITY 422 The source fails validation (the errors[] the validation endpoint reports) or exceeds the limits
Shared errors of the group — Above

4.6 Import from a file

Request

POST {v}/import/file — multipart/form-data.

Parameter In Type Required Description
Idempotency-Key header UUID v4 no A CI runner's retry lands on the same version with the same import_id
file multipart part binary yes A .dfexport.zip archive, plain or sealed
target.method form field create | replace no create (default) — a new version (the license version limit applies); replace — fully replace the version addressed in the path
target.version_name form field string yes The resulting version's name in both modes (the name of the new version, or the new name of the replaced one); up to 64 characters, letters/digits/underscore/space/dot/dash
conflict_strategy form field string no smart_merge (default), overwrite, skip, manual
options form field JSON string no JSON string with the import options: import_rmd, import_fact_tables, import_data_marts, import_connections (default true; a switched-off section stays as the current version has it), import_history (false), detect_merges (true), decrypt_sensitive (true; with false connections are imported without passwords), encryption_password
encryption_password form field string no Password of a sealed archive

Details

On-premises installations only (cloud constraint above).

In both modes the version in the path is the baseline the conflict strategy compares against. conflict_strategy acts element by element:

Strategy Behavior
smart_merge (default) Additions and modifications from the source land; elements only the current version has survive
overwrite The source lands verbatim, deletions included
skip Conflicting elements keep their current values; additions land, deletions do not
manual With conflicts present nothing is written: the response is success: false with the conflict list

The import is one transaction and creates the resulting version with element uuids preserved, so re-exports stay comparable in Git. Every import is audited with a before/after snapshot (section 7 of the API page).

Response

200 OK

{
  "success": true,
  "import_id": "7c0e4b2a-1d3f-4e5a-9b8c-6d7e8f9a0b1c",
  "target_project_id": "12",
  "target_version_id": "35",
  "target_version_name": "staging_4711",
  "summary": {
    "measures":    { "added": 3, "modified": 5, "deleted": 0, "total": 45 },
    "dimensions":  { "added": 0, "modified": 1, "deleted": 0, "total": 18 },
    "facts":       { "added": 0, "modified": 0, "deleted": 0, "total": 6 },
    "fact_tables": { "added": 0, "modified": 1, "deleted": 0, "total": 3 },
    "data_marts":  { "added": 1, "modified": 0, "deleted": 0, "total": 3 }
  },
  "conflicts": [],
  "conflict_resolution_required": false
}
Field Type Description
success boolean false only with the manual strategy and conflicts present — nothing was written
import_id string Identifier of the import operation; stable across an idempotent retry
target_project_id, target_version_id, target_version_name string / string / string | null Where the import landed (identifiers as strings)
summary.<section> object added, modified, deleted, total per section
conflicts[] array Field-level conflicts: element_type, element_id, element_name, field, current_value, imported_value
conflict_resolution_required boolean true when conflicts[] is not empty

Errors

Code HTTP Condition
DF_API.MISSING_REQUIRED_FIELD 400 target.version_name missing; neither connection_id nor authentication given
DF_API.DUPLICATE_NAME 409 target.version_name is already taken by another live version of the project
DF_API.LICENSE_LIMIT_REACHED 403 target.method: create while the license version limit is reached
DF_API.UNPROCESSABLE_ENTITY 422 The source fails validation (the errors[] the validation endpoint reports) or exceeds the limits
Shared errors of the group — Above
DF_API.INVALID_PARAMETER 400 A corrupted archive or a wrong file type

5 Git connection management (df-api/v2)

The company's registry of saved Git connections (see also section 4). Every endpoint requires the COMPANY_ADMIN role (or SUPER_ADMIN); an insufficient role answers 403 DF_API.WRITE_ACCESS_DENIED, a connection the key cannot see 404 DF_API.CONNECTION_NOT_FOUND. Paths are company-scoped and carry no project or version.

Method Path Section
GET /git-connections 5.1
POST /git-connections 5.2
GET /git-connections/{connection_id} 5.3
PUT /git-connections/{connection_id} 5.4
DELETE /git-connections/{connection_id} 5.5
POST /git-connections/{connection_id}/test 5.6

The connection object returned by 5.1–5.4:

{
  "id": "17",
  "name": "Config repository",
  "platform": "gitlab",
  "repository_url": "https://gitlab.example.com/analytics/dataforge-config.git",
  "branch": "main",
  "path": "/sales",
  "status": "active",
  "last_used": "2026-05-05T08:30:00.000Z",
  "created_at": "2026-04-01T10:00:00.000Z",
  "created_by": "admin@example.com",
  "shared": false,
  "default": true
}
Field Type Description
id string Connection identifier
name string Display name
platform string github, gitlab, bitbucket, azure-devops, generic; additionally github-enterprise on read (created only in the browser dialog)
repository_url string Repository URL without credentials
branch string Default branch
path string Path within the repository, always with a leading /; / for the root
status string active (the last check passed) or failed
last_used string | null Stamped by exports/imports running through the connection
created_at string Creation timestamp
created_by string | null The creator's e-mail
shared boolean Usable by every user of the company; a non-shared connection is visible only to its creator and administrators
default boolean The company's default connection

Credentials are never returned.

5.1 List Git connections

Request

GET /df-api/v2/git-connections

Parameter In Type Required Description
page query integer no Page number, 1-indexed. Default 1
pageSize query integer no Items per page. Default 20, maximum 100 (a larger value is refused)

Response

200 OK

{
  "git-connections": [ { "id": "17", "name": "Config repository", "…": "…" } ],
  "pagination": { "total": 1, "page": 1, "pageSize": 20, "totalPages": 1 }
}
Field Type Description
git-connections[] array Connection objects (above). The key is spelled with a hyphen
pagination object total, page, pageSize, totalPages

Errors

Code HTTP Condition
DF_API.PAGE_SIZE_EXCEEDED 400 pageSize above 100
DF_API.WRITE_ACCESS_DENIED 403 The key owner has neither the Administrator nor the Super administrator role

5.2 Create a Git connection

Request

POST /df-api/v2/git-connections

Parameter In Type Required Description
Idempotency-Key header UUID v4 no Replay protection
name body string yes 1–255 characters
platform body string yes github, gitlab, bitbucket, azure-devops, generic
repository_url body string yes Repository URL (an internal host is refused)
branch body string yes Default branch
path body string no Path within the repository
authentication body object yes Credentials (section 4): method pat / ssh / password and its fields
settings.allow_branch_override body boolean no Allow an export/import through this connection to name a different branch. Default true
settings.allow_path_override body boolean no The same for the path. Default true
settings.set_as_default body boolean no Make it the company's default connection (displaces the previous holder). Default false
settings.share_with_all body boolean no Make it usable by every user of the company. Default false (connections created in the internal UI are shared)
{
  "name": "Config repository",
  "platform": "gitlab",
  "repository_url": "https://gitlab.example.com/analytics/dataforge-config.git",
  "branch": "main",
  "path": "/sales",
  "authentication": { "method": "pat", "token": "<personal-access-token>" },
  "settings": { "set_as_default": true }
}

Details

The connection is tested before it is stored — an unreachable repository or rejected credentials refuse the creation. Credentials are encrypted at rest.

Response

201 Created

{
  "id": "17",
  "name": "Config repository",
  "platform": "gitlab",
  "repository_url": "https://gitlab.example.com/analytics/dataforge-config.git",
  "branch": "main",
  "path": "/sales",
  "status": "active",
  "last_used": "2026-05-05T08:30:00.000Z",
  "created_at": "2026-04-01T10:00:00.000Z",
  "created_by": "admin@example.com",
  "shared": false,
  "default": true
}
Field Type Description
id string Connection identifier
name string Display name
platform string github, gitlab, bitbucket, azure-devops, generic; additionally github-enterprise on read (created only in the browser dialog)
repository_url string Repository URL without credentials
branch string Default branch
path string Path within the repository, always with a leading /; / for the root
status string active (the last check passed) or failed
last_used string | null Stamped by exports/imports running through the connection
created_at string Creation timestamp
created_by string | null The creator's e-mail
shared boolean Usable by every user of the company; a non-shared connection is visible only to its creator and administrators
default boolean The company's default connection

Errors

Code HTTP Condition
DF_API.GIT_CONNECTION_FAILED 422 The repository is unreachable or rejected the credentials
DF_API.INVALID_PARAMETER 400 The branch does not exist
DF_API.WRITE_ACCESS_DENIED 403 The key owner is not an administrator

5.3 Get a Git connection

Request

GET /df-api/v2/git-connections/{connection_id}

Parameter In Type Required Description
connection_id path integer yes Connection identifier

Response

200 OK

{
  "id": "17",
  "name": "Config repository",
  "platform": "gitlab",
  "repository_url": "https://gitlab.example.com/analytics/dataforge-config.git",
  "branch": "main",
  "path": "/sales",
  "status": "active",
  "last_used": "2026-05-05T08:30:00.000Z",
  "created_at": "2026-04-01T10:00:00.000Z",
  "created_by": "admin@example.com",
  "shared": false,
  "default": true
}
Field Type Description
id string Connection identifier
name string Display name
platform string github, gitlab, bitbucket, azure-devops, generic; additionally github-enterprise on read (created only in the browser dialog)
repository_url string Repository URL without credentials
branch string Default branch
path string Path within the repository, always with a leading /; / for the root
status string active (the last check passed) or failed
last_used string | null Stamped by exports/imports running through the connection
created_at string Creation timestamp
created_by string | null The creator's e-mail
shared boolean Usable by every user of the company; a non-shared connection is visible only to its creator and administrators
default boolean The company's default connection

Errors. 404 DF_API.CONNECTION_NOT_FOUND, 403 DF_API.WRITE_ACCESS_DENIED.

5.4 Update a Git connection

Request

PUT /df-api/v2/git-connections/{connection_id}

Parameter In Type Required Description
connection_id path integer yes Connection identifier
name, platform, repository_url, branch, path body — no As on create; only the supplied fields change
authentication body object no New credentials; when absent, the stored credentials are kept
settings.* body boolean no Any subset of the create settings

Details

Repointing the connection to another host requires re-entering the credentials.

Response

200 OK

{
  "id": "17",
  "name": "Config repository",
  "platform": "gitlab",
  "repository_url": "https://gitlab.example.com/analytics/dataforge-config.git",
  "branch": "main",
  "path": "/sales",
  "status": "active",
  "last_used": "2026-05-05T08:30:00.000Z",
  "created_at": "2026-04-01T10:00:00.000Z",
  "created_by": "admin@example.com",
  "shared": false,
  "default": true
}
Field Type Description
id string Connection identifier
name string Display name
platform string github, gitlab, bitbucket, azure-devops, generic; additionally github-enterprise on read (created only in the browser dialog)
repository_url string Repository URL without credentials
branch string Default branch
path string Path within the repository, always with a leading /; / for the root
status string active (the last check passed) or failed
last_used string | null Stamped by exports/imports running through the connection
created_at string Creation timestamp
created_by string | null The creator's e-mail
shared boolean Usable by every user of the company; a non-shared connection is visible only to its creator and administrators
default boolean The company's default connection

Errors

Code HTTP Condition
DF_API.CONNECTION_NOT_FOUND 404 The connection does not exist or is not visible
DF_API.INVALID_PARAMETER 400 repository_url moves to another host without new authentication
DF_API.WRITE_ACCESS_DENIED 403 The key owner is not an administrator

5.5 Delete a Git connection

Request

DELETE /df-api/v2/git-connections/{connection_id}

Parameter In Type Required Description
connection_id path integer yes Connection identifier

Details

Versions imported through the connection survive and lose the link.

Response

204 No Content

Errors. 404 DF_API.CONNECTION_NOT_FOUND, 403 DF_API.WRITE_ACCESS_DENIED.

5.6 Test a Git connection

Request

POST /df-api/v2/git-connections/{connection_id}/test

Parameter In Type Required Description
connection_id path integer yes Connection identifier

Details

No body. Runs the five checks against the repository and refreshes the connection's stored status, as in the internal UI. Idempotency-Key is deliberately not honoured — a cached verdict would be stale. An empty repository is a valid export target: the checks pass and last_commit is null.

Response

200 OK

{
  "git-connection_id": "17",
  "status": "success",
  "tests": {
    "repository_reachable": true,
    "authentication_valid": true,
    "branch_exists": true,
    "write_permission": true,
    "path_accessible": true
  },
  "details": {
    "last_commit": "3f2a9c1",
    "last_commit_date": "2026-05-05T08:30:00.000Z",
    "available_branches": ["main", "develop"]
  },
  "tested_at": "2026-05-05T09:00:00.000Z"
}
Field Type Description
git-connection_id string The tested connection (the key is spelled exactly so, hyphenated)
status string success or failed
tests object Five checks forming a ladder — each implies the ones before it: repository_reachable, authentication_valid, branch_exists, write_permission, path_accessible
details.last_commit string | null The branch tip's short hash
details.last_commit_date string | null Date of that commit
details.available_branches array of string Branches of the repository
tested_at string When the test ran

Errors. 404 DF_API.CONNECTION_NOT_FOUND, 403 DF_API.WRITE_ACCESS_DENIED. A failed check is not an error: the response is 200 with status: "failed".