Modules

A module represents a table in your database. A module includes dimensions, join paths, and metrics, making it the foundation for how data is modeled and explored in Steep.

File structure

Keep yaml files modular by defining one module per file.

YAML

module:
  schema: "steep_demo_fintech"
  table: "customers"
  identifier: "customers"
  description: "Records of customers, including IDs, name, sign-up date."
  dimensions:
    - column: "user_country"
      type: "country"
  joinPaths:
    - from:
        column: "id"
      to:
        table: "transactions"
        column: "customer_id"
      type: "one-to-many"
  metrics:
    - identifier: "registrations"
      name: "Registrations"
      description: "Total number of user sign-ups."
      category: "Marketing"
      type: "count"
      time: "customers.created_at"
      dimensions:
        - "country"

Parameters

ParameterTypeDescriptionRequired
identifierstring
Unique name for the module within the workspace.
Required
schemastring
Name of the database schema.
Required
tablestring
Name of the database table.
Required
labelstring
Display name for the module
Optional
descriptionstring
A short explanation of the table's contents. Helps teams understand what data the module represents.
Optional
dimensionsarray
Array of dimension definitions for this module
Optional
metricsarray
Array of metric definitions for this module
Optional
joinPathsarray
Array of join path definitions to other modules
Optional
accessPoliciesarray
Array of access policy definitions for this module.
Optional

Access policy

An access policy controls which rows each workspace member can access. Access policies are defined on modules and filter data based on user attributes. Read more →

Access policies are defined as a list under accessPolicies within a module. Multiple policies on the same module are combined with AND.

YAML

accessPolicies:
  - column: "account_id"
    attribute: "user.account_id"
  - schema: "steep_demo_fintech"
    table: "transactions"
    column: "country"
    attribute: "user.market"

Parameters

ParameterTypeDescriptionRequired
schemastring
Name of the database schema. Optional if same schema as current module.
Optional
tablestring
Name of the database table. Optional if same table as current module.
Optional
columnstring
The column that contains the row-level information to filter on.
Required
attributestring
The user attribute that will determine how the policy filters data for each member, in user.<name> format.
Required

Dimensions

A dimension represents a column in your database. Dimensions are used for breakdowns and filters. Examples of dimensions are country or segment.

YAML

dimensions:
  - column: "country"
    type: "country"
    label: "Country"
    description: "The country of the customer"
  - column: "email"
    type: "categorical"
    label: "E-mail"
    description: "The customer e-mail address"

Parameters

ParameterTypeDescriptionRequired
columnstring
The name of the database column. The column name acts as the identifier of the dimension and is also used to match report filters. Dimensions can only be defined for string or boolean columns.
Required
labelstring
The display name of the dimension. If not defined, the column name will be used.
Optional
descriptionstring
A short explanation of what the dimension represents. Helps both data teams and business users understand its purpose. (currently not displayed for members)
Optional
typeenum
The dimension type. Possible values: `categorical`, `city`, `country`, `h3-cell-index`, `time`
Required

Join Paths

Join paths let you connect modules so that data from multiple modules can be combined into a single metric.

Define a join path in only one module. Once defined, the join can be used from both sides of the relationship.

Steep can automatically follow join paths up to two steps away.

YAML

This example joins the customers module to the transactions module using the id column on customers and customer_id on transactions.

joinPaths:
  - from:
      column: "id"
    to:
      table: "transactions"
      column: "customer_id"
    type: "one-to-many"

Parameters

ParameterTypeDescriptionRequired
fromobject
A column in the from module (current module) that you want to join from.
Required
toobject
The column in the module that you want to join to.
Required
typeenum
Defines the relationship between the modules. Possible values: `one-to-one`, `one-to-many`
Required

Metrics

A metric is an aggregation or calculation built on top of your modules. It represents key business indicators like order volume, active users, or conversion rate.

Metrics are defined in the module that represents the table that the metric is calculated on. Derived ratio metrics, which are not based on any table, can be defined in any module, but it is recommended to define them in the same module as the numerator metric.

Metric Parameters

ParameterTypeDescriptionRequiredApplies to
identifierstring
Unique metric identifier, used for referencing the metric.
Required
namestring
Display name of the metric.
Required
descriptionstring
Explanation of what the metric measures. Helps data teams and business users understand its purpose.
Optional
dimensionsarray
List of dimension columns available on the metric. Format: `schema.table.column`. schema and table are optional and can be omitted if same as current module. `this.*` can be used to get all dimensions from current module, while `schema.table.*` can be used to get all dimensions from a joined code module.
Optional
categorystring
Metric category. You can add one category.
Optional
owner_emailsarray
Email addresses of one or more metric owners. Must be workspace members.
Optional
is_privateboolean
Whether the metric is private. Defaults to false.
Optional
is_unlistedboolean
Whether the metric is unlisted. Defaults to false.
Optional
time_grainsarray
List of available time grains. Defaults to all time grains.
Optional
time_resamplingenum
Time resampling method. Defaults depends on the calculation type. Possible values: `sum/divide`, `average/repeat`
Optional
slicesarray
One or more slices of the metric.
Optional
filtersarray
One or more filters applied to the metric.
Optional
typeenum
Metric type. Possible values: `derived-ratio`, `sum`, `ratio`, `count`, `count-distinct`, `custom-value`, `custom-ratio`
Required
numeratorstring
For ratio metrics, the column used for ratio calculations in the format: `table.column`. For derived ratio metrics, the identifier of the metric used as the numerator.
Requiredderived-ratio, ratio
denominatorstring
For ratio metrics, the column used for ratio calculations in the format: `table.column`. For derived ratio metrics, the identifier of the metric used as the denominator.
Requiredderived-ratio, ratio
formatstring
Format of a ratio metric. Defaults to 'percentage'.
Optionalderived-ratio, ratio, custom-ratio
timestring
Column used to analyze the metric over time. Format: `table.column`. You can add only one time column.
Requiredsum, ratio, count, count-distinct, custom-value, custom-ratio
valuestring
Column used for sum calculations. Format: `table.column`.
Requiredsum
distinct_onstring
Column to count distinct values on. Format: `table.column`.
Requiredcount-distinct
sql_expressionstring
SQL expression that returns the metric value. Columns mentioned in expression should be of format table.column.
Requiredcustom-value
numerator_sqlstring
SQL expression for the ratio numerator. Columns mentioned in expression should be of format table.column.
Requiredcustom-ratio
denominator_sqlstring
SQL expression for the ratio denominator. Columns mentioned in expression should be of format table.column.
Requiredcustom-ratio

Slice Parameters

ParameterTypeDescriptionRequired
namestring
Name of the metric slice.
Required
filterobject
Filter applied to the metric slice.
Required

Filter Parameters

ParameterTypeDescriptionRequired
schemastring
Name of the database schema. Optional if same schema as current module.
Optional
tablestring
Name of the database table. Optional if same table as current module.
Optional
columnstring
Name of the database column.
Required
operatorenum
The operator to use for the filter. Possible values: `equals`, `not-equals`, `less-than`, `less-than-or-equal`, `greater-than`, `greater-than-or-equal`, `in`, `not-in`, `is`, `is-not`, `like`, `not-like`
Required
expressionstring
The expression to use for the filter.
Required

Metric examples

Example yaml code for different metric types.

Sum

metrics:
  - identifier: "order_vol"
    name: "Order volume"
    description: "Total sum of order value."
    category: "Operations"
    type: "sum"
    time: "orders.created_at"
    value: "orders.amount"
    owner_emails:
      - "vitor@company.com"
      - "ebba@company.com"
    is_private: true
    is_unlisted: true
    time_grains:
      - "weekly"
      - "monthly"
    filters:
      - column: "country"
        operator: "not-equals"
        expression: "test_country"
    slices:
      - name: "US"
        filter:
          column: "country"
          operator: "equals"
          expression: "US"
    dimensions:
      - "this.*"

Count

metrics:
  - identifier: "orders"
    name: "Orders"
    description: "Number of orders."
    category: "Operations"
    type: "count"
    time: "orders.created_at"
    owner_emails:
      - "vitor@company.com"
      - "ebba@company.com"
    filters:
      - column: "country"
        operator: "not-equals"
        expression: "test_country"
    dimensions:
      - "this.*"

Ratio

metrics:
  - identifier: "conversion_rate"
    name: "Conversion rate"
    description: "Conversion rate measures the percentage of users who sign-up."
    type: "ratio"
    time: "site.visit_at"
    numerator: "site.conversions"
    denominator: "site.visits"
    format: "percentage"
    dimensions:
      - "this.*"

Unique count

metrics:
  - identifier: "active_users"
    name: "Active users"
    description: "A user is considered active when they've made a transaction during the period"
    type: "count-distinct"
    time: "transactions.created_at"
    distinct_on: "customers.customer_id"
    dimensions:
      - "this.*"

Custom Value

metrics:
  - identifier: "partner_orders"
    name: "Partner orders"
    description: "Orders coming in through partner."
    type: "custom-value"
    time: "orders.created_at"
    sql_expression: "SUM(CASE WHEN customers.type = 'partner' THEN orders.order_volume END)"
    dimensions:
      - "this.*"

Custom Ratio

metrics:
  - identifier: "kyc_approved"
    name: "KYC Approved %"
    description: "Percentage of users approved through KYC processes. KYC stands for 'Know Your Customer': used to verify a customer's identity and assess risk, helping prevent fraud and financial crimes."
    type: "custom-ratio"
    time: "customers.created_at"
    numerator_sql: "SUM(CASE WHEN customers.country != 'SE' THEN 1 END)"
    denominator_sql: "COUNT(*)"
    format: "percentage"
    dimensions:
      - "this.*"

Derived Ratio

metrics:
  - identifier: "orders_per_active_user"
    name: "Orders per Active User"
    description: "Number of orders per active customer"
    category: "Commercial"
    numerator: "orders"
    denominator: "active_customers"
    type: "derived-ratio"
    format: "number"
    dimensions:
      - "this.*"