Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,709 changes: 2,277 additions & 432 deletions docs/api-reference/beta/openapi.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/api/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ Access is governed by your token's role at three levels:
`env_id` returns `403`.
2. **Resource scope** — the asset, column, and lineage endpoints require the
_assets_ view scope. A role that can reach the environment but isn't granted
the assets resource returns `403`. Test endpoints (**coming soon**) require
the _tests_ view scope.
the assets resource returns `403`. Test endpoints require the _tests_ view
scope.
3. **Per-asset access** — see below.

If your token's role is restricted to a subset of an environment's assets
Expand All @@ -88,8 +88,8 @@ columns and lineage edges derived from them — that you're allowed to see:
- Column-lineage edges are returned only when the downstream column's asset is
visible to you. A returned edge's `upstream_column_id` may reference a
restricted upstream asset; only the id is exposed, not its metadata.
- **Get-one endpoints** (`/assets/{id}`, `/columns/{id}`, and coming-soon
`/tests/{id}`) return `404` for an object you can't view — the same response
- **Get-one endpoints** (`/assets/{id}`, `/columns/{id}`, `/tests/{id}`)
return `404` for an object you can't view — the same response
as a nonexistent object, so the API never discloses that a restricted asset
or test exists.

Expand Down
27 changes: 16 additions & 11 deletions docs/api/incremental-sync.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ GET /{env_id}/assets?limit=500

## Incremental feeds

Assets, columns, and column lineage expose two separate feeds so upserts and
deletes stay clean and each can use its own index:
Assets, columns, column lineage, and tests expose two separate feeds so upserts
and deletes stay clean and each can use its own index:

| Filter | Returns | Use for |
| --------------- | ------------------------------------------------- | --------- |
Expand Down Expand Up @@ -65,17 +65,22 @@ Timestamps are UTC ISO-8601.

## Support matrix

| Dataset | Full scan | Incremental |
| -------------- | --------- | ------------------------------------ |
| Assets | ✅ | ✅ (`synced_since`, `deleted_since`) |
| Columns | ✅ | ✅ (`synced_since`, `deleted_since`) |
| Asset lineage | ✅ | Full replace |
| Column lineage | ✅ | ✅ (`synced_since`, `deleted_since`) |
| Dataset | Full scan | Incremental |
| ------------------------ | --------- | ------------------------------------ |
| Assets | ✅ | ✅ (`synced_since`, `deleted_since`) |
| Columns | ✅ | ✅ (`synced_since`, `deleted_since`) |
| Asset lineage | ✅ | Full replace |
| Column lineage | ✅ | ✅ (`synced_since`, `deleted_since`) |
| Tests | ✅ | ✅ (`synced_since`, `deleted_since`) |
| Latest test executions | ✅ | Full snapshot |
| Test execution history | ✅ | Time window (default last 30 days) |

<Note>
**Coming soon:** tests will use the same `synced_since` / `deleted_since`
pair as assets. Latest test executions will be a full snapshot (no incremental
feed). Per-test execution history is a time window, not an incremental feed.
A new test run does not bump `Test.synced_at` — current status lives on
latest test executions. Disabled tests are omitted from a full scan unless
`disabled=true`; the incremental feeds always include them so a sync observes
a disable. Latest test executions have no incremental feed. Per-test history
is filtered by `start_time`, not `synced_since`.
</Note>

<Note>
Expand Down
20 changes: 10 additions & 10 deletions docs/api/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,14 @@ Follow `next_cursor` until `has_more` is `false` — see [Pagination](/api/pagin
| Columns | `GET /{env_id}/columns` | Columns of assets |
| Asset lineage | `GET /{env_id}/asset-lineage` | Asset-to-asset edges |
| Column lineage | `GET /{env_id}/column-lineage` | Column-to-column edges |
| Tests | `GET /{env_id}/tests` | Test definitions. **Coming soon.** |
| Latest test executions | `GET /{env_id}/latest-test-executions` | Current run per sub-test. **Coming soon.** |
| Test execution history | `GET /{env_id}/tests/{test_id}/executions` | History for one test. **Coming soon.** |
| Tests | `GET /{env_id}/tests` | Test definitions |
| Latest test executions | `GET /{env_id}/latest-test-executions` | Current run per sub-test |
| Test execution history | `GET /{env_id}/tests/{test_id}/executions` | History for one test |

Every list endpoint supports a full scan and keyset pagination; assets and
columns also expose incremental feeds — see [Incremental sync](/api/incremental-sync).
Tests will use the same incremental pair when they ship.
Every list endpoint supports a full scan and keyset pagination. Assets,
columns, and tests also expose incremental feeds — see
[Incremental sync](/api/incremental-sync). Latest test executions are a full
snapshot; per-test history is a time window.

## Assets: one base endpoint, plus typed endpoints

Expand Down Expand Up @@ -96,10 +97,9 @@ A typical flow: page `/assets` to build the graph, then enrich the kinds you
care about via the typed endpoints — use the `kind` field to decide which one.

The full endpoint and schema reference is generated from the API and lives under
**API Reference**. Test endpoints are documented there as **coming soon** until
they ship.
**API Reference**.

## Tests (coming soon)
## Tests

Three datasets, one table each — definitions, current status, and per-test
history are not merged into a single response:
Expand All @@ -108,7 +108,7 @@ history are not merged into a single response:
(name, type, asset, severity, config, owners/tags). Incremental
`synced_since` / `deleted_since`. A new run does not bump `Test.synced_at`.
- **[`GET /latest-test-executions`](/api/reference/latest-test-executions/list-latest-test-executions)** —
the current run per sub-test. Full snapshot; no incremental feed in this cut.
the current run per sub-test. Full snapshot; no incremental feed.
Join to tests on `test_id`.
- **[`GET /tests/{test_id}/executions`](/api/reference/test-executions/list-test-executions)** —
history for one test (default last 30 days). Not an environment-wide dump.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,3 @@
---
title: 'Get a latest test execution'
description: 'Fetch the current run for one sub-test. Coming soon.'
openapi: api-reference/beta/openapi.json get /public/beta/{env_id}/latest-test-executions/{sub_test_unique_id}
---

<Info icon="clock">
**Coming soon.** This endpoint is not live yet. The contract below is the
planned shape and may change. Calling it today returns `404`.
</Info>

```
GET /public/beta/{env_id}/latest-test-executions/{sub_test_unique_id}
```

Path parameter is **`sub_test_unique_id`**, not the execution `id`. Unknown,
not permitted, or parent test not visible → `404`.

The body's `id` is the **current** execution id and **changes** on every new
run. Use `sub_test_unique_id` as the stable key.

## Response

Bare object. Field meanings match
[List latest test executions](/api/reference/latest-test-executions/list-latest-test-executions).

```json
{
"id": "exec_9f3c2a",
"test_id": "elementary_cloud.freshness_anomalies.analytics.orders",
"sub_test_unique_id": "elementary_cloud.freshness_anomalies.analytics.orders",
"sub_type": "freshness_anomalies",
"column_name": null,
"status": "PASS",
"failure_count": 0,
"start_time": "2026-08-20T11:55:00Z",
"duration_seconds": 12.4,
"quality_dimension": "freshness",
"result_reason": "NO_ANOMALY_DETECTED",
"exception": null,
"description": null,
"synced_at": "2026-08-20T11:55:10Z"
}
```

## Example

```bash
curl -H "Authorization: Bearer $ELEMENTARY_TOKEN" \
"$BASE/$ENV_ID/latest-test-executions/$SUB_TEST_UNIQUE_ID"
```
Original file line number Diff line number Diff line change
@@ -1,87 +1,3 @@
---
title: 'List latest test executions'
description: 'Current run per sub-test. Coming soon.'
openapi: api-reference/beta/openapi.json get /public/beta/{env_id}/latest-test-executions
---

<Info icon="clock">
**Coming soon.** This endpoint is not live yet. The contract below is the
planned shape and may change. Calling it today returns `404`.
</Info>

```
GET /public/beta/{env_id}/latest-test-executions
```

Current status snapshot: one row per live sub-test, updated in place. There is
**no** incremental feed (`synced_since` / `deleted_since`) on this dataset —
re-pull the full list (or filter with `test_ids`) when you want a refresh.

Rows whose parent test is deleted are omitted. Cloud monitors are typically
1:1 with `test_id`; dbt tests may have multiple sub-tests.

The execution `id` on each row **changes** when a new run overwrites the row.
The stable key is `sub_test_unique_id`.

## Query parameters

Shared pagination: `cursor`, `limit` (default `500`, max `2000`). Filter arrays
are any-of within a param, AND across params, max `1000` values each.

| Parameter | Notes |
| ------------------ | --------------------------------------------------------------------------------------------- |
| `sub_test_ids` | Filter by `sub_test_unique_id`. |
| `test_ids` | Latest rows for these tests. |
| `asset_ids` | Latest rows whose parent test is on these assets. |
| `test_types` | Parent test `test_type`. Extensible. |
| `definition_types` | Parent test `definition_type`. Extensible. |
| `source_types` | Parent test `source_type`. Extensible. |
| `statuses` | As stored: `PASS`, `WARN`, `FAIL`, `ERROR`, `SKIPPED`, `NO_DATA`. |
| `order_by` | `id` (default) or `synced_at`. Here `id` means **`sub_test_unique_id`**, not the execution id. |
| `direction` | `asc` (default) or `desc`. |

## Response

List envelope `{ items, next_cursor, has_more }`. Item shape is shared with
[test execution history](/api/reference/test-executions/list-test-executions).

```json
{
"items": [
{
"id": "exec_9f3c2a",
"test_id": "elementary_cloud.freshness_anomalies.analytics.orders",
"sub_test_unique_id": "elementary_cloud.freshness_anomalies.analytics.orders",
"sub_type": "freshness_anomalies",
"column_name": null,
"status": "PASS",
"failure_count": 0,
"start_time": "2026-08-20T11:55:00Z",
"duration_seconds": 12.4,
"quality_dimension": "freshness",
"result_reason": "NO_ANOMALY_DETECTED",
"exception": null,
"description": null,
"synced_at": "2026-08-20T11:55:10Z"
}
],
"next_cursor": "eyJ...",
"has_more": true
}
```

| Field | Notes |
| --------------------- | ---------------------------------------------------------------------------------------------------------- |
| `id` | This run's execution id. On latest rows it **changes** when a new run overwrites the row. |
| `sub_test_unique_id` | Stable per sub-test. Path key for get-one. |
| `status` | As stored: `PASS`, `WARN`, `FAIL`, `ERROR`, `SKIPPED`, `NO_DATA`. |
| `failure_count` | Cloud freshness/volume often `0` — the signal is `status`. |
| `quality_dimension` | Nullable. Examples: `completeness`, `uniqueness`, `freshness`, `validity`, `accuracy`, `consistency`. |
| `result_reason` | Nullable. Examples: `ANOMALY_DETECTED`, `NO_ANOMALY_DETECTED`, `PERMISSIONS_ERROR`, `NOT_ENOUGH_DATA_SAMPLES`. |
| `description` | Empty string in storage is returned as `null`. No `metrics` in this cut. |

## Example

```bash
curl -H "Authorization: Bearer $ELEMENTARY_TOKEN" \
"$BASE/$ENV_ID/latest-test-executions?test_types=elementary_cloud&limit=500"
```
46 changes: 1 addition & 45 deletions docs/api/reference/test-executions/get-a-test-execution.mdx
Original file line number Diff line number Diff line change
@@ -1,47 +1,3 @@
---
title: 'Get a test execution'
description: 'Fetch one historical execution for a test. Coming soon.'
openapi: api-reference/beta/openapi.json get /public/beta/{env_id}/tests/{test_id}/executions/{execution_id}
---

<Info icon="clock">
**Coming soon.** This endpoint is not live yet. The contract below is the
planned shape and may change. Calling it today returns `404`.
</Info>

```
GET /public/beta/{env_id}/tests/{test_id}/executions/{execution_id}
```

Path `test_id` unknown or not visible → `404`. An `execution_id` that exists
but belongs to a **different** test also returns `404`.

## Response

Bare object. Field meanings match
[Test execution history](/api/reference/test-executions/list-test-executions).

```json
{
"id": "exec_9f3c2a",
"test_id": "elementary_cloud.freshness_anomalies.analytics.orders",
"sub_test_unique_id": "elementary_cloud.freshness_anomalies.analytics.orders",
"sub_type": "freshness_anomalies",
"column_name": null,
"status": "FAIL",
"failure_count": 0,
"start_time": "2026-08-20T11:55:00Z",
"duration_seconds": 12.4,
"quality_dimension": "freshness",
"result_reason": "ANOMALY_DETECTED",
"exception": null,
"description": null,
"synced_at": "2026-08-20T11:55:10Z"
}
```

## Example

```bash
curl -H "Authorization: Bearer $ELEMENTARY_TOKEN" \
"$BASE/$ENV_ID/tests/$TEST_ID/executions/$EXECUTION_ID"
```
74 changes: 1 addition & 73 deletions docs/api/reference/test-executions/list-test-executions.mdx
Original file line number Diff line number Diff line change
@@ -1,75 +1,3 @@
---
title: 'Test execution history'
description: 'Execution history for one test. Coming soon.'
openapi: api-reference/beta/openapi.json get /public/beta/{env_id}/tests/{test_id}/executions
---

<Info icon="clock">
**Coming soon.** This endpoint is not live yet. The contract below is the
planned shape and may change. Calling it today returns `404`.
</Info>

```
GET /public/beta/{env_id}/tests/{test_id}/executions
```

History for **one** test — not an environment-wide dump of every run. Unknown
or not-visible `test_id` → `404`.

There is no `synced_since` feed on this nested list. Default lookback is the
last **30 days** (`start_time >= now - 30d`) when `start_time_from` is omitted.
Default sort is `start_time` **descending**.

Item shape is shared with
[latest test executions](/api/reference/latest-test-executions/list-latest-test-executions).
Metrics (`metric_value`, `expected_min`, `expected_max`, `chart_data`) are not
in this cut.

## Query parameters

Shared pagination: `cursor`, `limit` (default `500`, max `2000`). Filter arrays
are any-of within a param, AND across params, max `1000` values each.

| Parameter | Notes |
| ----------------- | --------------------------------------------------------------------------------------------- |
| `sub_test_ids` | Filter by `sub_test_unique_id`. |
| `statuses` | As stored: `PASS`, `WARN`, `FAIL`, `ERROR`, `SKIPPED`, `NO_DATA`. |
| `start_time_from` | Inclusive lower bound (UTC ISO-8601). Default: 30 days ago. |
| `start_time_to` | Inclusive upper bound (UTC ISO-8601). |
| `order_by` | `start_time` (default) or `id`. |
| `direction` | Default `desc` when `order_by` is omitted; otherwise `asc` unless you pass `desc`. |

## Response

List envelope `{ items, next_cursor, has_more }`.

```json
{
"items": [
{
"id": "exec_9f3c2a",
"test_id": "elementary_cloud.freshness_anomalies.analytics.orders",
"sub_test_unique_id": "elementary_cloud.freshness_anomalies.analytics.orders",
"sub_type": "freshness_anomalies",
"column_name": null,
"status": "FAIL",
"failure_count": 0,
"start_time": "2026-08-20T11:55:00Z",
"duration_seconds": 12.4,
"quality_dimension": "freshness",
"result_reason": "ANOMALY_DETECTED",
"exception": null,
"description": null,
"synced_at": "2026-08-20T11:55:10Z"
}
],
"next_cursor": "eyJ...",
"has_more": true
}
```

## Example

```bash
curl -H "Authorization: Bearer $ELEMENTARY_TOKEN" \
"$BASE/$ENV_ID/tests/$TEST_ID/executions?limit=500"
```
Loading
Loading