Celiq
v0.12Open app โ†—
Docs/Developer/CML reference

CML reference

Complete reference for every CML field โ€” node, dimension, measure, domain, data_keys, data_gates, and locale blocks.

WeaverReferenceUpdated May 2026 ยท 15 min read
โœฆ
In this section
You rarely need to write CML by hand โ€” Orion generates it. Use this reference when customising field types, measures, or joins.

CML (Celiq Modelling Language) is the YAML-based language for defining your semantic layer. Every node, domain, join, security rule, and locale setting is written in CML and version-controlled in Forge.

This page is a complete reference. For a conceptual introduction, see Key concepts.

node fields

The top-level block for a single table mapping.

yaml
node: <identifier>
  label: <string>
  description: <string>
  sql_table: <schema.table>
  connection: <connection_name>
  tags: [<tag>, ...]
  primary_key: <dimension_identifier>
FieldTypeRequiredDescription
nodeidentifierYesUnique identifier for this node. Snake case. Used in domain join references.
labelstringYesHuman-readable name shown in Discover.
descriptionstringNoShown in Discover field picker and search. Markdown supported.
sql_tablestringYesThe fully-qualified table name. Use schema.table format. Required unless sql_derived_table is set.
sql_derived_tablestringNoA SQL subquery that defines the table. Use instead of sql_table for derived tables.
connectionstringNoThe name of the data connection to use. Defaults to workspace default if omitted.
tagsstring[]NoArbitrary tags for organising nodes in Forge. Not visible in Discover.
primary_keyidentifierNoThe dimension that uniquely identifies a row. Used for deduplication in certain join types.

dimension fields

Dimensions are categorical or temporal fields used for grouping and filtering.

yaml
dimension: <identifier>
  type: string | number | date | datetime | boolean | location
  label: <string>
  description: <string>
  sql: <sql_expression>
  primary_key: true | false
  hidden: true | false
  tags: [<tag>, ...]
  data_gate: true | false
  gate_behavior: restrict | hide
  group_label: <string>
  format: <format_string>
  case_sensitive: true | false
FieldTypeRequiredDescription
dimensionidentifierYesUnique identifier within the node.
typeenumYesData type. string, number, date, datetime, boolean, location.
labelstringYesHuman-readable name in Discover.
descriptionstringNoShown in field picker tooltip.
sqlstringYesSQL expression for the field. Use ${TABLE}.column_name for direct column references.
primary_keybooleanNoMarks this as the node's primary key. Defaults to false.
hiddenbooleanNoHides the field from Discover. Still usable in measures and joins. Defaults to false.
data_gatebooleanNoEnables field-level security. Access managed in Admin Console. Defaults to false.
gate_behaviorenumNorestrict (show badge, block query) or hide (field invisible). Defaults to restrict.
group_labelstringNoGroups related dimensions under a collapsible heading in Discover.
formatstringNoDisplay format for number and date types. E.g. "$#,##0.00", "YYYY-MM-DD".

Dimension type: date

Date dimensions support automatic granularity groups (year, quarter, month, week, day). Celiq generates these sub-fields automatically when type: date or type: datetime is set.

yaml
dimension: created_at
  type: date
  label: Created At
  sql: ${TABLE}.created_at
  granularities: [day, week, month, quarter, year]   # Default: all five

measure fields

Measures are aggregated calculations exposed in Discover as metrics.

yaml
measure: <identifier>
  type: count | count_distinct | sum | average | min | max | percent_of_total | custom
  label: <string>
  description: <string>
  sql: <sql_expression>
  filters:
    - dimension: <identifier>
      value: <value>
  format: number | currency | percent | <custom_format>
  hidden: true | false
  data_gate: true | false
  gate_behavior: restrict | hide
  tags: [<tag>, ...]
FieldTypeRequiredDescription
measureidentifierYesUnique identifier within the node.
typeenumYesAggregation type.
labelstringYesHuman-readable name.
sqlstringYesSQL expression for the field. Not required for count.
filterslistNoOptional WHERE conditions applied only to this measure.
formatstringNoDisplay format. currency, percent, number, or a custom format string.

Measure types

TypeSQL equivalentsql field required
countCOUNT(*)No
count_distinctCOUNT(DISTINCT ${sql})Yes
sumSUM(${sql})Yes
averageAVG(${sql})Yes
minMIN(${sql})Yes
maxMAX(${sql})Yes
percent_of_totalSUM / SUM OVER ()Yes
customRaw SQL expressionYes

domain fields

Domains join multiple nodes together and define query entry points.

yaml
domain: <identifier>
  label: <string>
  description: <string>
  base_node: <node_identifier>
  joins:
    - node: <node_identifier>
      type: left_outer | full_outer | inner | cross
      sql_on: <join_condition>
      relationship: one_to_one | one_to_many | many_to_one | many_to_many
FieldTypeRequiredDescription
domainidentifierYesUnique identifier.
labelstringYesShown in the Discover node picker.
base_nodeidentifierYesThe primary node that defines the cardinality of the query.
joinslistNoAdditional nodes to join.

Join fields

FieldTypeRequiredDescription
nodeidentifierYesThe node to join.
typeenumYesJoin type: left_outer, full_outer, inner, cross.
sql_onstringYesThe join condition. Use ${node.dimension} syntax.
relationshipenumYesCardinality. Affects fan-out detection and measure correctness.

data_keys block

Row-level security. See the full guide at Data Keys.

yaml
data_keys:
  - key: <key_name>
    dimension: <dimension_identifier>
    null_behavior: deny | allow_all | deny_with_message
    message: <string>
FieldTypeRequiredDescription
keystringYesThe attribute name used for assignments in Admin Console.
dimensionidentifierYesThe dimension to filter on. Must be defined in this node.
null_behaviorenumNoWhat to do when a user has no assignment. Default: deny.
messagestringNoCustom message shown when null_behavior: deny_with_message.

locale block

Controls how a dimension's values are displayed in different languages.

yaml
dimension: status
  type: string
  label: Status
  sql: ${TABLE}.status
  locale:
    en: { "active": "Active", "inactive": "Inactive" }
    fr: { "active": "Actif", "inactive": "Inactif" }
    de: { "active": "Aktiv", "inactive": "Inaktiv" }

Locale mappings translate raw database values into display labels based on the user's language setting.