# Query a dataset

> Run a dataset query (issues, pull requests, workflow runs, deployments, spend or agent sessions) as you, over what you can read: rows of the measure, grouped and filtered as asked, with truncated when more rows matched, and partial true when some of it was left out because you cannot read it.

<div class="g1t-endpoint"><span class="g1t-method" data-method="post">POST</span><code>/workspaces/{workspace}/datasets/query</code></div>

Answers that dashboards are not here yet until they ship.

Runs as you, over what you can read: `partial` is true when some of it was left out because you cannot read it. Until dashboards ship this answers `422` saying they are not here yet.

- **Authentication:** Required. Send an [access token](/reference/api/#authentication) as `Authorization: Bearer`.
- **MCP tool:** [`artifact`](/reference/mcp/#artifact) with `action` `query_data`, and the same inputs
- **Scope:** An access token needs [`artifacts:read`](/guides/authentication/#scopes).

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `workspace` | string | Yes | The workspace's slug, e.g. "acme". |

## Body parameters

Send a JSON object. Names are `snake_case`, as in responses; the `camelCase` spelling is accepted too.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `query` | object | Yes | dataset (issues, pull_requests, workflow_runs, deployments, spend or agent_sessions), measure ({ op: count, sum, avg, p50, p95 or rate, field where it takes one }), and optional group_by, interval (day, week or month), time, filters ([{ field, op, value }], at most 10), range (7d, 30d, 90d, or { from, to }, at most 366 days) and limit (at most 100). |

## Example request

```sh
curl -X POST https://api.g1t.sh/workspaces/acme/datasets/query \
  -H "Authorization: Bearer $G1T_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": {
      "dataset": "pull_requests",
      "measure": {
        "op": "count"
      },
      "group_by": "repo",
      "range": {
        "from": "2026-09-01",
        "to": "2026-09-30"
      }
    }
  }'
```

## Example response

A successful request answers `200` with:

```json
{
  "columns": [
    {
      "name": "repo",
      "type": "string"
    },
    {
      "name": "count",
      "type": "number"
    }
  ],
  "rows": [
    [
      "acme/web",
      42
    ],
    [
      "acme/api",
      7
    ]
  ],
  "truncated": false,
  "partial": false,
  "as_of": "2026-10-09T12:00:00.000Z"
}
```

## Errors

A failed request answers with one of these statuses and a body like `{"error": {"code": "not_found", "message": "Repository not found."}}`. See [errors](/reference/api/#errors).

| Status | Code | When |
| --- | --- | --- |
| 401 | `unauthenticated` | A token is required, or the one sent is not valid. |
| 403 | `forbidden` | The token is valid but not allowed to do this, such as a member-only change or an agent token outside its repository. |
| 404 | `not_found` | It does not exist, or you cannot see it. |
| 409 | `conflict` | The request conflicts with the current state. |
| 422 | `invalid` | The input is not valid. `message` says which field and why. |
