> ## Documentation Index
> Fetch the complete documentation index at: https://code.dcycle.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Dataset Schema

> Describe the dimensions, metrics and temporal behaviour of one dataset before querying it

Return what a dataset can be grouped by and what it can measure. [Query datasets](/api-reference/datasets/query) accepts only the dimension and metric keys listed here, so this is the contract to build a query against rather than guessing field names.

The same native key can return **different dimensions for different organizations**: the schema is extended with the custom columns your organization defined on that entity. Fetch it per organization; do not cache one organization's schema and reuse it for another.

On `emissions`, those custom columns come from **every table an emission row comes from**, prefixed by that source so two sources never share a key: `custom_consumption_<key>` (vehicle consumptions), `custom_invoice_<key>`, `custom_waste_<key>`, `custom_purchase_<key>`, `custom_business_travel_<key>`, `custom_hotel_stay_<key>`, `custom_wastewater_<key>`, `custom_commuting_<key>`, plus `custom_vehicles_<key>` and `custom_facilities_<key>`. They are always dimensions — an emission row is a day-by-gas slice of its source, so a number from the source (or from the record a relation points at) is never summed.

When your organization links a source that has no facility of its own to a facility with a relation column (a vehicle consumption's "Facility", a business trip's "Sede"), `facility` on `emissions` becomes the facility each row **belongs to**: its own facility when it has one, otherwise the one the relation assigns. The facility's other columns (`country`, `facilities__*`, `custom_facilities_*`) follow it. The most specific source wins for each row: its own facility first, then a relation on the row's source (a consumption's "Facility", which is where the vehicle was that day), then one on its vehicle, which only fills the consumptions that say nothing. So adding a relation, or leaving a new one empty, never moves a row away from the facility it had. If two facility columns on the same record point at different facilities, neither is used for that record (its vehicle's relation, if any, still applies). Without such a relation, `facility` keeps its meaning.

## Request

### Headers

<ParamField header="x-api-key" type="string" required>
  Your API key for authentication

  **Example:** `sk_live_1234567890abcdef`
</ParamField>

<ParamField header="x-organization-id" type="string" required>
  Your organization UUID

  **Example:** `a8315ef3-dd50-43f8-b7ce-d839e68d51fa`
</ParamField>

### Path Parameters

<ParamField path="key" type="string" required>
  Dataset key from [List Available Datasets](/api-reference/datasets/list) — a catalogue key, or `elastic:<uuid>` for a custom dataset

  **Example:** `own_workforce_remuneration`
</ParamField>

### Query Parameters

<ParamField query="framework" type="string">
  Narrow the dataset to a reporting taxonomy. It only affects datasets with framework-specific dimensions — notably `emissions` — and is a no-op elsewhere.
</ParamField>

## Response

<ResponseField name="key" type="string">
  Echo of the dataset key
</ResponseField>

<ResponseField name="label_key" type="string">
  i18n key for native datasets; the user's literal name for custom ones
</ResponseField>

<ResponseField name="kind" type="string">
  `kpi`, `activity`, `master`, `custom` or `custom_kpi`
</ResponseField>

<ResponseField name="dimensions" type="array[object]">
  <Expandable title="dimension">
    <ResponseField name="key" type="string">
      What to send in the query's `dimensions`
    </ResponseField>

    <ResponseField name="label_key" type="string">
      i18n key for the dimension name
    </ResponseField>

    <ResponseField name="field_type" type="string">
      `string`, `number`, `date`, …
    </ResponseField>

    <ResponseField name="group" type="string">
      Which entity the dimension comes from, for grouping in a picker
    </ResponseField>

    <ResponseField name="i18n_namespace" type="string | null">
      When set, the dimension's **values** are translation keys in this namespace — `gender` and `accident_context` are the workforce examples. Translate the values, not just the label.
    </ResponseField>

    <ResponseField name="relation_label" type="string | null">
      Set when the dimension is borrowed through a relation column
    </ResponseField>

    <ResponseField name="via" type="string | null">
      The relation column it was borrowed through. Advisory — the query accepts every listed dimension regardless.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="metrics" type="array[object]">
  <Expandable title="metric">
    <ResponseField name="key" type="string">
      What to send in the query's `metrics`
    </ResponseField>

    <ResponseField name="label_key" type="string">
      i18n key for the metric name
    </ResponseField>

    <ResponseField name="agg" type="string">
      How the value is aggregated across rows.

      Read it together with `row_level`. When `row_level` is `false` the metric's expression is **already** an aggregate — a count, a ratio, a wage gap — and `agg` carries its default `sum` without being applied. That is why `remuneration_avg` and `wage_gap` both report `"agg": "sum"` in the example below: the field describes the engine's aggregation step, not the metric's meaning, and for these two there is no such step.
    </ResponseField>

    <ResponseField name="decimals" type="integer">
      Suggested precision for display
    </ResponseField>

    <ResponseField name="suffix" type="string | null">
      Unit to render after the value — `h`, `%`, `t CO₂e`
    </ResponseField>

    <ResponseField name="grouping_hint_key" type="string | null">
      Dimension the metric is most meaningful grouped by
    </ResponseField>

    <ResponseField name="row_level" type="boolean">
      `false` when the metric is already an aggregate — a count, a ratio, a gap. A row-mode formula over such a metric is rejected with 400.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="default_metrics" type="array[string]">
  Metrics to preselect when nothing is chosen
</ResponseField>

<ResponseField name="window_required" type="boolean">
  `true` for native KPI and activity datasets: the query's start/end window is mandatory and drives proration. `false` for master and custom datasets, where the window is optional or ignored.
</ResponseField>

<ResponseField name="time_axis_default" type="string | null">
  The dimension that seeds the period axis
</ResponseField>

<ResponseField name="data_version" type="integer | null">
  Custom datasets only: incremented on every write, so it works as a cache key. Null for native datasets.
</ResponseField>

<Note>
  Every dataset with a date column also exposes a synthetic `period` dimension that is not part of its stored fields. It is how you group by month, quarter or year.
</Note>

## Reading the workforce schemas

`own_workforce_remuneration` is the one worth knowing in detail. Its time axis is **annual** — one row per employee per fiscal year — and its `wage_gap` metric has three traps worth repeating from [Query datasets](/api-reference/datasets/query):

* it is an FTE-weighted mean, not a simple average of salaries;
* the sign is positive when men earn more, since it is computed as `(avg_M − avg_F) / avg_M × 100`;
* it returns **null**, not `0`, for any group that lacks at least one man and one woman. Null is "not computable here", and it is not summable or averageable across groups — ask the server for subtotals instead of aggregating the numbers yourself.

It also carries fewer dimensions than `own_workforce_contracts`: organization, country, nationality, gender, job category, age and period, with no contract type, workday type, disability or labour-agreement split.

## Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X GET "https://api.dcycle.io/v1/datasets/own_workforce_remuneration/schema" \
    -H "x-api-key: ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}"
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import os

  import requests

  headers = {
      "x-api-key": os.getenv("DCYCLE_API_KEY"),
      "x-organization-id": os.getenv("DCYCLE_ORG_ID"),
  }

  schema = requests.get(
      "https://api.dcycle.io/v1/datasets/own_workforce_remuneration/schema",
      headers=headers,
  ).json()

  print("group by:", [d["key"] for d in schema["dimensions"]])
  print("measure:", [m["key"] for m in schema["metrics"]])
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const axios = require('axios');

  const headers = {
    'x-api-key': process.env.DCYCLE_API_KEY,
    'x-organization-id': process.env.DCYCLE_ORG_ID
  };

  axios.get('https://api.dcycle.io/v1/datasets/own_workforce_remuneration/schema', { headers })
    .then(({ data }) => {
      console.log('group by:', data.dimensions.map(d => d.key));
      console.log('measure:', data.metrics.map(m => m.key));
    })
    .catch(error => console.error(error));
  ```
</CodeGroup>

### Successful Response

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "key": "own_workforce_remuneration",
  "label_key": "datasets.own_workforce_remuneration.label",
  "kind": "activity",
  "dimensions": [
    { "key": "organization", "label_key": "datasets.dim.organization", "field_type": "string", "group": "own_workforce_remuneration", "i18n_namespace": null },
    { "key": "gender", "label_key": "datasets.dim.gender", "field_type": "string", "group": "own_workforce_remuneration", "i18n_namespace": "customDashboard.pivotTable.values.gender" },
    { "key": "job_category", "label_key": "datasets.dim.job_category", "field_type": "string", "group": "own_workforce_remuneration", "i18n_namespace": null },
    { "key": "age", "label_key": "datasets.dim.age", "field_type": "number", "group": "own_workforce_remuneration", "i18n_namespace": null },
    { "key": "period", "label_key": "datasets.dim.period", "field_type": "date", "group": "own_workforce_remuneration", "i18n_namespace": null }
  ],
  "metrics": [
    { "key": "remuneration_avg", "label_key": "datasets.own_workforce_remuneration.metric.remuneration_avg", "agg": "sum", "decimals": 2, "suffix": null, "row_level": false },
    { "key": "wage_gap", "label_key": "datasets.own_workforce_remuneration.metric.wage_gap", "agg": "sum", "decimals": 2, "suffix": "%", "row_level": false }
  ],
  "default_metrics": ["remuneration_avg"],
  "window_required": true,
  "time_axis_default": "year",
  "data_version": null
}
```

## Common Errors

### 401 Unauthorized

**Cause:** the key is invalid, or it does not belong to the organization in `x-organization-id` — the two are looked up as a pair. A request carrying no credentials at all answers `AUTH_REQUIRED` instead.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": "Invalid API key for organization",
  "code": "INVALID_API_KEY"
}
```

### 404 Not Found

**Cause:** unknown key, or a custom dataset belonging to another organization.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": "Unknown dataset 'own_workforce_salaries'."
}
```

## Related Endpoints

<CardGroup cols={2}>
  <Card title="List available datasets" icon="list" href="/api-reference/datasets/list">
    Where the key comes from
  </Card>

  <Card title="Query datasets" icon="chart-simple" href="/api-reference/datasets/query">
    Run the aggregation
  </Card>
</CardGroup>

## Organization hierarchy capability

`organization_hierarchy_supported` indicates whether the dataset can return recalculated holding rows when `organization` is the first dimension and `nest_organization_by_hierarchy` is enabled. Consumers should show the hierarchy control only when this capability is true. The default is false for older servers and unsupported dataset definitions.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.