> ## 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.

# My Categories

> Create, edit and delete custom datasets, their columns and their records

<Note>
  **Early Access** - The Dcycle CLI is currently available for enterprise customers.
  [Contact us](/docs/support) to learn more about access.
</Note>

## Overview

**My categories** (elastic data) are datasets your organization defines itself, for operational data that doesn't fit a standard emission category: meter readings, supplier scorecards, customer metrics, anything you track in a spreadsheet today. Each dataset has:

* **Fields** (columns), each with a stable `key`, a visible `name` and a `data_type`.
* **Records** (rows), stored as a JSON object keyed by field `key`.

`dcy elastic` manages all three from the terminal. The command is also available as `dcy categories` and `dcy my-categories`.

<Warning>
  My categories live on the internal `/v2` API, which only accepts a user session. Run `dcy auth login` first: configurations that use an API key (`DCYCLE_API_KEY`) are rejected before any request is sent.
</Warning>

### Available Commands

| Command                                              | Description                                      |
| ---------------------------------------------------- | ------------------------------------------------ |
| `dcy elastic dataset list`                           | List the organization's datasets                 |
| `dcy elastic dataset show <dataset-id>`              | Show a dataset and its fields                    |
| `dcy elastic dataset create`                         | Create an empty dataset                          |
| `dcy elastic dataset edit <dataset-id>`              | Rename a dataset or change its description       |
| `dcy elastic dataset delete <dataset-id>`            | Delete a dataset with all its fields and records |
| `dcy elastic field add <dataset-id>`                 | Add one field (flags) or several (`--file`)      |
| `dcy elastic field edit <dataset-id> <field-id>`     | Edit a field; only the flags you pass change     |
| `dcy elastic field delete <dataset-id> <field-id>`   | Delete a field and its value in every record     |
| `dcy elastic record list <dataset-id>`               | List records, optionally sorted and filtered     |
| `dcy elastic record show <dataset-id> <record-id>`   | Show one record                                  |
| `dcy elastic record create <dataset-id>`             | Create one record (`--data`) or many (`--file`)  |
| `dcy elastic record edit <dataset-id> <record-id>`   | Change some values of a record                   |
| `dcy elastic record delete <dataset-id> <record-id>` | Delete one record                                |

***

## List Datasets

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic dataset list
```

Output:

```
79511472-... | Customer Success Metrics | 248 records
a3c1e9f0-... | Water meters | 36 records
```

## Show a Dataset

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic dataset show 79511472-...
```

Output:

```
Customer Success Metrics
  id:      79511472-...
  fields:
    customer | Customer | text (required) | id 746f1a53-...
    country | Country | select | id 588afbda-...
    amount | Amount MRR | quantity_unit (required) | id 7dc48246-...
    date | Date | date (required) | id 626c4db2-...
    type | Type | select (required) | id 5fa99b2c-...
```

Use `--format json` to get the full schema, including each field's `options` (the allowed values of a `select`, the unit of a `quantity_unit`).

***

## Create a Dataset

A dataset starts empty. Create it, then add its fields:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic dataset create --name "Water meters" --description "Monthly reads per site"
```

### Flags

| Flag            | Short | Default | Description                |
| --------------- | ----- | ------- | -------------------------- |
| `--name`        | —     | —       | **Required.** Dataset name |
| `--description` | —     | —       | Dataset description        |
| `--org`         | —     | —       | Organization ID override   |

`dcy elastic dataset edit <dataset-id>` takes the same flags and changes only the ones you pass.

***

## Add Fields

One field at a time with flags:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic field add <dataset-id> --key site --name Site --type text --required
dcy elastic field add <dataset-id> --key status --name Status --type select \
  --options '{"values":["open","closed"]}'
```

Or several at once from a JSON array that uses the API names (`key`, `name`, `data_type`, `required`, `description`, `options`, `default_value`):

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic field add <dataset-id> --file fields.json
```

```json title="fields.json" theme={"theme":{"light":"github-light","dark":"github-dark"}}
[
  { "key": "site", "name": "Site", "data_type": "text", "required": true },
  { "key": "reading", "name": "Reading", "data_type": "quantity_unit", "options": { "unit": "m3" } },
  { "key": "measured_on", "name": "Measured on", "data_type": "date" }
]
```

### Flags

| Flag            | Short | Default | Description                                                         |
| --------------- | ----- | ------- | ------------------------------------------------------------------- |
| `--key`         | —     | —       | Stable internal key, lowercase snake\_case. Cannot be changed later |
| `--name`        | —     | —       | Visible column label                                                |
| `--type`        | —     | —       | Data type (see below)                                               |
| `--required`    | —     | `false` | Whether a value is mandatory                                        |
| `--description` | —     | —       | Field description                                                   |
| `--options`     | —     | —       | Type-specific config as JSON                                        |
| `--default`     | —     | —       | Default value (raw text)                                            |
| `--file`        | —     | —       | JSON file with an array of fields (`-` for stdin)                   |
| `--org`         | —     | —       | Organization ID override                                            |

<Accordion title="Data types and options">
  | Type            | Value format                        | `--options`                            |
  | --------------- | ----------------------------------- | -------------------------------------- |
  | `text`          | `"Madrid"`                          | —                                      |
  | `integer`       | `42`                                | —                                      |
  | `decimal`       | `12.5`                              | —                                      |
  | `boolean`       | `true`                              | —                                      |
  | `date`          | `"2026-01-31"`                      | —                                      |
  | `datetime`      | `"2026-01-31T10:00:00"`             | —                                      |
  | `select`        | One of the allowed values           | `{"values": ["open", "closed"]}`       |
  | `reference`     | UUID of a record in another dataset | `{"target": "dataset:<dataset-uuid>"}` |
  | `quantity_unit` | `{"value": "12.5", "unit": "kg"}`   | `{"unit": "kg"}`                       |
  | `user`          | A user of the organization          | —                                      |
  | `formula`       | Computed from other fields          | —                                      |
</Accordion>

***

## Edit a Field

Only the flags you pass change. The `key` never changes.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic field edit <dataset-id> <field-id> --name "Site name" --required=false
```

<Note>
  `--type` only works while no record has a value for the field. For a `select` field, `--options` must keep every value already in use. To rename a value, add the new one, move the records, then remove the old one (see [Rename a select value](#rename-a-select-value)).
</Note>

***

## List Records

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic record list <dataset-id> --sort -date --filter 'type:eq:Churn'
```

Output:

```
Showing 36 of 36 records
0009d1cc-... | {"amount":{"unit":"eur","value":"417.0"},"country":"ESP","customer":"Acme","date":"2026-06-17","type":"Churn"}
```

### Flags

| Flag       | Short | Default | Description                                                |
| ---------- | ----- | ------- | ---------------------------------------------------------- |
| `--filter` | —     | —       | `field_key:op:value` clause. Repeatable; clauses are ANDed |
| `--sort`   | —     | —       | Field key to sort by; prefix `-` for descending            |
| `--page`   | —     | `1`     | Page number                                                |
| `--size`   | —     | `50`    | Page size (max 200)                                        |
| `--org`    | —     | —       | Organization ID override                                   |

<Accordion title="Filter syntax (field_key:op:value)">
  | Field type                                           | Operators                                                                 |
  | ---------------------------------------------------- | ------------------------------------------------------------------------- |
  | any                                                  | `eq`, `ne`, `in`, `ni`                                                    |
  | integer / decimal / date / datetime / quantity\_unit | + `gt`, `ge`, `lt`, `le`, `bt` (between), `nb` (not between)              |
  | text / select / reference                            | + `il` (contains, case-insensitive), `lk` (contains), `nl` (not contains) |

  * `bt`/`nb` take a JSON 2-array: `amount:bt:[100,200]`
  * `in`/`ni` take a JSON array: `status:in:["open","late"]`
  * `*:value` searches every field

  A clause on an unknown field, or with an operator the field's type doesn't allow, is **silently ignored**. Check the keys with `dcy elastic dataset show` first.
</Accordion>

***

## Create Records

One record:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic record create <dataset-id> --data '{"site":"Madrid","reading":{"value":"120.5","unit":"m3"}}'
```

Many records from a JSON array (or `--file -` for stdin):

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic record create <dataset-id> --file rows.json
```

Output:

```
created 35, failed 1
  row 12: <the API's validation error for that row>
```

Rows are created one by one, so a bad row doesn't block the rest. The command exits non-zero if any row failed; with `--format json` you get each row's new `id` or its `error`.

***

## Edit a Record

Only the keys you pass change; a key set to `null` clears it.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic record edit <dataset-id> <record-id> --data '{"reading":{"value":"130","unit":"m3"},"note":null}'
```

***

## Delete

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
dcy elastic record delete <dataset-id> <record-id>
dcy elastic field delete <dataset-id> <field-id>
dcy elastic dataset delete <dataset-id>
```

<Warning>
  Deletes are permanent. Deleting a field removes its value from every record; deleting a dataset removes all its fields and records. Each command asks for confirmation unless you pass `--yes` (`-y`).
</Warning>

***

## Typical Workflows

### Load a Dataset from a CSV

Convert the CSV to a JSON array keyed by field key, then create the rows in one call:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
DS=$(dcy elastic dataset create --name "Water meters" --format json | jq -r '.id')
dcy elastic field add "$DS" --file fields.json

jq -R -s 'split("\n") | map(select(length>0) | split(",")) | .[1:]
  | map({site: .[0], reading: {value: .[1], unit: "m3"}, measured_on: .[2]})' readings.csv \
  | dcy elastic record create "$DS" --file -
```

### Rename a Select Value

A `select` field only accepts its listed values, and the list must keep every value in use. To rename `Churn MRR` to `Churn` across a dataset:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
DS=<dataset-id>; FIELD=<field-id>

# 1. Allow both the old and the new value
dcy elastic field edit "$DS" "$FIELD" --options '{"values":["Churn MRR","Churn"]}'

# 2. Move every record to the new value
dcy elastic record list "$DS" --filter 'type:eq:Churn MRR' --size 200 --format json \
  | jq -r '.items[].id' \
  | while read -r id; do
      dcy elastic record edit "$DS" "$id" --data '{"type":"Churn"}'
    done

# 3. Drop the old value
dcy elastic field edit "$DS" "$FIELD" --options '{"values":["Churn"]}'
```

For more than 200 matching records, repeat step 2 until the filter returns nothing.

***

## Aliases

| Command               | Alias                                                             |
| --------------------- | ----------------------------------------------------------------- |
| `dcy elastic`         | `dcy categories`, `dcy my-categories`                             |
| `dcy elastic dataset` | `dcy elastic datasets`, `dcy elastic ds`                          |
| `dcy elastic field`   | `dcy elastic fields`, `dcy elastic column`, `dcy elastic columns` |
| `dcy elastic record`  | `dcy elastic records`, `dcy elastic row`, `dcy elastic rows`      |
| `... list`            | `... ls`                                                          |
| `... delete`          | `... rm`                                                          |

## Limitations

* **User session only.** API keys are not accepted; use `dcy auth login`.
* **No folders or project links.** Organizing datasets into folders and linking them to projects are done in the app.
* **No field type change once the field has values.** Create a new field and move the values instead.

## Next Steps

<CardGroup cols={2}>
  <Card title="MCP Elastic Data Tools" icon="robot" href="/mcp/elastic-data">
    The same operations from an AI assistant
  </Card>

  <Card title="Custom KPIs" icon="chart-bar" href="/mcp/custom-kpis">
    KPI definitions that can be built on your datasets
  </Card>
</CardGroup>
