> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oviond.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Querying data

> Use POST /v1/data/query to pull live metric values from a client's connected data sources — the endpoint behind Oviond's charts and KPIs.

`POST /v1/data/query` returns live metric values from one of a client's **connected** data sources. It's the same call that powers every chart and KPI widget in the app, exposed for your own automations.

<Note>
  This endpoint proxies to Oviond's datasource service. It reads a data source the client has already connected in the app — it does not create or authorize connections. Connect a source in the [project editor](/data-sources/connect) first.
</Note>

## Request

```bash theme={null}
curl -X POST https://api.oviond.com/v1/data/query \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "datasource_id": "ga4",
    "client_id": "cliAbc123",
    "date_range": { "current_start": "2026-03-01", "current_end": "2026-03-31" },
    "metrics": ["sessions", "conversions"],
    "dimensions": ["DATE"],
    "data_view": "OVERVIEW"
  }'
```

| Field           | Required | Description                                                                                                                                                                                                                                                                                                    |
| --------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `datasource_id` | ✓        | The datasource alias, e.g. `ga4`, `gadw`, `fb-ads`. **List all with [`GET /v1/data/datasources`](#finding-valid-identifiers).**                                                                                                                                                                                |
| `client_id`     | ✓        | The client whose connected data source you're querying. List with `GET /v1/clients`.                                                                                                                                                                                                                           |
| `date_range`    | ✓        | `{ current_start, current_end }` as `YYYY-MM-DD`. Add `previous_start` / `previous_end` to get period-over-period comparison values.                                                                                                                                                                           |
| `metrics`       | ✓        | Array of metric `id`s, e.g. `["clicks", "impressions"]`. **Get valid ids from [`GET /v1/data/{datasource_id}/metrics`](#finding-valid-identifiers).**                                                                                                                                                          |
| `dimensions`    | ✓        | Array of dimension `id`s, e.g. `["DATE"]` for a time series, or `[]` for a single total. **Get valid ids from [`GET /v1/data/{datasource_id}/dimensions`](#finding-valid-identifiers).**                                                                                                                       |
| `data_view`     | ✓        | The datasource view, e.g. `ACCOUNT`. Returned alongside each field by the `/metrics` and `/dimensions` endpoints above.                                                                                                                                                                                        |
| `filters`       |          | Array of `{ field, operator, value }` filter objects. `operator` is one of `equals`, `not_equals`, `contains`, `not_contains`, `starts_with`, `ends_with`, `greater_than`, `less_than`, `greater_than_or_equal`, `less_than_or_equal`. Add `"logicalOperator": "and"` (or `"or"`) to combine multiple filters. |
| `timezone`      |          | IANA timezone for date bucketing. Defaults to `UTC`.                                                                                                                                                                                                                                                           |

## Response

```json theme={null}
{
  "success": true,
  "data": {
    "current": [
      { "DATE": "2026-03-01", "sessions": 1240, "conversions": 18 },
      { "DATE": "2026-03-02", "sessions": 1310, "conversions": 22 }
    ],
    "currentSummary": { "sessions": 39120, "conversions": 604 },
    "previous": [],
    "previousSummary": {},
    "state": "ACTIVE"
  },
  "meta": { "request_id": "req_a1b2c3" }
}
```

* `data.current` — the rows for the current range (one per `dimensions` bucket, keyed by your metric and dimension identifiers).
* `data.currentSummary` — the totals across the current range.
* `data.previous` / `data.previousSummary` — the same for the comparison period, when you pass `previous_start` / `previous_end` (empty otherwise).
* `data.state` — `ACTIVE` when the connection returned data.

Read fields by the identifiers you requested rather than by position; the exact keys vary by datasource and `data_view`.

## Finding valid identifiers

The valid `datasource_id`, `metrics`, `dimensions`, and `data_view` values are all discoverable — you never have to guess. Walk the **field catalog**:

**1. Find the `datasource_id`** — list every datasource Oviond supports:

```bash theme={null}
curl "https://api.oviond.com/v1/data/datasources" \
  -H "Authorization: Bearer YOUR_API_KEY"
# → [{ "id": "gadw", "name": "Google Ads", "category": "...", "data_views": [...] }, ...]
```

**2. List its metrics and dimensions** — the `id`s you pass to the query:

```bash theme={null}
curl "https://api.oviond.com/v1/data/gadw/metrics" \
  -H "Authorization: Bearer YOUR_API_KEY"

curl "https://api.oviond.com/v1/data/gadw/dimensions" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Each returns a **flat, scannable list** — every field carries its `id`, `name`, `data_view`, and `group`:

```json theme={null}
{
  "success": true,
  "data": {
    "datasource": "gadw",
    "data_views": ["ACCOUNT", "CAMPAIGNS", "..."],
    "fields": [
      { "id": "impressions", "name": "Impressions", "data_view": "ACCOUNT", "group": "Basic" },
      { "id": "clicks", "name": "Clicks", "data_view": "ACCOUNT", "group": "Basic" }
    ]
  }
}
```

Add `?data_view=ACCOUNT` to filter to one view. Use each `id` as an entry in `metrics` / `dimensions`, and its `data_view` as `data_view`.

Other helpful endpoints:

* **`GET /v1/clients/{id}/datasources`** — which sources a specific client has connected.
* **`POST /v1/data/resource`** — selectable sub-resource values (campaigns, ad sets, videos) for filters.

<Tip>
  Over MCP the same catalog is available as tools — `data_list_datasources` → `data_list_metrics` / `data_list_dimensions` → `data_query`. Agents call them in that order, no guessing.
</Tip>

## Common errors

| Status | Cause                                                                                                                                                                                                                                                  | What to do                                                                                                                     |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `422`  | Missing/invalid field — no `metrics`, or an unknown `datasource_id`, `metric`, or `dimension` for that datasource. Identifiers are validated against the field catalog before the query runs, so a typo is rejected here rather than failing upstream. | Check the request against the table above and the [field catalog](#finding-valid-identifiers); details are in `error.details`. |
| `404`  | `client_id` doesn't exist in your account.                                                                                                                                                                                                             | Verify the ID via `GET /v1/clients`.                                                                                           |
| `502`  | Upstream datasource error — not connected or an expired OAuth token.                                                                                                                                                                                   | Run [`POST /v1/data/test`](/api/introduction) to check the connection; if the token expired, reconnect the source in the app.  |

<Tip>
  A `502` most often means the client's OAuth token for that datasource has expired and needs reconnecting in the app — it's not a bug in your request.
</Tip>
