# Querying a SDTF graph

## Introduction

Your token system can be more complex than it seems. You will often need to interact with your token graph to transform a specific set of design tokens within a Specify configuration.

This article will help you understand how you can query your token graph to select a specific set of tokens.

## Compatible parsers

* [filter](/reference/parsers/filter.md)
* [change-case](/reference/parsers/change-case.md)
* [convert-color](/reference/parsers/convert-color.md)
* [convert-dimension](/reference/parsers/convert-dimension.md)

## Query structure

Every Query holds a single a `where` property being an object, to select one branch of the graph, or an array of objects, to select many branches of the graph (OR statement).

```typescript
Type Query = { where: Where | Array<Where> }
```

The `where` property splits in 3 kinds: token, group, collection - offering a dedicated set of options to match against the given kind.

The `name` property accepts a RegExp for a value. These resources will help you debug your regular expressions:

* <https://regex101.com/>
* <https://regexr.com/>

### Where Token

```typescript
type WhereToken = {
  token: 
    | string
    | {
      name?: string;
      description?: string?;
    }
  select: 
    | true
    | {
      token?: boolean;
      parents?:
        | true
        | {
          groups?: true;
          collections?: true;
        }
    }
}
```

### Where Group

```typescript
type WhereGroup = {
  group: string;
  select: 
    | true
    | {
      group?: boolean;
      parents?:
        | true
        | {
          groups?: true;
          collections?: true;
        }
      children:
        | true
        | {
          groups?: true;
          collections?: true;
          tokens?: true;
        }
    }
}
```

### Where Collection

```typescript
type WhereCollection = {
  collection: string;
  select: 
    | true
    | {
      collection?: boolean;
      parents?:
        | true
        | {
          groups?: true;
        }
      children:
        | true
        | {
          groups?: true;
          tokens?: true;
        }
    }
}
```

## Use cases

### Select tokens from a specific collection

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "primitive": {
</strong>    "$description": "`primitive` is a group used for semantic grouping.",
    "spacing": {
      "1": {
        "$type": "dimension",
        "$value": {
          "default": {
            "value": 4,
            "unit": "px"
          }
        }
      }
    }
  },
<strong>  "Colors": {
</strong>    "$description": "`Colors` is a collection.",
    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get tokens from collection named 'Colors'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "collection": "^Colors$",
                "select": {
                  "parents": true,
                  "children": true
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Colors": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select tokens from several collections matching a naming pattern

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "primitive": {
</strong>    "$description": "`primitive` is a group used for semantic grouping.",
    "spacing": {
      "1": {
        "$type": "dimension",
        "$description": "`primitive.spacing.1` is a dimension token without modes.",
        "$value": {
          "default": {
            "value": 4,
            "unit": "px"
          }
        }
      }
    }
  },
<strong>  "Core - Colors": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  },
<strong>  "Core - Spacing": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "space-1": {
      "$type": "spacing",
      "$value": {
        "default": { "value": 1, "unit": "px" }
      }
    },
    "space-2": {
      "$type": "spacing",
      "$value": {
        "default": { "value": 2, "unit": "px" }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get tokens from all collections whose names contain 'Core'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "where": {
              "collection": "Core",
              "select": {
                "collection": true,
                "children": {
                  "tokens": true
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Core - Colors": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  },
<strong>  "Core - Spacing": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "space-1": {
      "$type": "spacing",
      "$value": {
        "default": {
          "value": 1,
          "unit": "px"
        }
      }
    },
    "space-2": {
      "$type": "spacing",
      "$value": {
        "default": {
          "value": 2,
          "unit": "px"
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select tokens from a specific group

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "primitive": {
</strong>    "$description": "`primitive` is a group used for semantic grouping.",
    "spacing": {
      "1": {
        "$type": "dimension",
        "$description": "`primitive.spacing.1` is a dimension token without modes.",
        "$value": {
          "default": {
            "value": 4,
            "unit": "px"
          }
        }
      }
    },
    "font": {
      "interBold": {
        "$type": "font",
        "$value": {
          "default": {
            "family": "Inter",
            "postScriptName": "Inter Bold",
            "weight": "bold",
            "style": "normal",
            "files": [
              {
                "format": "ttf",
                "url": "https://static.specifyapp.com/sdtf-seeds/inter-bold.ttf",
                "provider": "Specify"
              }
            ]
          }
        }
      }
    }
  },
<strong>  "Text Styles": {
</strong>    "heading": {
      "$type": "textStyle",
      "$value": {
        "default": {
          "font": {
            "$alias": "primitive.font.interBold",
            "$mode": "default"
          },
          "color": null,
          "fontSize": {
            "value": 32,
            "unit": "px"
          },
          "lineHeight": {
            "value": 40,
            "unit": "px"
          },
          "fontFeatures": null,
          "letterSpacing": null,
          "paragraphSpacing": null,
          "textAlignHorizontal": null,
          "textAlignVertical": null,
          "textDecoration": null,
          "textIndent": null,
          "textTransform": null
        }
      }
    },
    "display": {
      "$type": "textStyle",
      "$value": {
        "default": {
          "font": {
            "$alias": "primitive.font.interBold",
            "$mode": "default"
          },
          "color": null,
          "fontSize": {
            "value": 56,
            "unit": "px"
          },
          "lineHeight": {
            "value": 64,
            "unit": "px"
          },
          "fontFeatures": null,
          "letterSpacing": {
            "value": -1,
            "unit": "px"
          },
          "paragraphSpacing": null,
          "textAlignHorizontal": null,
          "textAlignVertical": null,
          "textDecoration": null,
          "textIndent": null,
          "textTransform": null
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get tokens from the group named 'Text Styles'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "group": "^Text Styles$",
                "select": {
                  "parents": true,
                  "children": true
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Text Styles": {
</strong>    "display": {
      "$type": "textStyle",
      "$value": {
        "default": {
          "fontSize": {
            "value": 56,
            "unit": "px"
          },
          "color": null,
          "fontFeatures": null,
          "lineHeight": {
            "value": 64,
            "unit": "px"
          },
          "letterSpacing": {
            "value": -1,
            "unit": "px"
          },
          "paragraphSpacing": null,
          "textAlignHorizontal": null,
          "textAlignVertical": null,
          "textDecoration": null,
          "textIndent": null,
          "textTransform": null,
          "font": {
            "$alias": "primitive.font.interBold",
            "$mode": "default"
          }
        }
      }
    },
    "heading": {
      "$type": "textStyle",
      "$value": {
        "default": {
          "fontSize": {
            "value": 32,
            "unit": "px"
          },
          "color": null,
          "fontFeatures": null,
          "lineHeight": {
            "value": 40,
            "unit": "px"
          },
          "letterSpacing": null,
          "paragraphSpacing": null,
          "textAlignHorizontal": null,
          "textAlignVertical": null,
          "textDecoration": null,
          "textIndent": null,
          "textTransform": null,
          "font": {
            "$alias": "primitive.font.interBold",
            "$mode": "default"
          }
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select tokens of a specific type from a collection

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Android": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  },
  "primitive": {
    "gray": {
      "0": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#f8f9fa",
            "alpha": 1
          }
        }
      },
      "9": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#212529",
            "alpha": 1
          }
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get color tokens from the 'Android' collection",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "collection": "^Android$",
                "andWhere": {
                  "token": ".*",
                  "withTypes": { "include": ["color"] },
                  "select": {
                    "token": true,
                    "parents": {
                      "collections": true
                    }
                  }
                }
              }            
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "Android": {
</strong>    "$collection": {
      "$modes": [
        "default"
      ]
    },
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    },
    "white": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select all tokens from a collection and from groups matching a naming pattern

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
  "Android": {
    "$collection": {
      "$modes": [
        "default"
      ]
    },
<strong>    "primitive": {
</strong>      "gray": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#f8f9fa",
            "alpha": 1
          }
        }
      }
    },
<strong>    "components": {
</strong>      "black": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#000000",
            "alpha": 1
          }
        }
      },
      "white": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#FFFFFF",
            "alpha": 1
          }
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get color tokens from the 'Android' collection and from all groups named 'components'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "collection": "^Android$",
                "andWhere": {
                  "group": "^components$",
                  "andWhere": {
                    "token": ".*",
                    "withTypes": {
                      "include": ["color"]
                    },
                    "select": {
                      "token": true,
                      "parents": true
                    }
                  }
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
  "Android": {
    "$collection": {
      "$modes": [
        "default"
      ]
    },
<strong>    "components": {
</strong>      "black": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#000000",
            "alpha": 1
          }
        }
      },
      "white": {
        "$type": "color",
        "$value": {
          "default": {
            "model": "hex",
            "hex": "#FFFFFF",
            "alpha": 1
          }
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select tokens from several groups with different names

{% tabs %}
{% tab title="Input" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "group1": {
</strong>    "token1": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    }
  },
<strong>  "group2": {
</strong>    "token2": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  },
<strong>  "group3": {
</strong>    "token3": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get tokens from the group named 'Components' and/or from the group named 'Semantic'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "group": "^group1$|^group2$",
                "andWhere": {
                  "token": ".*",
                  "select": {
                    "token": true,
                    "parents": true
                  }
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}

<pre class="language-json" data-line-numbers><code class="lang-json">{
<strong>  "group1": {
</strong>    "token1": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    }
  },
<strong>  "group2": {
</strong>    "token2": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#FFFFFF",
          "alpha": 1
        }
      }
    }
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

### Select design tokens from a specific type

{% tabs %}
{% tab title="Input" %}
{% code lineNumbers="true" %}

```json
{
  "dimensions": {
    "spacing": {
      "1": {
        "$type": "dimension",
        "$value": {
          "default": {
            "value": 4,
            "unit": "px"
          }
        }
      }
    }
  },
  "colors": {
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    }
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Config" %}
{% code title=".specifyrc.json" lineNumbers="true" %}

```json
{
  "version": "2",
  "repository": "@organization/repository",
  "personalAccessToken": "<your-personal-access-token>",
  "rules": [
    {
      "name": "Get color tokens from the 'Android' collection and from all groups named 'components'",
      "parsers": [
        {
          "name": "filter",
          "options": {
            "query": {
              "where": {
                "token": ".*",
                "withTypes": {
                  "include": [
                    "color"
                  ]
                },
                "select": {
                  "parents": true
                }
              }
            }
          }
        }
      ]
    }
  ]
}
```

{% endcode %}
{% endtab %}

{% tab title="Output" %}
{% code lineNumbers="true" %}

```json
{
  "colors": {
    "black": {
      "$type": "color",
      "$value": {
        "default": {
          "model": "hex",
          "hex": "#000000",
          "alpha": 1
        }
      }
    }
  }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.specifyapp.com/guides/querying-a-sdtf-graph.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
