Skip to content
Get started

Getting started

This guide walks you through your first hour with Grunddata. By the end you will have a working model with two tables, a lookup relationship between them, validation rules, a view for reporting, and real records — created and versioned by a commit.

We will build a small Accounting domain:

Table What it holds Purpose
Currency A short, fixed list of allowed currencies A lookup (domain table)
Accounts The chart of accounts The main data table
  1. Sign in. Open the Grunddata web app and sign in with your organisation account. Grunddata uses Microsoft Entra ID, so this is the same account you use for Microsoft 365.

  2. Find your way around. The top navigation has five entries:

    • Dashboard — your recently used tables.
    • Models — the top level grouping. This is where most work starts.
    • Tables — every table across all models, in one flat list.
    • Views — the stable contracts you expose to OData clients.
    • Auth — group based access control.

A model is a container. It groups related tables together, like a folder groups files or a workbook groups sheets. It holds nothing but a name, a description and tags.

  1. Go to Models and click Create New Model.

  2. Fill in the fields:

    Field Value Required
    Name Accounting Yes
    Description Chart of accounts and supporting lookups No
    Tags finance No
  3. Click Create.

Grunddata assigns the model a source_id — a UUID that identifies it forever, even if you rename it later. See Identifiers.


Step 2 — Create a domain table (the lookup)

Section titled “Step 2 — Create a domain table (the lookup)”

We will create Currency first, because Accounts is going to point at it.

A domain table is an ordinary table that is used as a lookup. What makes it usable as a lookup is one setting: Code generation = MANUAL.

  1. Open the Accounting model and click Create Table.

  2. Fill in:

    Field Value
    Name Currency
    Description Allowed currencies
    Code generation MANUAL
    Tags finance
  3. Click Create.

Now add the currencies. Open the table and use Add Record:

Code Name
SEK Swedish krona
EUR Euro
USD US dollar
GBP Pound sterling

  1. Back in the Accounting model, click Create Table again.

  2. Fill in:

    Field Value
    Name Accounts
    Description Chart of accounts
    Code generation AUTO
  3. Click Create.

We choose AUTO here because nothing else will look up an account by a hand-typed code — Accounts is a data table, not a lookup.


Attributes are the columns of your table. Open Accounts and click Attributes, then Add attribute.

Create these four:

Name Datatype Required Unique Notes
account_number string, max length 10 Yes Yes The natural key
account_name string, max length 120 Yes No
opened_on date No No
currency (domain table) Yes No Points at the Currency table

For currency, instead of choosing a datatype, pick the domain table model (Accounting) and the domain table (Currency). The datatype field becomes read-only — it is determined by the referenced table.

Full details in Attributes.


Attribute properties like required and max length handle the basics. Validations handle the business rules. They are expressed as JSON Schema, but the web app builds the schema for you from a form.

Open the account_number attribute and add a validation. For a string attribute you can choose:

Rule Meaning
Starts with The value must begin with a given prefix
Ends with The value must end with a given suffix
Min length Minimum number of characters
Regex pattern The value must match a regular expression
One of (list) The value must be one of an explicit list

For numeric attributes (integer, decimal) you get:

Rule Meaning
Number comparison Greater/less than a fixed value
Multiple of The value must be a multiple of a number
One of (list) The value must be one of an explicit list

Add a Regex pattern of ^[1-9][0-9]{3}$ to account_number so only four-digit account numbers are accepted.

Open the Accounts table and use Validation to compare two attributes against each other. For example, on a table with valid_from and valid_to you could require valid_to > valid_from.

More in Validations.


Now put data in. Open Accounts and click Add Record.

Best for one or two rows. Type the values, use the magnifying glass next to currency to search the Currency domain table, and save. The Code and Name fields are only shown when the table is MANUAL.

Add a few accounts:

account_number account_name opened_on currency
1200 Nominal amount 2024-01-01 SEK — Swedish krona
1300 Market value adjustment 2024-01-01 SEK — Swedish krona
1400 Interest rate 2024-01-01 EUR — Euro

Step 7 — Understand what just happened: commits

Section titled “Step 7 — Understand what just happened: commits”

Every save — one row in the web app or five thousand from Excel — is wrapped in a commit. A commit records:

  • Who made the change.
  • When.
  • A commit message.
  • Every record version it produced.

Records are never overwritten. Saving a row appends a new version with version + 1, and deleting a row appends a version flagged as deleted. The full trail stays.

Open the table overview and you will see the most recent commits listed with author and timestamp.

Read more in Commits and versions.


Your data is now clean and governed. The last step is publishing it in a shape that downstream tools can rely on.

A view is a named, stable contract over a table. It decides exactly which fields are exposed over OData and what they are called — so you can rename an attribute internally without breaking a Power BI report.

  1. Go to Views and click Create View.

  2. Choose model Accounting and table Accounts. Name it AccountsView.

  3. Tick the fields to expose. For the currency domain attribute you get three separate fields to choose from:

    • CurrencySourceId — the referenced record’s UUID
    • CurrencyCode — the referenced record’s Code (SEK)
    • CurrencyName — the referenced record’s Name (Swedish krona)
  4. Click Create.

Your view is now available in Excel, Power Query and Power BI at /odata/AccountsView. See OData API.


  1. Created a model to group things.
  2. Created a MANUAL domain table to serve as a lookup.
  3. Created an AUTO data table for the real data.
  4. Added attributes, including one pointing at the domain table.
  5. Added validations so bad values are rejected.
  6. Added records, each stored with a resolved reference rather than free text.
  7. Saw how every change becomes a commit and a new record version.
  8. Published a view for downstream consumption.