> For the complete documentation index, see [llms.txt](https://v2.dataos.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://v2.dataos.info/consume/v1/recipes/query-semantic-model-with-graphql.md).

# Build Applications with Semantic GraphQL

Use the Semantic GraphQL endpoint when an application needs to request specific measures and dimensions in a structured GraphQL response.

GraphQL is useful for interactive applications because the client can define the exact fields it needs and receive the query result in a single response.

## When to use this recipe

Use the GraphQL endpoint when:

* The application already uses GraphQL.
* The client needs only selected measures and dimensions.
* The response should match the requested field structure.
* The application needs query results immediately in JSON format.
* Developers want to avoid polling and fetching results through separate endpoints.

{% hint style="info" %}
Unlike the asynchronous Semantic SQL and REST flow, the GraphQL endpoint returns the query result and execution metadata in the same response.

A `statement_id` is still created and returned under `extensions`, but no additional polling is required when the returned status is `SUCCESS`.
{% endhint %}

## Send a GraphQL query

{% code title="Semantic GraphQL request" %}

```bash
curl --location \
  'https://<DATAOS_FQDN>/vulcan/tenants/<DATAOS_TENANT_ID>/data-products/<DATAOS_TENANT_ID>-<resource-name>/api/v1/query/semantic/graphql' \
  --header 'Content-Type: application/json' \
  --header "Authorization: Bearer ${DATAOS_TOKEN}" \
  --data '{
    "query": "query {\n  table(limit: 10) {\n    customer_profile {\n      count\n      region_id\n    }\n  }\n}",
    "variables": {}
  }'
```

{% endcode %}

The query requests:

* `customer_profile.count` as a measure.
* `customer_profile.region_id` as a dimension.
* A maximum of 10 records.

## Understand the response

```json
{
  "data": {
    "table": [
      {
        "customer_profile": {
          "count": 1.0,
          "region_id": 1.0
        }
      },
      {
        "customer_profile": {
          "count": 1.0,
          "region_id": 3.0
        }
      }
    ]
  },
  "extensions": {
    "statement_id": "01KYPE8HDFCDFAMCJ76D5CVS9K",
    "strategy": "EXECUTE",
    "status": "SUCCESS",
    "fingerprint": "06458a7a04494abd34cbebbd8a8be25ec022dcf04bea497fb3e7496bfbea25ef",
    "is_stale": false,
    "_links": {
      "self": {
        "href": "/api/v1/query/statement/01KYPE8HDFCDFAMCJ76D5CVS9K"
      },
      "result": {
        "href": "/api/v1/query/statement/01KYPE8HDFCDFAMCJ76D5CVS9K/result"
      }
    }
  }
}
```

The response contains two main sections.

### `data`

The `data` object contains the records returned by the semantic query.

The response structure follows the fields selected in the GraphQL request:

```
table
 └── customer_profile
       ├── count
       └── region_id
```

### `extensions`

The `extensions` object contains query execution metadata.

| Field           | What to check                                          |
| --------------- | ------------------------------------------------------ |
| `statement_id`  | Unique identifier created for the query execution.     |
| `status`        | Confirm that the query completed with `SUCCESS`.       |
| `strategy`      | Indicates whether the query was executed or reused.    |
| `fingerprint`   | Identifies the normalized query for matching or reuse. |
| `is_stale`      | Check whether the returned result is marked as stale.  |
| `_links.self`   | Statement endpoint associated with the query.          |
| `_links.result` | Result endpoint associated with the statement.         |

## Validate the response

Applications should check both the GraphQL payload and the execution metadata.

```
Check for GraphQL errors
   ├── Confirm data is present
   ├── Confirm extensions.status is SUCCESS
   ├── Check extensions.is_stale
   └── Process the returned records
```

At minimum, validate:

* The response does not contain a top-level `errors` array.
* The expected object exists under `data`.
* `extensions.status` is `SUCCESS`.
* `extensions.is_stale` has the expected value.
* The requested fields are present in every returned record.

## Use GraphQL variables

Use variables when filter values or limits need to be supplied dynamically by the application.

{% code title="GraphQL request with variables" %}

```bash
curl --location \
  'https://<DATAOS_FQDN>/vulcan/tenants/<DATAOS_TENANT_ID>/data-products/<DATAOS_TENANT_ID>-<resource-name>/api/v1/query/semantic/graphql' \
  --header 'Content-Type: application/json' \
  --header "Authorization: Bearer ${DATAOS_TOKEN}" \
  --data '{
    "query": "query CustomerProfile($limit: Int!) {\n  table(limit: $limit) {\n    customer_profile {\n      count\n      region_id\n    }\n  }\n}",
    "variables": {
      "limit": 10
    }
  }'
```

{% endcode %}

Variables keep the GraphQL query reusable and separate the query structure from runtime values.

## Complete workflow

```
Define required measures and dimensions
        └──► Send GraphQL request
                └──► Validate errors and execution metadata
                        └──► Read records from data.table
                                └──► Render or process the result
```

## Best practices

* Request only the fields required by the application.
* Use variables for dynamic values instead of constructing query strings.
* Always check for GraphQL `errors`, even when the HTTP request succeeds.
* Confirm `extensions.status` before processing the result.
* Review `is_stale` when result freshness matters.
* Use pagination or a bounded `limit` for large datasets.
* Keep API tokens outside application source code.

## References

* [GraphQL API reference](https://v2.dataos.info/references/interfaces/apis/data-product-apis/api-reference/graphql): full endpoint details and error behavior
* [Retrieve large result sets with pagination](/consume/v1/recipes/retrieve-large-result-sets-with-pagination.md): for Semantic REST/SQL queries returning more than 50,000 records
* [Generate native warehouse SQL](/consume/v1/recipes/transpile-semantic-queries-to-native-warehouse-sql.md): inspect the SQL a semantic query would run, without executing it


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://v2.dataos.info/consume/v1/recipes/query-semantic-model-with-graphql.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
