# listFilterFields

The filterable-field catalog for a filter domain WITH full value shapes: how to WRITE a condition once you know which field you want (CONTACT, PROPERTY or DEAL; other FilterType values are rejected). Call this BEFORE authoring a saveFilter tree: never guess fieldIds. `fieldIds` is REQUIRED: name the fields you actually need. Unnarrowed, the catalog would be TRUNCATED BY DROPPING WHOLE FIELDS, so this operation is NEVER evidence that a field does not exist: to discover what exists, or before telling anyone a filter cannot express something, call `listFilterFieldNames`, which always arrives complete. An unknown requested fieldId errors naming it (it means that field does NOT exist; do not invent a value shape for it). Each row carries label/category/description, the UI component kind (the value-shape hint: e.g. numericRange, multiSelect, dateRange), acceptedValueKeys (for object-shaped values: the exact top-level keys, e.g. min/max), and static options for select-like fields. USE `valueShapes`, NOT `acceptedValueKeys`, WHENEVER A FIELD HAS MORE THAN ONE: some fields accept several mutually-exclusive value shapes, and acceptedValueKeys flattens them into one list that is NOT itself a valid value. `valueShapes` reports them arm by arm: each with the `discriminatorKey`/`discriminatorValue` literal that selects it, and only that arm’s keys, each marked required or optional with its `acceptedValues` when the key is an enum or literal. A shape carrying `scalar` instead of keys is a BARE value (`bedrooms` accepts `3` as well as `{min, max}`) so send the plain value for that arm, not an object. Pick ONE shape, send that arm’s discriminator literal verbatim, and send only its keys: `dateCustomFieldFilters`, for instance, has seven arms keyed on `comparison`; ON, BEFORE and AFTER take a strict YYYY-MM-DD `date`, MORE_THAN, LESS_THAN and WITHIN_NEXT take number+timeUnit (an interval), and BETWEEN takes from/to (absolute bounds). An unrecognized `comparison` literal fails the WHOLE save; keys borrowed from another arm are silently STRIPPED, so the filter saves without that constraint. Contact CUSTOM fields are NOT addressed by their custom-field UUID as a fieldId: use the wrapper fields this catalog lists (e.g. dropdownCustomFieldFilters / textCustomFieldFilters) whose VALUE carries the custom-field id. `countyFilters` takes a county `fips` (searchCounties), `cityFilters` a city `id` (searchCities). Static schema introspection: reads no org data and never changes with account state.

- Call: `POST https://server.goliathdata.com/api/v1/call` with `{ "operationId": "listFilterFields", "variables": {...} }`
- Scope: `READ`
- Type: query
- Idempotency: a read; rejects `Idempotency-Key`
- Rate-limited: no

## Variables

- `type`: `FilterType!` (required, one of `PROPERTY`, `CONTACT`, `PIPELINE_ITEM`, `DEAL`, `OWNER`, `POST`, `ENTITY`, `PERSON`, `USER`, `ORGANIZATION`)
- `fieldIds`: `[String!]!` (required)

## Response (data, an example)

```json
{
  "filterQuery": {
    "listFilterFields": [
      {
        "fieldId": "<ID>",
        "label": "…",
        "category": "…",
        "description": "…",
        "component": "…",
        "acceptedValueKeys": [
          "…"
        ],
        "valueShapes": [
          {
            "discriminatorKey": "…",
            "discriminatorValue": "…",
            "scalar": {
              "type": "…",
              "acceptedValues": [
                "…"
              ]
            },
            "keys": [
              {
                "key": "…",
                "required": true,
                "acceptedValues": [
                  "…"
                ]
              }
            ]
          }
        ],
        "options": [
          {
            "label": "…",
            "value": "…"
          }
        ],
        "hidden": true,
        "retired": true
      }
    ]
  }
}
```

## Example

```bash
curl https://server.goliathdata.com/api/v1/call \
  -H "Authorization: Bearer $GOLIATH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operationId": "listFilterFields",
    "variables": {
      "type": "PROPERTY",
      "fieldIds": [
        "<String>"
      ]
    }
  }'
```
