> For the complete documentation index, see [llms.txt](https://docs.groundcover.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.groundcover.com/reference/remote-access-and-apis/api-examples/query-data-gcql.md).

# Query Data with gcQL

Query logs, traces, and Kubernetes events over HTTP using gcQL, groundcover's pipe-based query language. All signals share the same request structure and response format.

groundcover exposes a search endpoint per data type, all sharing the same request structure and all powered by [gcQL](/investigate/querying-your-groundcover-data/groundcover-query-language.md) - the same query language used in the platform's Data Explorer, dashboards, and monitors. Anything you can express in the product's search bar can be executed through these endpoints: filtering, field projection, aggregations, sorting, joins, and more.

### Endpoints

| Data type         | Endpoint                             |
| ----------------- | ------------------------------------ |
| Logs              | **POST** `/api/logs/v2/search`       |
| Traces            | **POST** `/api/traces/v2/search`     |
| Kubernetes Events | **POST** `/api/k8s/v2/events/search` |

The base URL for all endpoints is `https://api.groundcover.com`.

{% hint style="info" %}
Self-hosted ([onPrem](/architecture/overview.md#onprem) / [airGapped](/architecture/overview.md#airgapped)) deployments use their own API URL. Replace `https://api.groundcover.com` with your environment's endpoint everywhere in this section, and use an API key generated in that environment's console - API keys are only valid for the environment that issued them.
{% endhint %}

### Authentication

All endpoints require an [API key](/administer/api-keys.md) passed in the Authorization header:

```
Authorization: Bearer <YOUR_API_KEY>
```

If your account is associated with multiple backends, also include the `X-Backend-Id` header:

```
X-Backend-Id: <YOUR_BACKEND_ID>
```

To locate your Backend ID, navigate to **Settings → Access**, open the **API Keys** tab, and find it in the section header.

### Request Body

All search endpoints accept the same JSON body:

| Parameter | Type   | Required | Description                                                                 |
| --------- | ------ | -------- | --------------------------------------------------------------------------- |
| `start`   | string | Yes      | Start of the time range, RFC3339 / ISO 8601 (e.g. `"2026-08-22T14:00:00Z"`) |
| `end`     | string | Yes      | End of the time range, RFC3339 / ISO 8601                                   |
| `query`   | string | Yes      | The gcQL query to execute                                                   |

**Example Request Body:**

```json
{
  "start": "2026-08-22T14:00:00Z",
  "end": "2026-08-22T15:00:00Z",
  "query": "level:error | fields _time, workload, content | limit 20"
}
```

### Writing gcQL Queries

A gcQL query starts with a filter expression (or `*` to match everything) followed by pipe operations:

```
<filter> | pipe1 | pipe2 | ...
```

For example, counting error logs per workload:

```
level:error | stats by (workload) count() as errors | sort by (errors desc) | limit 10
```

A few rules of thumb for queries over the API:

* **Always end with `| limit N`** to bound the result size.
* **Filters alone return no data** - pipe to `| fields`, `| stats`, or `| limit` to select what comes back.
* **Prefer selective filters** (a specific workload, namespace, or level) over `*`, and keep time ranges as narrow as your use case allows. Both dramatically reduce query cost.
* **Use `| fields`** to select only the columns you need and keep responses small.
* The request's `start` and `end` set the time window - use the `_time` field inside the query only for sub-windows or offsets.

See the full [gcQL reference](/investigate/querying-your-groundcover-data/groundcover-query-language/groundcover-query-language-gcql-reference.md) for all filters, pipes, and aggregation functions.

### Response

The response is a JSON array of row objects. The shape of each row depends on the query: raw record queries return the record fields (or the ones selected with `| fields`), and aggregation queries return the group-by fields plus the computed values.

```json
[
  {
    "_time": "2026-08-22T15:50:56.503949956Z",
    "workload": "checkout-service",
    "content": "failed to process payment: connection timeout"
  }
]
```

### Pagination

Paginate with the `offset` and `limit` pipes, keeping the same time range and a stable sort order across pages:

```
level:error | sort by (_time desc) | fields _time, workload, content | limit 200
level:error | sort by (_time desc) | fields _time, workload, content | offset 200 | limit 200
level:error | sort by (_time desc) | fields _time, workload, content | offset 400 | limit 200
```

For aggregation queries, prefer refining the query (tighter filters, higher-level grouping) over paginating through a large result set.

### Per-Signal Examples

* [Query Logs](/reference/remote-access-and-apis/api-examples/query-data-gcql/query-logs.md)
* [Query Traces](/reference/remote-access-and-apis/api-examples/query-data-gcql/query-traces.md)
* [Query Kubernetes Events](/reference/remote-access-and-apis/api-examples/query-data-gcql/query-events.md)

APM measurements (pre-aggregated request, error, and latency data) are also queried with gcQL, through their own endpoints - see [Query APM Measurements](/reference/remote-access-and-apis/api-examples/query-apm-measurements.md).


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.groundcover.com/reference/remote-access-and-apis/api-examples/query-data-gcql.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
