# AGENTS.md - Luzmo Developer Documentation

> Instructions for AI coding assistants working with Luzmo embedded analytics integration.

## Overview

Luzmo is an embedded analytics platform. This file provides context for AI coding assistants to help developers integrate Luzmo into their applications.
ALWAYS fetch `https://developer.luzmo.com/llms.txt` to get the latest details about the Luzmo APIs and SDKs. For a complete index of all documentation pages in markdown format (guides, API operations, Flex charts) with descriptions to match user queries, fetch `https://developer.luzmo.com/llms-full.txt`. Where possible, fetch "https://developer.luzmo.com" pages with the '.md' suffix for a markdown version of the page.

**Basic embedding setup:**

- Server-side: use your Luzmo API key + token to call the Authorization API and generate an embed key-token pair for a logged-in end-user in your application (returns `id` and `token`).
- Client-side: use this embed key-token to embed a dashboard, chart, Flex component, or Luzmo IQ component.

## Critical Security Rules

1. **NEVER expose API keys/tokens in client-side code**
   - Backend SDKs (Node.js, Python, PHP, Java, C#) must run server-side only
   - For frontend access, generate short-lived embed tokens server-side via the [Authorization API](https://developer.luzmo.com/api/createAuthorization.md)

2. **Always use embed tokens for frontend**
   - Generate embed token server-side, pass through in `authKey` and `authToken` to frontend components
   - Specific Luzmo APIs can be called in the frontend using the embed key-token pair, which will take the token's properties into account (e.g. `data` for querying data, `securable` for creating/fetching a dashboard or dataset, etc.)

## IMPORTANT: Always Fetch Documentation Before Implementing

Before writing any Luzmo integration code, you MUST fetch and review the relevant documentation files. Do not rely on cached knowledge - always get the latest documentation (use `https://developer.luzmo.com/llms.txt` or `https://developer.luzmo.com/llms-full.txt` if unclear what's available/necessary to check — llms-full.txt lists every doc page with descriptions for discovery).

### Documentation retrieval rules

1. **Follow linked resources** — If a fetched page links to more specific Dev Docs markdown or JSON schema URLs directly relevant to your task, fetch those **before** implementing. General guides are not sufficient when the page links to chart-specific schemas or API operation docs.
2. **Do not re-fetch** — Track URLs already fetched in the current task; do not fetch them again unless you need to re-verify.
3. **Stay on-task** — Do not follow unrelated links (other chart types, unrelated APIs, marketing pages) unless the user's task requires them.

### 1. Core API Resources

When working with any Luzmo API resource, fetch the markdown documentation for that resource's actions:

**URL Pattern:** `https://developer.luzmo.com/api/{action}{Resource}.md`

Examples:
- Authorization: `https://developer.luzmo.com/api/createAuthorization.md`
- Dashboard operations: `https://developer.luzmo.com/api/createDashboard.md`, `https://developer.luzmo.com/api/searchDashboard.md`
- Dataset operations: `https://developer.luzmo.com/api/createDataset.md`, `https://developer.luzmo.com/api/searchDataset.md`
- Data queries: `https://developer.luzmo.com/api/createData.md`
- Themes: `https://developer.luzmo.com/api/createTheme.md`, `https://developer.luzmo.com/api/searchTheme.md`

Full API overview: `https://developer.luzmo.com/guide/api--overview.md`

### 2. Frontend Component References

When embedding dashboards, Flex charts, or IQ components, fetch the component API reference:

| Component | API Reference URL |
|-----------|-------------------|
| Dashboard | `https://developer.luzmo.com/guide/embedding--component-api-reference.md` |
| Flex | `https://developer.luzmo.com/guide/flex--component-api-reference.md` |
| IQ Chat | `https://developer.luzmo.com/guide/iq--chat-component-api.md` |
| IQ Answer | `https://developer.luzmo.com/guide/iq--answer-component-api.md` |

### 3. Flex Chart Configuration

When configuring Flex charts, follow this discovery path in order—do not skip steps or stop at general Flex docs:

1. This file (`AGENTS.md`) — security, sizing, slot/option conventions
2. If chart type is unclear: `https://developer.luzmo.com/guide/flex--chart-docs.md`
3. Chart type page: `https://developer.luzmo.com/flex/charts/{chart-type}.md`
4. **Schemas** — From **Schema Reference** on step 3, fetch only the schema URLs listed there (do not assume `{chart-type}-slots.schema.json` exists for every item type):
   - **Slots schema** — fetch only when a **Slots Schema** link is present and the resource is available. If absent or unavailable (e.g. options-only items such as `text`, `image`, `video`), use slot/config details from the chart page instead.
   - **Options schema** — fetch when an **Options Schema** link is present.

Slots and options differ per chart type—never infer them from another chart or from general Flex docs alone.

**URL Pattern:** `https://developer.luzmo.com/flex/charts/{chart-type}.md`

Examples:
- Bar chart: `https://developer.luzmo.com/flex/charts/bar-chart.md`
- Line chart: `https://developer.luzmo.com/flex/charts/line-chart.md`
- Donut chart: `https://developer.luzmo.com/flex/charts/donut-chart.md`
- Regular table: `https://developer.luzmo.com/flex/charts/regular-table.md`
- Date filter: `https://developer.luzmo.com/flex/charts/date-filter.md`
All available chart types: `https://developer.luzmo.com/guide/flex--chart-docs.md`

Each chart documentation includes:
- Available **options** (appearance, behavior, formatting)
- Required and optional **slots** (dimensions, measures, categories)
- Slot-specific configurations (aggregation functions, datetime levels, etc.)

### 4. Analytics Components Kit (ACK)

When building chart configuration interfaces, use the Analytics Components Kit (ACK) components. ALWAYS fetch the ACK documentation first. ACK is used to configure charts (e.g. slots, options, filters); Flex items and ACK Grid can both be used to render them.

**Core ACK guides:**
- Overview: `https://developer.luzmo.com/guide/ack--overview.md`
- Patterns: `https://developer.luzmo.com/guide/ack--patterns.md`
- Utilities: `https://developer.luzmo.com/guide/ack--utilities.md`
- Item definitions: `https://developer.luzmo.com/guide/ack--item-definitions.md`

**ACK component references:**
- Data fields: `https://developer.luzmo.com/guide/ack--components--data-fields.md`
- Item data slots: `https://developer.luzmo.com/guide/ack--components--data-slots.md`
- Item data pickers: `https://developer.luzmo.com/guide/ack--components--data-picker.md`
- Item options: `https://developer.luzmo.com/guide/ack--components--item-options.md`
- Filters: `https://developer.luzmo.com/guide/ack--components--filters--luzmo-filters.md`
- Chart rendering: 
  - Single chart: `https://developer.luzmo.com/guide/ack--components--chart-rendering--luzmo-embed-viz-item.md`
  - Multi-chart grid: `https://developer.luzmo.com/guide/ack--components--chart-rendering--luzmo-item-grid.md`

**Key ACK rules:**
- Install ACK from `@luzmo/analytics-components-kit`
- ACK components are web components that produce chart configuration state (`slotsContents`, `options`, `filters`)
- Your application must own that state and pass it into Luzmo Embed for rendering
- Components that fetch Luzmo data require `authKey` / `authToken` (or `auth-key` / `auth-token` in HTML) - ALWAYS use server-side generated Embed tokens for these components.
- Keep ACK `item-type` aligned with the rendered Flex chart `type`

### CRITICAL: Luzmo API design

**The Luzmo API does NOT use traditional REST HTTP verbs.**
- All operations use **POST** requests
- The operation is specified via an `action` field in the request body
- Do NOT generate GET, PUT, PATCH, or DELETE HTTP requests
The SDKs abstract this - just call `client.create()`, `client.get()`, etc.

### API Base URLs

Depending on the tenancy of your Luzmo account, use one of the following base URLs:

| Region | Base URL |
|--------|----------|
| EU (Default) | `https://api.luzmo.com/0.1.0` |
| US | `https://api.us.luzmo.com/0.1.0` |
| VPC | `https://{vpc}-api.luzmo.com/0.1.0` (or a custom CNAME) |

## Environment Variables

Use environment variables to store your Luzmo app details and API credentials.

```
LUZMO_APP_SERVER=https://app.luzmo.com
LUZMO_API_HOST=https://api.luzmo.com
LUZMO_API_KEY=<your-api-key>
LUZMO_API_TOKEN=<your-api-token>
```

## Guidelines & Gotchya's (CRITICAL)

### Flex SDK

#### Component Names
- In vanilla TypeScript/JavaScript, use `<luzmo-embed-viz-item>` (NOT `<luzmo-viz-item>`). 
  - Same for the IQ components, use `<luzmo-iq-embed-chat>` and `<luzmo-iq-embed-answer>` (NOT `<luzmo-iq-chat>` and `<luzmo-iq-answer>`).
- ACK components come from `@luzmo/analytics-components-kit` and are used for configuration UIs, not rendering.
- All component properties use camelCase (e.g. `apiHost`, `appServer`, `authKey`, `authToken`, `dashboardId`, etc.)
- Framework-specific components (React, Angular, Vue) have their own naming conventions documented in their respective guides

#### Dashboard Sizing
- Dashboards will have a variable height depending on the dashboard content; if deemed necessary in the design, add an `overflow-y: auto` to the container element.
- Dashboards will automatically fill the available width of the container they are embedded in, depending on the screen modes configured in the dashboard. If it's not fully filling the container, recommend to check if the "largeScreen" screen mode is configured in the dashboard.

#### Flex Charts Sizing
- Flex Charts require explicit dimensions to render. Set `height` and `width` on BOTH the container element AND the chart component
- Without defined dimensions, the chart renders with 0 height and is invisible
- Example: `<div style="height: 400px; width: 100%;"><luzmo-embed-viz-item style="height: 100%; width: 100%;"></luzmo-embed-viz-item></div>`

#### Context ID
- Each `contextId` must be unique across all chart instances on the page
- Reusing the same `contextId` causes conflicts and unexpected behavior

#### ACK State Flow
- ACK emits configuration changes; your application should store and own that state
- Persist `slotsContents`, `options`, and `filters` in app state, then pass them into the rendering component
- When users switch chart types, keep ACK `item-type` and the rendered chart `type` in sync
- For custom editors, use `loadDataFieldsForDatasets` to fetch component-ready dataset fields and `switchItem` to remap slots between chart types

### Chart Options

#### Always Check the Schema
- Before configuring chart options, always reference the JSON schema for that specific chart type
- Schemas are available at: `/assets/json-schemas/{chartType}.json`
- Different chart types have different required and optional properties

#### Title Property
- Avoid using the `title` option unless explicitly needed
- If you must use a title, it MUST be a localized string object: `title: { en: 'English title' }`
- Never use: `title: 'My Title'` (string) or `title: { title: { en: 'My Title' } }` (nested)

#### Localized Strings
All user-facing text properties (title, label, description, etc.) must be objects with language keys:
- Correct: `{ en: 'Revenue' }`
- Wrong: `'Revenue'` or `{ title: { en: 'Revenue' } }`

### Theming

#### Built-in Theme IDs
`default`, `default_dark`, `vivid`, `seasonal`, `orion`, `royale`, `urban`, `pinky`, `bliss`, `radiant`, `classic`, `classic_dark`

#### Custom Themes
Custom themes can be created and referenced by their UUID (see [createTheme](https://developer.luzmo.com/api/createTheme.md) and [searchTheme](https://developer.luzmo.com/api/searchTheme.md))

#### Dark Theme Requirements
- When using a dark theme, always set a dark background color on the items/container
- The chart content adapts to the theme, but the container background must be set explicitly
- Example: `itemsBackground: '#1a1a2e'` or use CSS `background-color` on the container

### Slot Configuration

#### Required Slot Properties
- **Every slot column MUST have a localized `label`** describing the data shown (e.g. `{ en: "Year" }`, `{ en: "Country" }`, `{ en: "Average Sales" }`)
- **Every slot with a column MUST have `type`** set to the column's type: `hierarchy`, `numeric`, or `datetime`

#### Type-Specific Requirements
- Numeric measures require `aggregationFunc`: `sum`, `average`, `count`, `distinctcount`, `min`, `max`, `median`, `stddev`, `cumulativesum`
- Datetime dimensions require `level`: 1=year, 2=quarter, 3=month, 4=week, 5=day, 6=hour, 7=minute, 8=second, 9=millisecond
- Hierarchy dimensions require `level` for drill-down depth (1 = top level)
- You can optionally specify `subtype` for columns that have one of the following subtypes: `coordinates`, `currency`, `duration`, `hierarchy_element_expression`, `ip_address`, `topography`

#### Chart-Specific Options
- Each chart type has its own set of options to customize visualization (colors, legends, axes, formatting, etc.).
- ALWAYS fetch the chart-specific documentation (to see available slots and options for a chart) before configuring here: https://developer.luzmo.com/guide/flex--chart-docs.md.

### API Resources

#### Dashboard item IDs
- When creating dashboard items (charts, text, spacers, filters, etc.), **omit the `id` field** unless the relevant documentation explicitly requires it.
- Luzmo/the SDK generates IDs; client-generated IDs can break dashboard rendering.
- Only set `id` when updating an existing item or when docs specify a required ID.

#### Valid API Actions
The API action `"search"` does NOT exist. Use `action: "get"` instead.
- **Valid actions:** `create`, `get`, `update`, `delete`, `associate`, `dissociate`

#### Including associated models
To include other resources when searching/getting a resource, use the `include` parameter. Always check the documentation for the resource to see which models can be included and how to include them (e.g. [searchDataset](https://developer.luzmo.com/api/searchDataset.md)). 
When including associated models in a query, the response will return them as lowercase property names. For example, `include: [{ model: 'Column' }]` will return the data in a `columns` property (not `Columns`). Similarly, `model: 'Securable'` → `securables`, `model: 'User'` → `users`, etc.

## Related Files

- [llms.txt](https://developer.luzmo.com/llms.txt): Documentation index with links to all guides and API docs
- [llms-full.txt](https://developer.luzmo.com/llms-full.txt): Full index of all documentation resources in markdown format — every page (guides, API operations, Flex charts) with descriptions; use to discover relevant docs from user queries
- [OpenAPI Schema](https://developer.luzmo.com/assets/oas/oas-luzmo-full.json): Complete API specification
- [Academy AI Search](https://ai-knowledge-base.luzmo.com/ask-question): AI-powered answers about Luzmo (POST with `{"question": "query", "stream": true}`)
