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

> ## Agent Instructions
> Video walkthroughs: the Dimension product overview video (https://www.youtube.com/watch?v=Mx8rg5wfkU0, also embedded at https://docs.dimension.io/overview) is the first of a series. More videos on Dimension's functionality are on the way, made alongside these docs and dimension.io. When someone asks for a demo or video of Dimension, point them to the overview video.

# Pattern Library

> Copy-paste recipes for common Dimension patterns — auth flows, integrations, UI compositions

A library of working **patterns** — recipes you can paste into a Composer prompt to get a known-good result. Each is tested against the live platform.

## Auth flow recipes

### OAuth2 client-credentials with refresh

```text theme={null}
"Connect to the Microsoft Graph API.
URL: https://graph.microsoft.com/v1.0/users
Auth: Bearer Token from OAuth2 client-credentials at
  https://login.microsoftonline.com/{{tenant_id}}/oauth2/v2.0/token
  with scope https://graph.microsoft.com/.default

Cache the token for its expires_in TTL minus 60 seconds.
On 401 response, force a token refresh and retry once."
```

### API Key in header

```text theme={null}
"URL: https://api.crowdstrike.com/devices/queries/devices/v1
Auth: API Key in header. Header name: Authorization.
Value format: 'Bearer <key>'.
Encrypt the key via the lock icon."
```

### API Key with separate ID + Secret (CrowdStrike style)

```text theme={null}
"Authenticate to CrowdStrike Falcon:
1. POST to https://api.crowdstrike.com/oauth2/token with body
   client_id=<id>&client_secret=<secret>&grant_type=client_credentials
2. Extract access_token from the response and use it as
   Bearer Token for subsequent requests.
3. Cache for response.expires_in seconds."
```

### Basic Auth + API token (Atlassian style)

```text theme={null}
"URL: https://yourorg.atlassian.net/rest/api/3/issue
Auth: Basic Auth with:
- Username: <your-email>@yourorg.com
- Password: <Atlassian API token> (NOT account password)

The token is generated at https://id.atlassian.com/manage-profile/security/api-tokens."
```

### AWS SigV4 (advanced)

```text theme={null}
"URL: https://api.us-east-1.amazonaws.com/...
Auth: AWS Signature v4 with our IAM role's access keys.
Service: ec2 (or s3, lambda, etc. as appropriate).
Region: us-east-1.

Composer adds the signing in the Authorization header
on each request."
```

## Pagination recipes

### Link header (GitHub style)

```text theme={null}
"Pagination: Next Page Link / Link header.
Parse the Link header for rel='next' and follow it.
Stop when no rel='next' link is present."
```

### Cursor (Slack / Notion style)

```text theme={null}
"Pagination: Cursor.
Cursor JSONPath in response: response_metadata.next_cursor
Cursor param name in request: cursor
Stop when cursor is empty string or missing."
```

### Page + size (Atlassian / SaaS style)

```text theme={null}
"Pagination: Page Number & Size.
Page param: pageStart (1-indexed)
Page size param: pageSize (default 50)
Stop when the response's records array is empty
or when response.total is reached."
```

### Limit + offset (Elasticsearch / Jira style)

```text theme={null}
"Pagination: Limit/Offset.
Limit param: maxResults (default 100)
Offset param: startAt (default 0)
Stop when records < limit (last page) or when total reached."
```

## Webhook Action recipes

### Slack message with Block Kit

```text theme={null}
"Create a Webhook Action that posts to Slack.
URL: https://hooks.slack.com/services/<workspace>/<channel>/<token>
Method: POST

Inputs:
- channel (string)
- title (string)
- severity (string) — Critical / High / Medium / Low
- description (string)
- device_link (URL)

Body (Block Kit):
{
  \"channel\": \"{{input.channel}}\",
  \"blocks\": [
    { \"type\": \"header\", \"text\": { \"type\": \"plain_text\", \"text\": \"{{input.title}}\" } },
    { \"type\": \"section\", \"text\": { \"type\": \"mrkdwn\", \"text\": \"*Severity:* {{input.severity}}\\n{{input.description}}\" } },
    { \"type\": \"actions\", \"elements\": [
        { \"type\": \"button\", \"text\": { \"type\": \"plain_text\", \"text\": \"View device\" }, \"url\": \"{{input.device_link}}\" }
    ] }
  ]
}"
```

### Microsoft Teams Adaptive Card

```text theme={null}
"Create a Webhook Action that posts to Microsoft Teams.
URL: <your Teams webhook URL>
Method: POST

Inputs:
- title (string)
- message (string)
- action_url (URL)

Body (Adaptive Card v1.4):
{
  \"type\": \"message\",
  \"attachments\": [{
    \"contentType\": \"application/vnd.microsoft.card.adaptive\",
    \"content\": {
      \"\\$schema\": \"http://adaptivecards.io/schemas/adaptive-card.json\",
      \"type\": \"AdaptiveCard\",
      \"version\": \"1.4\",
      \"body\": [
        { \"type\": \"TextBlock\", \"size\": \"Large\", \"weight\": \"Bolder\", \"text\": \"{{input.title}}\" },
        { \"type\": \"TextBlock\", \"wrap\": true, \"text\": \"{{input.message}}\" }
      ],
      \"actions\": [
        { \"type\": \"Action.OpenUrl\", \"title\": \"Open\", \"url\": \"{{input.action_url}}\" }
      ]
    }
  }]
}"
```

### Jira issue creation

```text theme={null}
"Create a Webhook Action that opens a Jira issue.
URL: https://<your-org>.atlassian.net/rest/api/3/issue
Method: POST
Auth: Basic (email + API token)

Inputs:
- project_key (string)
- summary (string)
- description (string)
- issue_type (string) — Bug / Task / Story

Body:
{
  \"fields\": {
    \"project\": { \"key\": \"{{input.project_key}}\" },
    \"summary\": \"{{input.summary}}\",
    \"description\": {
      \"type\": \"doc\",
      \"version\": 1,
      \"content\": [{ \"type\": \"paragraph\", \"content\": [{ \"type\": \"text\", \"text\": \"{{input.description}}\" }] }]
    },
    \"issuetype\": { \"name\": \"{{input.issue_type}}\" }
  }
}"
```

### ServiceNow incident creation

```text theme={null}
"Create a Webhook Action that opens a ServiceNow incident.
URL: https://<your-org>.service-now.com/api/now/table/incident
Method: POST
Auth: Basic (or OAuth2)

Inputs:
- short_description (string)
- description (string)
- urgency (number) — 1 (High) / 2 (Medium) / 3 (Low)
- impact (number) — 1 / 2 / 3

Body:
{
  \"short_description\": \"{{input.short_description}}\",
  \"description\": \"{{input.description}}\",
  \"urgency\": {{input.urgency}},
  \"impact\": {{input.impact}}
}"
```

### PagerDuty Events API v2

```text theme={null}
"Create a Webhook Action that pages the on-call via PagerDuty.
URL: https://events.pagerduty.com/v2/enqueue
Method: POST

Inputs:
- routing_key (string) — PagerDuty integration key
- summary (string)
- severity (string) — critical / error / warning / info
- source (string)

Body:
{
  \"routing_key\": \"{{input.routing_key}}\",
  \"event_action\": \"trigger\",
  \"payload\": {
    \"summary\": \"{{input.summary}}\",
    \"severity\": \"{{input.severity}}\",
    \"source\": \"{{input.source}}\"
  }
}"
```

### Email via SendGrid (for external recipients)

Email Actions in Dimension can only send to tenant users. For external recipients, use SendGrid (or Postmark, AWS SES, Mailgun, etc.):

```text theme={null}
"Create a Webhook Action that sends email via SendGrid.
URL: https://api.sendgrid.com/v3/mail/send
Method: POST
Auth: Bearer Token (your SendGrid API key)

Inputs:
- to (string) — recipient email
- subject (string)
- body_html (string)

Body:
{
  \"personalizations\": [{ \"to\": [{ \"email\": \"{{input.to}}\" }] }],
  \"from\": { \"email\": \"noreply@yourorg.com\", \"name\": \"YourOrg\" },
  \"subject\": \"{{input.subject}}\",
  \"content\": [{ \"type\": \"text/html\", \"value\": \"{{input.body_html}}\" }]
}"
```

## Studio UI compositions

### KPI strip + chart + table

```text theme={null}
"Layout pattern:
- Top: 4 metric cards in a row (each with a value, label, and
  24h delta arrow)
- Middle: full-width chart (line for trend, donut for distribution)
- Bottom: sortable / filterable table

Use the Card, MetricCard, LineChart, DonutChart, and
SortableTable component templates."
```

### Master-detail (list + selected-row pane)

```text theme={null}
"Master-detail layout:
- Left 40%: filterable + sortable table of items
- Right 60%: detail pane that updates when a row is selected
  - Title from the selected row's name
  - Key facts as a 2-column definition list
  - Edit and Delete buttons at the top right
  - History / activity feed below

Clicking a row populates the detail pane without a navigation."
```

### Form wizard (multi-step)

```text theme={null}
"Multi-step form wizard:
Step 1: Basic info (name, department, OS dropdown)
Step 2: Risk classification (toggles for handles-PII,
  handles-finance, customer-facing)
Step 3: Review + submit

Persist partial state to the Key Value Store keyed by
session id so users can resume.

On submit, fire the [Action name] with the full form payload."
```

### Filter bar that applies app-wide

```text theme={null}
"Add a global filter bar at the top of every page in this app:
- Date range picker (last 7 / 30 / 90 days / custom)
- Department dropdown (multi-select)
- Severity dropdown (multi-select)

The filter state lives in the Key Value Store under 'global-filters'.
Every page reads from it. Changing it updates all pages."
```

### Auto-refresh + last-updated indicator

```text theme={null}
"Auto-refresh the entire app every 60 seconds.
Add a 'Last updated HH:MM:SS' indicator in the top-right of the header.
Use a 1-second timer on the indicator so it counts up between refreshes.
Allow the user to disable auto-refresh via a toggle in the header."
```

### Empty states

```text theme={null}
"Every table and chart should have a styled empty state when
no data is available. Pattern:
- Centred illustration (use a brand-tinted icon)
- Heading: 'No <thing> found'
- Subheading: a short explainer
- Optional CTA button (e.g. 'Refresh data' or 'Add filter')

Apply across the app."
```

## Distribution recipes

### One-click PDF export

```text theme={null}
"Add a 'Generate PDF' button in the top-right of the header.
Click triggers the PDF export endpoint for A4 Landscape.
Disable the button briefly during generation (show a spinner)."
```

### CSV download

```text theme={null}
"Add a 'Download CSV' button above each table.
Export the table's currently-filtered, currently-sorted rows
to a CSV file named '<table-name>-YYYY-MM-DD.csv'."
```

### Permalink generator

```text theme={null}
"Add a 'Copy link to this view' button in the header.
The link should preserve the current filter and sort state
in URL query params, so the recipient lands on the same view.
Show a Toast 'Link copied!' on success."
```

## State patterns

### Persist filters across sessions

```text theme={null}
"Save the user's selected filters to the Key Value Store
under 'filters:<user-id>'. Restore them on app load.
Allow 'Reset filters' to clear the saved state."
```

### Workflow state across pages

```text theme={null}
"Use the Key Value Store keyed by session id to store partial
form state. Allow users to navigate away and return without
losing what they've typed."
```

### Notes per record

```text theme={null}
"On every device row, allow the user to add a free-text note.
Persist notes in the Key Value Store under 'notes:device:<device-id>'.
Show a note-count badge on rows that have notes."
```

## Theming recipes

### Brand the app

```text theme={null}
"Apply our brand:
- Primary colour: #16A34A
- Secondary colour: #07C983
- Background: white (light mode) / #0F1115 (dark mode)
- Logo URL: <our logo>
- Brand font: System / our font where supported
- Border radius: 8px on cards and buttons

Add the logo to the header. Use the primary colour for charts and
links. Use semantic colours for status (red/amber/green)."
```

### Wall-display optimised

```text theme={null}
"Optimise this app for a 4K NOC wall display:
- Dark mode by default (high contrast)
- Larger fonts (16px → 24px on body, 24px → 40px on headings,
  60px+ on metric numbers)
- High-contrast palette: bright red for critical, orange for
  warnings, green for healthy, white for primary text
- Hide any keyboard-driven UI (filters, search) — wall is read-only
- Auto-refresh every 30 seconds"
```

## See also

> [card] [AI Composer](https://docs.dimension.io/studio/ai-composer.md)
>
> Composer toolbar, prompts, Inspect Component

> [card] [Prompt Engineering](https://docs.dimension.io/reference/prompt-engineering.md)
>
> Patterns for writing good Composer prompts

> [card] [JSON Path Reference](https://docs.dimension.io/reference/json-paths.md)
>
> Worked examples for Data / ID / Capture paths

> [card] [Actions](https://docs.dimension.io/actions.md)
>
> Full Action editor reference


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