> For the complete documentation index, see [llms.txt](https://docs.mediarithmics.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mediarithmics.io/setup-and-monitor/operate-and-monitor/query-your-datamart/query-api.md).

# Query API

Save, validate, and execute queries from your own code.

## Your goal

Run and manage queries programmatically - and save them as objects when another platform feature needs to reference one.

## Expected outcome

Queries you can check before saving, saved queries other objects can point at, and executions whose caching behaviour you control.

## When a query has to be saved

You usually type OTQL queries directly into tools such as the Navigator. But **queries can be saved and managed by code as objects**, and some features require you to link an object to a saved query rather than to query text:

| Feature                                                                                                   | Why it needs a saved query                    |
| --------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| [Export](/setup-and-monitor/collect-and-manage-your-data/export-your-data/export.md)                      | An export definition references a `query_id`. |
| [Segment metrics](/setup-and-monitor/plan-and-integrate/set-up-the-environment/set-up-segment-metrics.md) | Each metric references a `query_id`.          |
| [Dashboards](/setup-and-monitor/operate-and-monitor/create-a-custom-dashboard.md)                         | Cards reference queries.                      |

{% hint style="info" %}
Features that ask you to save a query usually do so to **optimise performance**.
{% endhint %}

## Check a query before you save it

```
POST https://api.mediarithmics.com/v1/datamarts/:datamartId/query_check/otql
```

```json
{ "query": "SELECT {id} FROM UserPoint" }
```

A valid query returns `type: "VALID"`. An invalid one returns `type: "PARSING_ERROR"` with a message, the row and column of the problem, and an error type:

```json
{
    "status": "ok",
    "data": {
        "type": "PARSING_ERROR",
        "error": {
            "message": "Syntax error while parsing document ...",
            "position": { "row": 1, "col": 1 },
            "error_type": "PARSING"
        },
        "status": "error"
    }
}
```

{% hint style="success" %}
Note that the check itself returns `status: "ok"` - the validity is in `data.type`, not in the HTTP-level status. Read the right field.
{% endhint %}

## Save a query

```
POST https://api.mediarithmics.com/v1/datamarts/:datamartId/queries
```

```json
{
    "query_text": "SELECT {id} FROM UserPoint",
    "datamart_id": "<ASSOCIATED_DATAMART_ID>",
    "query_language": "OTQL"
}
```

The response returns the query object, including the **`id` you use in the next steps**:

```json
{
  "id": "50409",
  "datamart_id": "1509",
  "query_language": "OTQL",
  "query_text": "SELECT {id} FROM UserPoint",
  "favorite": false
}
```

An invalid query is rejected with `BAD_REQUEST_DATA` and the parsing error - **you cannot save an invalid query**.

## Execute a query

```
POST https://api.mediarithmics.com/v1/datamarts/:datamart_id/query_executions/otql?use_cache=true
```

The body is the OTQL query as a string.

```json
{
    "status": "ok",
    "data": {
        "took": 112015,
        "timed_out": false,
        "result_type": "COUNT",
        "precision": "FULL_PRECISION",
        "sampling_ratio": null,
        "rows": [ { "count": 80975924 } ],
        "cache_hit": true
    }
}
```

Fields worth reading beyond `rows`:

| Field                         | What it tells you                         |
| ----------------------------- | ----------------------------------------- |
| `took`                        | Execution time.                           |
| `timed_out`                   | Whether the query completed.              |
| `result_type`                 | The kind of result - `COUNT`, and so on.  |
| `precision`, `sampling_ratio` | Whether the answer is exact.              |
| `cache_hit`                   | Whether the response came from the cache. |

A `503` with `SERVICE_UNAVAILABLE` means retry later - worth handling explicitly in an automated job.

### Caching

`use_cache=true` returns the cached result when one is available; check `cache_hit` to know whether it did. The cache expires after **12 hours**.

Without the parameter, or with `false`, the cache is skipped: the query runs and its result is **not stored**. You cannot use this to force a cache refresh.

{% hint style="warning" %}
The cache is keyed on the query text. A query using a relative date such as `now-1h` returns the **same** cached result for the next twelve hours, even though `now` has moved. For a scheduled job that must see fresh data, either skip the cache or round the anchor so the text changes.
{% endhint %}

## For GraphQL

The GraphQL endpoint is separate, and covered in [GraphQL queries](/setup-and-monitor/operate-and-monitor/query-your-datamart/graphql-queries.md):

```
POST /v1/datamarts/:datamartId/query_executions/graphql
```

## Related pages

<table data-view="cards" data-search="false"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>OTQL documentation</strong></td><td>The language, and the execution semantics.</td><td><a href="/setup-and-monitor/operate-and-monitor/query-your-datamart/otql/otql-documentation.md">OTQL documentation</a></td></tr><tr><td><strong>Query Tool</strong></td><td>The interactive equivalent.</td><td><a href="/setup-and-monitor/operate-and-monitor/query-your-datamart/query-tool.md">Query Tool</a></td></tr><tr><td><strong>Manage API access</strong></td><td>Authentication and response wrappers.</td><td><a href="/setup-and-monitor/manage-the-platform/manage-api-access.md">Manage API access</a></td></tr></tbody></table>


---

# 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.mediarithmics.io/setup-and-monitor/operate-and-monitor/query-your-datamart/query-api.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.
