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

# Decision Context Preview

> List the assembled decision-context namespace available for authoring — every key a gate, compute formula, or scoring predictor can reference, with its type and source.

## What this endpoint is for

The engine [auto-assembles one canonical decision context](/decisioning/decision-flows#the-decision-context-auto-assembled) per Recommend call (`customer.*`, `<entity>.*`, `behavior.*`, `journey.*`, `attributes.*`). This endpoint answers the authoring-time question **"what keys can I reference?"** — it returns the full key catalog derived from your tenant's *metadata* (customer schema columns, active Schema Joins and their aggregations, active Behavioral Metrics), without assembling any real customer.

It powers the **attribute picker** in the Decisioning Gates builder (Studio → Decisioning Gates), so authors pick verified keys instead of typing a guess — eliminating the namespace-mismatch class of silently skipped gates at author time.

## GET /api/v1/decision-context/preview

Tenant-scoped, read-only. Any role (viewer+).

### Query Parameters

| Parameter | Type   | Required | Description                                                                                                                                                                                                                  |
| --------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `flowKey` | string | No       | A Decision Flow `key` or `id`. Applies that flow's Enrich-node `excludeJoinIds[]` opt-out so the catalog matches what *that flow* assembles (uses the flow's latest published config, else its draft). Unknown flow → `404`. |

### Response

A JSON **array** of key descriptors:

```json theme={null}
[
  { "key": "customer.credit_score_band", "type": "string", "source": "customer", "description": "Base customer field (schema \"customers\")" },
  { "key": "accounts.total_balance", "type": "number", "source": "join", "entity": "accounts", "description": "sum(balance) over joined \"Customer → Accounts\"" },
  { "key": "accounts.count", "type": "number", "source": "join", "entity": "accounts" },
  { "key": "accounts[]", "type": "array", "source": "join", "entity": "accounts", "description": "Raw accounts row collection — quantifier escape hatch (advanced)" },
  { "key": "behavior.converts_30d", "type": "number", "source": "behavior" },
  { "key": "journey.current", "type": "string", "source": "journey" },
  { "key": "attributes.*", "type": "unknown", "source": "attributes" },
  { "key": "attributes.propensityScores", "type": "json", "source": "attributes" }
]
```

| Field         | Description                                                                                                                         |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `key`         | The **exact key** the runtime assembler emits — safe to paste into a gate's `attribute`, a compute formula, or a scoring predictor. |
| `type`        | Coarse value type: `string` \| `number` \| `boolean` \| `date` \| `json` \| `array` \| `unknown`.                                   |
| `source`      | Which namespace produced it: `customer` \| `join` \| `behavior` \| `journey` \| `attributes`.                                       |
| `entity`      | Present on `join` keys — the joined schema's entity slug (the namespace prefix).                                                    |
| `description` | Human-readable provenance (schema/join/metric name, aggregation applied).                                                           |

### How the catalog is built

* **`customer.*`** — every live column of each `entityType: customer` schema's `ds_*` table (the same column universe the runtime `SELECT *`s), minus the internal `id` / `created_at` / `updated_at` columns.
* **`<entity>.*`** — for each active Schema Join with `autoEnrich: true`: the join's configured [`aggregations`](/api-reference/schema-joins) produce exactly one key each (`alias`, else `<field>_<aggregator>`; count-star → `count`). A join with **no** aggregations shows the default rollup: `<entity>.count` plus the first row's scalar fields. Every join also advertises the raw-collection escape hatch `<entity>[]`.
* **`behavior.*`** — one key per **active** Behavioral Metric, slugified exactly like the runtime (metric "Converts 30d" → `behavior.converts_30d`).
* **`journey.*`** — `journey.current`, `journey.step`, `journey.enrolled` (all absent at runtime when the customer isn't enrolled).
* **`attributes.*`** — request-time attributes are free-form, so the catalog documents the wildcard plus `attributes.propensityScores` (read by `propensity_threshold` gates).

<Note>
  The catalog lists keys that **can** exist at decision time. A key may still be absent for a specific customer (e.g. `journey.current` when not enrolled, a join that matched zero rows) — attribute-reading gates then follow their [`onMissing` behavior](/decisioning/qualification-rules#missing-data-onmissing).
</Note>

### Example

```bash theme={null}
curl -s "https://your-host/api/v1/decision-context/preview?flowKey=homepage-decisioning" \
  -H "X-API-Key: $KAIREON_API_KEY" \
  -H "X-Tenant-Id: $TENANT_ID"
```

### Errors

| Status | Meaning                                                   |
| ------ | --------------------------------------------------------- |
| `400`  | Invalid `flowKey` query value.                            |
| `401`  | Missing/invalid credentials.                              |
| `404`  | `flowKey` doesn't match any Decision Flow in this tenant. |
