diff --git a/docs/api-reference/beta/openapi.json b/docs/api-reference/beta/openapi.json index 5e212633e..74a9dde4f 100644 --- a/docs/api-reference/beta/openapi.json +++ b/docs/api-reference/beta/openapi.json @@ -503,6 +503,11 @@ "title": "Environment", "type": "object" }, + "HistoryOrderBy": { + "enum": ["start_time", "id"], + "title": "HistoryOrderBy", + "type": "string" + }, "OrderBy": { "enum": ["id", "synced_at"], "title": "OrderBy", @@ -706,6 +711,72 @@ "title": "PaginatedResponse[TableAsset]", "type": "object" }, + "PaginatedResponse_TestExecution_": { + "properties": { + "has_more": { + "default": false, + "description": "The only signal to continue pagination; a short page may still have more items because permission filtering can trim rows.", + "title": "Has More", + "type": "boolean" + }, + "items": { + "description": "Objects returned in the current page.", + "items": { + "$ref": "#/components/schemas/TestExecution" + }, + "title": "Items", + "type": "array" + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Opaque cursor for the next page, valid only with identical query parameters.", + "title": "Next Cursor" + } + }, + "required": ["items"], + "title": "PaginatedResponse[TestExecution]", + "type": "object" + }, + "PaginatedResponse_Test_": { + "properties": { + "has_more": { + "default": false, + "description": "The only signal to continue pagination; a short page may still have more items because permission filtering can trim rows.", + "title": "Has More", + "type": "boolean" + }, + "items": { + "description": "Objects returned in the current page.", + "items": { + "$ref": "#/components/schemas/Test" + }, + "title": "Items", + "type": "array" + }, + "next_cursor": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Opaque cursor for the next page, valid only with identical query parameters.", + "title": "Next Cursor" + } + }, + "required": ["items"], + "title": "PaginatedResponse[Test]", + "type": "object" + }, "TableAsset": { "properties": { "created_at": { @@ -883,37 +954,1778 @@ ], "title": "TableAsset", "type": "object" + }, + "Test": { + "properties": { + "asset_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ID of the asset this test runs on, when known.", + "title": "Asset Id" + }, + "column_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Column the test runs on, for column-level tests.", + "title": "Column Name" + }, + "config": { + "additionalProperties": true, + "default": {}, + "description": "Test configuration as defined in the source system.", + "title": "Config", + "type": "object" + }, + "definition_type": { + "description": "Extensible enum. The test's name in the source system \u2014 dbt test name for dbt tests, test type for Elementary tests.", + "examples": [ + "not_null", + "unique", + "volume_anomalies", + "source_freshness" + ], + "title": "Definition Type", + "type": "string" + }, + "deleted_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Soft-delete timestamp. Present only in the `deleted_since` feed.", + "title": "Deleted At" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Description from the source platform.", + "title": "Description" + }, + "disabled": { + "description": "Whether the test is disabled. Disabled tests are omitted from list responses unless `disabled=true` is passed.", + "title": "Disabled", + "type": "boolean" + }, + "id": { + "description": "Unique test identifier.", + "title": "Id", + "type": "string" + }, + "name": { + "description": "Test name.", + "title": "Name", + "type": "string" + }, + "owners": { + "default": [], + "description": "Owners assigned to the test.", + "items": { + "type": "string" + }, + "title": "Owners", + "type": "array" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Logical path of the test in its project tree.", + "title": "Path" + }, + "project": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Project the test belongs to, when known.", + "title": "Project" + }, + "severity": { + "description": "Configured severity of the test.", + "examples": ["ERROR", "WARNING"], + "title": "Severity", + "type": "string" + }, + "source_type": { + "description": "Extensible enum. Integration that synced this test. New values may be added over time.", + "examples": ["dbt", "elementary_cloud", "python_sdk"], + "title": "Source Type", + "type": "string" + }, + "synced_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When Elementary last synced this test definition. Bumped by definition changes only \u2014 new executions do not bump it. Use with `synced_since` for incremental reads.", + "title": "Synced At" + }, + "tags": { + "default": [], + "description": "Tags assigned to the test.", + "items": { + "type": "string" + }, + "title": "Tags", + "type": "array" + }, + "test_type": { + "description": "Extensible enum. Elementary's category for the test. New values may be added over time.", + "examples": [ + "dbt_test", + "anomaly_detection", + "schema_change", + "source_freshness", + "elementary_cloud" + ], + "title": "Test Type", + "type": "string" + }, + "updated_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When the test definition was last updated in the source platform.", + "title": "Updated At" + } + }, + "required": [ + "id", + "name", + "test_type", + "definition_type", + "source_type", + "severity", + "disabled" + ], + "title": "Test", + "type": "object" + }, + "TestExecution": { + "properties": { + "column_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Column this execution checked, when applicable.", + "title": "Column Name" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Description of the test at execution time.", + "title": "Description" + }, + "duration_seconds": { + "description": "How long the execution took.", + "title": "Duration Seconds", + "type": "number" + }, + "exception": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Error message when the execution errored.", + "title": "Exception" + }, + "failure_count": { + "description": "Number of failed rows or detected issues.", + "title": "Failure Count", + "type": "integer" + }, + "id": { + "description": "Identifier of this execution.", + "title": "Id", + "type": "string" + }, + "quality_dimension": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Extensible enum. Data-quality dimension the test covers, when classified.", + "examples": [ + "completeness", + "uniqueness", + "freshness", + "validity", + "accuracy", + "consistency" + ], + "title": "Quality Dimension" + }, + "result_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Extensible enum. Why the execution produced its status, when Elementary could determine it.", + "examples": ["PERMISSIONS_ERROR"], + "title": "Result Reason" + }, + "start_time": { + "description": "When the execution started.", + "format": "date-time", + "title": "Start Time", + "type": "string" + }, + "status": { + "description": "Extensible enum. Result of the execution. New values may be added over time.", + "examples": ["PASS", "WARN", "FAIL", "ERROR", "SKIPPED", "NO_DATA"], + "title": "Status", + "type": "string" + }, + "sub_test_unique_id": { + "description": "Stable identifier of the sub-test (a test can explode into several sub-tests, e.g. one per column). Use it to key latest executions.", + "title": "Sub Test Unique Id", + "type": "string" + }, + "sub_type": { + "description": "Sub-test type within the test (e.g. the anomaly type checked).", + "title": "Sub Type", + "type": "string" + }, + "synced_at": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "When Elementary last synced this execution.", + "title": "Synced At" + }, + "test_id": { + "description": "ID of the test that produced this execution.", + "title": "Test Id", + "type": "string" + } + }, + "required": [ + "id", + "test_id", + "sub_test_unique_id", + "sub_type", + "status", + "failure_count", + "start_time", + "duration_seconds" + ], + "title": "TestExecution", + "type": "object" + } + }, + "securitySchemes": { + "bearerAuth": { + "description": "Personal or account token.", + "scheme": "bearer", + "type": "http" + } + } + }, + "info": { + "description": "The Elementary Public API is a REST interface for programmatically reading\nElementary's assets, columns, lineage, tests, and test results for one\nenvironment.\n\n**Authentication.** Send a bearer token (personal or account token) in the\n`Authorization` header. The token resolves to an account; results are scoped to\nthe environments that token may view.\n\n**Environment scope.** Every resource lives under `/{env_id}`. Call\n`GET /environments` first to discover the ids you can access.\n\n**Pagination.** List endpoints are keyset-paginated: pass `limit` (default 500,\nmax 2000) and follow `next_cursor` until `has_more` is `false`. Cursors are opaque\nand bound to the filters that produced them \u2014 reusing a cursor with different\nfilters returns `400`.\n\n**Incremental sync.** Every dataset supports a full scan (default). Assets,\ncolumns, and tests also expose two incremental feeds: `synced_since` (upserts)\nand `deleted_since` (soft-delete tombstones). A test's `synced_at` tracks its\ndefinition \u2014 new executions do not bump it.\n\nLatest test executions and per-test execution history are **not** incremental.\nLatest executions are a full snapshot replaced in place: re-read it. Execution\nhistory is append-only and scoped to one test, filtered by `start_time_from` /\n`start_time_to` (last 30 days by default).\n\n**Rate limiting.** Requests are rate-limited per account; responses carry\n`RateLimit-*` headers and `429` responses include `Retry-After`.\n\n_Beta: the shape may change while we co-design with early adopters._\n", + "title": "Elementary Public API", + "version": "beta" + }, + "openapi": "3.1.0", + "paths": { + "/public/beta/environments": { + "get": { + "description": "Lists the environments the token can access. Each `id` is an `env_id` for the other endpoints. Call this first.", + "operationId": "list_environments_public_beta_environments_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/Environment" + }, + "title": "Response List Environments Public Beta Environments Get", + "type": "array" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Invalid cursor or request parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Authentication is required." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The token does not have permission to access the resource." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The requested resource was not found." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Request validation failed." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Rate limit exceeded.", + "headers": { + "RateLimit-Limit": { + "description": "Maximum requests allowed in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Remaining": { + "description": "Requests remaining in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Reset": { + "description": "Seconds until the current rate-limit window resets.", + "schema": { + "type": "integer" + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + } + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "An unexpected server error occurred." + } + }, + "summary": "List environments", + "tags": ["Environments"] + } + }, + "/public/beta/{env_id}/asset-lineage": { + "get": { + "description": "Lists asset-to-asset lineage edges. Full scan only. Edges are returned as-is, including edges to and from ephemeral (CTE-only) dbt models; those assets are also returned by the assets endpoints.", + "operationId": "list_asset_lineage_public_beta__env_id__asset_lineage_get", + "parameters": [ + { + "description": "Environment identifier that scopes the request.", + "in": "path", + "name": "env_id", + "required": true, + "schema": { + "description": "Environment identifier that scopes the request.", + "title": "Env Id", + "type": "string" + } + }, + { + "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", + "title": "Cursor" + } + }, + { + "description": "Maximum items to return per page (1-2000).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 500, + "description": "Maximum items to return per page (1-2000).", + "maximum": 2000, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "description": "Return only edges touching these asset ids.", + "in": "query", + "name": "asset_ids", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only edges touching these asset ids.", + "title": "Asset Ids" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedResponse_AssetLineage_" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Invalid cursor or request parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Authentication is required." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The token does not have permission to access the resource." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The requested resource was not found." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Request validation failed." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Rate limit exceeded.", + "headers": { + "RateLimit-Limit": { + "description": "Maximum requests allowed in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Remaining": { + "description": "Requests remaining in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Reset": { + "description": "Seconds until the current rate-limit window resets.", + "schema": { + "type": "integer" + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + } + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "An unexpected server error occurred." + } + }, + "summary": "List asset lineage edges", + "tags": ["Asset lineage"] + } + }, + "/public/beta/{env_id}/assets": { + "get": { + "description": "Lists lineage assets of every kind (tables, BI assets, semantic models, \u2026) with their common fields. Use `kind` to enrich a row from the typed endpoints (`/assets/tables`, `/assets/bi`). Full scan by default; pass `synced_since` for the upserts feed or `deleted_since` for the tombstones feed (mutually exclusive).", + "operationId": "list_assets_public_beta__env_id__assets_get", + "parameters": [ + { + "description": "Environment identifier that scopes the request.", + "in": "path", + "name": "env_id", + "required": true, + "schema": { + "description": "Environment identifier that scopes the request.", + "title": "Env Id", + "type": "string" + } + }, + { + "description": "Return only assets with these ids.", + "in": "query", + "name": "ids", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only assets with these ids.", + "title": "Ids" + } + }, + { + "description": "Return only assets from these source types (e.g. `dbt`, `fivetran`, `looker`).", + "in": "query", + "name": "source_types", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only assets from these source types (e.g. `dbt`, `fivetran`, `looker`).", + "title": "Source Types" + } + }, + { + "description": "Return only assets tagged with any of these tags.", + "in": "query", + "name": "tags", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only assets tagged with any of these tags.", + "title": "Tags" + } + }, + { + "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "in": "query", + "name": "synced_since", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "title": "Synced Since" + } + }, + { + "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "in": "query", + "name": "deleted_since", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "title": "Deleted Since" + } + }, + { + "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", + "title": "Cursor" + } + }, + { + "description": "Maximum items to return per page (1-2000).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 500, + "description": "Maximum items to return per page (1-2000).", + "maximum": 2000, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "description": "Sort field for a full scan. Ignored when `synced_since`/`deleted_since` is set (those feeds always order by their own cursor).", + "in": "query", + "name": "order_by", + "required": false, + "schema": { + "$ref": "#/components/schemas/OrderBy", + "default": "id", + "description": "Sort field for a full scan. Ignored when `synced_since`/`deleted_since` is set (those feeds always order by their own cursor)." + } + }, + { + "description": "Sort direction for `order_by`.", + "in": "query", + "name": "direction", + "required": false, + "schema": { + "$ref": "#/components/schemas/Direction", + "default": "asc", + "description": "Sort direction for `order_by`." + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedResponse_Asset_" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Invalid cursor or request parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Authentication is required." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The token does not have permission to access the resource." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The requested resource was not found." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Request validation failed." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Rate limit exceeded.", + "headers": { + "RateLimit-Limit": { + "description": "Maximum requests allowed in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Remaining": { + "description": "Requests remaining in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Reset": { + "description": "Seconds until the current rate-limit window resets.", + "schema": { + "type": "integer" + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + } + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "An unexpected server error occurred." + } + }, + "summary": "List assets", + "tags": ["Assets"] + } + }, + "/public/beta/{env_id}/assets/bi": { + "get": { + "description": "Lists BI assets with their BI-specific fields (`bi_platform`, `bi_type`, `url`). Full scan by default; supports the `synced_since` / `deleted_since` feeds.", + "operationId": "list_bi_assets_public_beta__env_id__assets_bi_get", + "parameters": [ + { + "description": "Environment identifier that scopes the request.", + "in": "path", + "name": "env_id", + "required": true, + "schema": { + "description": "Environment identifier that scopes the request.", + "title": "Env Id", + "type": "string" + } + }, + { + "description": "Return only BI assets with these ids.", + "in": "query", + "name": "ids", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only BI assets with these ids.", + "title": "Ids" + } + }, + { + "description": "Return only BI assets from these source types (e.g. `looker`, `sigma`).", + "in": "query", + "name": "source_types", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only BI assets from these source types (e.g. `looker`, `sigma`).", + "title": "Source Types" + } + }, + { + "description": "Return only BI assets tagged with any of these tags.", + "in": "query", + "name": "tags", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only BI assets tagged with any of these tags.", + "title": "Tags" + } + }, + { + "description": "Return only BI assets on these platforms (e.g. `looker`, `sigma`, `tableau`).", + "in": "query", + "name": "bi_platforms", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only BI assets on these platforms (e.g. `looker`, `sigma`, `tableau`).", + "title": "Bi Platforms" + } + }, + { + "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "in": "query", + "name": "synced_since", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "title": "Synced Since" + } + }, + { + "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "in": "query", + "name": "deleted_since", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "title": "Deleted Since" + } + }, + { + "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", + "title": "Cursor" + } + }, + { + "description": "Maximum items to return per page (1-2000).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 500, + "description": "Maximum items to return per page (1-2000).", + "maximum": 2000, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "description": "Sort field for a full scan. Ignored when `synced_since`/`deleted_since` is set (those feeds always order by their own cursor).", + "in": "query", + "name": "order_by", + "required": false, + "schema": { + "$ref": "#/components/schemas/OrderBy", + "default": "id", + "description": "Sort field for a full scan. Ignored when `synced_since`/`deleted_since` is set (those feeds always order by their own cursor)." + } + }, + { + "description": "Sort direction for `order_by`.", + "in": "query", + "name": "direction", + "required": false, + "schema": { + "$ref": "#/components/schemas/Direction", + "default": "asc", + "description": "Sort direction for `order_by`." + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedResponse_BiAsset_" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Invalid cursor or request parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Authentication is required." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The token does not have permission to access the resource." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The requested resource was not found." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Request validation failed." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Rate limit exceeded.", + "headers": { + "RateLimit-Limit": { + "description": "Maximum requests allowed in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Remaining": { + "description": "Requests remaining in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Reset": { + "description": "Seconds until the current rate-limit window resets.", + "schema": { + "type": "integer" + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + } + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "An unexpected server error occurred." + } + }, + "summary": "List BI assets", + "tags": ["Assets"] + } + }, + "/public/beta/{env_id}/assets/bi/{asset_id}": { + "get": { + "description": "Fetches a single BI asset by id. Returns 404 if it doesn't exist in this environment or isn't a BI asset.", + "operationId": "get_bi_asset_public_beta__env_id__assets_bi__asset_id__get", + "parameters": [ + { + "description": "Asset identifier.", + "in": "path", + "name": "asset_id", + "required": true, + "schema": { + "description": "Asset identifier.", + "title": "Asset Id", + "type": "string" + } + }, + { + "description": "Environment identifier that scopes the request.", + "in": "path", + "name": "env_id", + "required": true, + "schema": { + "description": "Environment identifier that scopes the request.", + "title": "Env Id", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BiAsset" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Invalid cursor or request parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Authentication is required." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The token does not have permission to access the resource." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The requested resource was not found." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Request validation failed." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Rate limit exceeded.", + "headers": { + "RateLimit-Limit": { + "description": "Maximum requests allowed in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Remaining": { + "description": "Requests remaining in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Reset": { + "description": "Seconds until the current rate-limit window resets.", + "schema": { + "type": "integer" + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + } + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "An unexpected server error occurred." + } + }, + "summary": "Get a BI asset", + "tags": ["Assets"] + } + }, + "/public/beta/{env_id}/assets/tables": { + "get": { + "description": "Lists warehouse table assets with their warehouse-specific fields (`data_platform`, `db_name`, `schema_name`, `table_name`, `materialization`). Full scan by default; supports the `synced_since` / `deleted_since` feeds.", + "operationId": "list_table_assets_public_beta__env_id__assets_tables_get", + "parameters": [ + { + "description": "Environment identifier that scopes the request.", + "in": "path", + "name": "env_id", + "required": true, + "schema": { + "description": "Environment identifier that scopes the request.", + "title": "Env Id", + "type": "string" + } + }, + { + "description": "Return only table assets with these ids.", + "in": "query", + "name": "ids", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only table assets with these ids.", + "title": "Ids" + } + }, + { + "description": "Return only table assets from these source types (e.g. `dbt`, `fivetran`).", + "in": "query", + "name": "source_types", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only table assets from these source types (e.g. `dbt`, `fivetran`).", + "title": "Source Types" + } + }, + { + "description": "Return only table assets tagged with any of these tags.", + "in": "query", + "name": "tags", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only table assets tagged with any of these tags.", + "title": "Tags" + } + }, + { + "description": "Return only table assets in these databases.", + "in": "query", + "name": "db_names", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only table assets in these databases.", + "title": "Db Names" + } + }, + { + "description": "Return only table assets in these schemas.", + "in": "query", + "name": "schema_names", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only table assets in these schemas.", + "title": "Schema Names" + } + }, + { + "description": "Return only table assets with these materializations (e.g. `table`, `view`, `incremental`).", + "in": "query", + "name": "materializations", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only table assets with these materializations (e.g. `table`, `view`, `incremental`).", + "title": "Materializations" + } + }, + { + "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "in": "query", + "name": "synced_since", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "title": "Synced Since" + } + }, + { + "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "in": "query", + "name": "deleted_since", + "required": false, + "schema": { + "anyOf": [ + { + "format": "date-time", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "title": "Deleted Since" + } + }, + { + "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", + "title": "Cursor" + } + }, + { + "description": "Maximum items to return per page (1-2000).", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "default": 500, + "description": "Maximum items to return per page (1-2000).", + "maximum": 2000, + "minimum": 1, + "title": "Limit", + "type": "integer" + } + }, + { + "description": "Sort field for a full scan. Ignored when `synced_since`/`deleted_since` is set (those feeds always order by their own cursor).", + "in": "query", + "name": "order_by", + "required": false, + "schema": { + "$ref": "#/components/schemas/OrderBy", + "default": "id", + "description": "Sort field for a full scan. Ignored when `synced_since`/`deleted_since` is set (those feeds always order by their own cursor)." + } + }, + { + "description": "Sort direction for `order_by`.", + "in": "query", + "name": "direction", + "required": false, + "schema": { + "$ref": "#/components/schemas/Direction", + "default": "asc", + "description": "Sort direction for `order_by`." + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedResponse_TableAsset_" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Invalid cursor or request parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Authentication is required." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The token does not have permission to access the resource." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The requested resource was not found." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Request validation failed." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Rate limit exceeded.", + "headers": { + "RateLimit-Limit": { + "description": "Maximum requests allowed in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Remaining": { + "description": "Requests remaining in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Reset": { + "description": "Seconds until the current rate-limit window resets.", + "schema": { + "type": "integer" + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + } + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "An unexpected server error occurred." + } + }, + "summary": "List table assets", + "tags": ["Assets"] } }, - "securitySchemes": { - "bearerAuth": { - "description": "Personal or account token.", - "scheme": "bearer", - "type": "http" - } - } - }, - "info": { - "description": "The Elementary Public API is a REST interface for programmatically reading\nElementary's assets, columns, and lineage for one environment.\n\n**Authentication.** Send a bearer token (personal or account token) in the\n`Authorization` header. The token resolves to an account; results are scoped to\nthe environments that token may view.\n\n**Environment scope.** Every resource lives under `/{env_id}`. Call\n`GET /environments` first to discover the ids you can access.\n\n**Pagination.** List endpoints are keyset-paginated: pass `limit` (default 500,\nmax 2000) and follow `next_cursor` until `has_more` is `false`. Cursors are opaque\nand bound to the filters that produced them \u2014 reusing a cursor with different\nfilters returns `400`.\n\n**Incremental sync.** Every dataset supports a full scan (default). Assets and\ncolumns also expose two incremental feeds: `synced_since` (upserts) and\n`deleted_since` (soft-delete tombstones).\n\n**Rate limiting.** Requests are rate-limited per account; responses carry\n`RateLimit-*` headers and `429` responses include `Retry-After`.\n\n_Beta: the shape may change while we co-design with early adopters._\n", - "title": "Elementary Public API", - "version": "beta" - }, - "openapi": "3.1.0", - "paths": { - "/public/beta/environments": { + "/public/beta/{env_id}/assets/tables/{asset_id}": { "get": { - "description": "Lists the environments the token can access. Each `id` is an `env_id` for the other endpoints. Call this first.", - "operationId": "list_environments_public_beta_environments_get", + "description": "Fetches a single table asset by id. Returns 404 if it doesn't exist in this environment or isn't a table asset.", + "operationId": "get_table_asset_public_beta__env_id__assets_tables__asset_id__get", + "parameters": [ + { + "description": "Asset identifier.", + "in": "path", + "name": "asset_id", + "required": true, + "schema": { + "description": "Asset identifier.", + "title": "Asset Id", + "type": "string" + } + }, + { + "description": "Environment identifier that scopes the request.", + "in": "path", + "name": "env_id", + "required": true, + "schema": { + "description": "Environment identifier that scopes the request.", + "title": "Env Id", + "type": "string" + } + } + ], "responses": { "200": { "content": { "application/json": { "schema": { - "items": { - "$ref": "#/components/schemas/Environment" - }, - "title": "Response List Environments Public Beta Environments Get", - "type": "array" + "$ref": "#/components/schemas/TableAsset" } } }, @@ -1016,78 +2828,35 @@ "description": "An unexpected server error occurred." } }, - "summary": "List environments", - "tags": ["Environments"] + "summary": "Get a table asset", + "tags": ["Assets"] } }, - "/public/beta/{env_id}/asset-lineage": { + "/public/beta/{env_id}/assets/{asset_id}": { "get": { - "description": "Lists asset-to-asset lineage edges. Full scan only. Edges are returned as-is, including edges to and from ephemeral (CTE-only) dbt models; those assets are also returned by the assets endpoints.", - "operationId": "list_asset_lineage_public_beta__env_id__asset_lineage_get", + "description": "Fetches a single asset (common fields) by id. Returns 404 if it doesn't exist in this environment.", + "operationId": "get_asset_public_beta__env_id__assets__asset_id__get", "parameters": [ { - "description": "Environment identifier that scopes the request.", + "description": "Asset identifier.", "in": "path", - "name": "env_id", + "name": "asset_id", "required": true, "schema": { - "description": "Environment identifier that scopes the request.", - "title": "Env Id", + "description": "Asset identifier.", + "title": "Asset Id", "type": "string" } }, { - "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", - "in": "query", - "name": "cursor", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Opaque cursor from a previous response's `next_cursor`. Reuse it only with the identical query parameters that produced it.", - "title": "Cursor" - } - }, - { - "description": "Maximum items to return per page (1-2000).", - "in": "query", - "name": "limit", - "required": false, - "schema": { - "default": 500, - "description": "Maximum items to return per page (1-2000).", - "maximum": 2000, - "minimum": 1, - "title": "Limit", - "type": "integer" - } - }, - { - "description": "Return only edges touching these asset ids.", - "in": "query", - "name": "asset_ids", - "required": false, + "description": "Environment identifier that scopes the request.", + "in": "path", + "name": "env_id", + "required": true, "schema": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - { - "type": "null" - } - ], - "description": "Return only edges touching these asset ids.", - "title": "Asset Ids" + "description": "Environment identifier that scopes the request.", + "title": "Env Id", + "type": "string" } } ], @@ -1096,7 +2865,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PaginatedResponse_AssetLineage_" + "$ref": "#/components/schemas/Asset" } } }, @@ -1199,14 +2968,14 @@ "description": "An unexpected server error occurred." } }, - "summary": "List asset lineage edges", - "tags": ["Asset lineage"] + "summary": "Get an asset", + "tags": ["Assets"] } }, - "/public/beta/{env_id}/assets": { + "/public/beta/{env_id}/column-lineage": { "get": { - "description": "Lists lineage assets of every kind (tables, BI assets, semantic models, \u2026) with their common fields. Use `kind` to enrich a row from the typed endpoints (`/assets/tables`, `/assets/bi`). Full scan by default; pass `synced_since` for the upserts feed or `deleted_since` for the tombstones feed (mutually exclusive).", - "operationId": "list_assets_public_beta__env_id__assets_get", + "description": "Lists column-to-column lineage edges, one record per edge (mirroring the asset-lineage shape). Full scan by default; the `synced_since` / `deleted_since` feeds filter on the downstream column's timestamps.", + "operationId": "list_column_lineage_public_beta__env_id__column_lineage_get", "parameters": [ { "description": "Environment identifier that scopes the request.", @@ -1220,31 +2989,9 @@ } }, { - "description": "Return only assets with these ids.", - "in": "query", - "name": "ids", - "required": false, - "schema": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - { - "type": "null" - } - ], - "description": "Return only assets with these ids.", - "title": "Ids" - } - }, - { - "description": "Return only assets from these source types (e.g. `dbt`, `fivetran`, `looker`).", + "description": "Return only edges whose downstream column is in this set.", "in": "query", - "name": "source_types", + "name": "column_ids", "required": false, "schema": { "anyOf": [ @@ -1259,14 +3006,14 @@ "type": "null" } ], - "description": "Return only assets from these source types (e.g. `dbt`, `fivetran`, `looker`).", - "title": "Source Types" + "description": "Return only edges whose downstream column is in this set.", + "title": "Column Ids" } }, { - "description": "Return only assets tagged with any of these tags.", + "description": "Return only edges whose downstream column belongs to these asset ids.", "in": "query", - "name": "tags", + "name": "asset_ids", "required": false, "schema": { "anyOf": [ @@ -1281,12 +3028,12 @@ "type": "null" } ], - "description": "Return only assets tagged with any of these tags.", - "title": "Tags" + "description": "Return only edges whose downstream column belongs to these asset ids.", + "title": "Asset Ids" } }, { - "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "description": "Upserts feed: edges whose downstream column `synced_at` >= this time (inclusive). Orders by `synced_at`.", "in": "query", "name": "synced_since", "required": false, @@ -1300,12 +3047,12 @@ "type": "null" } ], - "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "description": "Upserts feed: edges whose downstream column `synced_at` >= this time (inclusive). Orders by `synced_at`.", "title": "Synced Since" } }, { - "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "description": "Tombstones feed: edges whose downstream column `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", "in": "query", "name": "deleted_since", "required": false, @@ -1319,7 +3066,7 @@ "type": "null" } ], - "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "description": "Tombstones feed: edges whose downstream column `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", "title": "Deleted Since" } }, @@ -1383,7 +3130,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PaginatedResponse_Asset_" + "$ref": "#/components/schemas/PaginatedResponse_ColumnLineage_" } } }, @@ -1486,14 +3233,14 @@ "description": "An unexpected server error occurred." } }, - "summary": "List assets", - "tags": ["Assets"] + "summary": "List column lineage", + "tags": ["Column lineage"] } }, - "/public/beta/{env_id}/assets/bi": { + "/public/beta/{env_id}/columns": { "get": { - "description": "Lists BI assets with their BI-specific fields (`bi_platform`, `bi_type`, `url`). Full scan by default; supports the `synced_since` / `deleted_since` feeds.", - "operationId": "list_bi_assets_public_beta__env_id__assets_bi_get", + "description": "Lists asset columns. Full scan by default; pass `synced_since` for the upserts feed or `deleted_since` for the tombstones feed.", + "operationId": "list_columns_public_beta__env_id__columns_get", "parameters": [ { "description": "Environment identifier that scopes the request.", @@ -1507,7 +3254,7 @@ } }, { - "description": "Return only BI assets with these ids.", + "description": "Return only columns with these ids.", "in": "query", "name": "ids", "required": false, @@ -1524,36 +3271,14 @@ "type": "null" } ], - "description": "Return only BI assets with these ids.", + "description": "Return only columns with these ids.", "title": "Ids" } }, { - "description": "Return only BI assets from these source types (e.g. `looker`, `sigma`).", - "in": "query", - "name": "source_types", - "required": false, - "schema": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - { - "type": "null" - } - ], - "description": "Return only BI assets from these source types (e.g. `looker`, `sigma`).", - "title": "Source Types" - } - }, - { - "description": "Return only BI assets tagged with any of these tags.", + "description": "Return only columns belonging to these asset ids.", "in": "query", - "name": "tags", + "name": "asset_ids", "required": false, "schema": { "anyOf": [ @@ -1568,14 +3293,14 @@ "type": "null" } ], - "description": "Return only BI assets tagged with any of these tags.", - "title": "Tags" + "description": "Return only columns belonging to these asset ids.", + "title": "Asset Ids" } }, { - "description": "Return only BI assets on these platforms (e.g. `looker`, `sigma`, `tableau`).", + "description": "Return only columns with these data types.", "in": "query", - "name": "bi_platforms", + "name": "data_types", "required": false, "schema": { "anyOf": [ @@ -1590,12 +3315,12 @@ "type": "null" } ], - "description": "Return only BI assets on these platforms (e.g. `looker`, `sigma`, `tableau`).", - "title": "Bi Platforms" + "description": "Return only columns with these data types.", + "title": "Data Types" } }, { - "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "description": "Upserts feed: columns whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", "in": "query", "name": "synced_since", "required": false, @@ -1609,12 +3334,12 @@ "type": "null" } ], - "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "description": "Upserts feed: columns whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", "title": "Synced Since" } }, { - "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "description": "Tombstones feed: columns whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", "in": "query", "name": "deleted_since", "required": false, @@ -1628,7 +3353,7 @@ "type": "null" } ], - "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "description": "Tombstones feed: columns whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", "title": "Deleted Since" } }, @@ -1692,7 +3417,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PaginatedResponse_BiAsset_" + "$ref": "#/components/schemas/PaginatedResponse_Column_" } } }, @@ -1795,23 +3520,23 @@ "description": "An unexpected server error occurred." } }, - "summary": "List BI assets", - "tags": ["Assets"] + "summary": "List columns", + "tags": ["Columns"] } }, - "/public/beta/{env_id}/assets/bi/{asset_id}": { + "/public/beta/{env_id}/columns/{column_id}": { "get": { - "description": "Fetches a single BI asset by id. Returns 404 if it doesn't exist in this environment or isn't a BI asset.", - "operationId": "get_bi_asset_public_beta__env_id__assets_bi__asset_id__get", + "description": "Fetches a single column by id. Returns 404 if it doesn't exist in this environment.", + "operationId": "get_column_public_beta__env_id__columns__column_id__get", "parameters": [ { - "description": "Asset identifier.", + "description": "Column identifier.", "in": "path", - "name": "asset_id", + "name": "column_id", "required": true, "schema": { - "description": "Asset identifier.", - "title": "Asset Id", + "description": "Column identifier.", + "title": "Column Id", "type": "string" } }, @@ -1832,7 +3557,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BiAsset" + "$ref": "#/components/schemas/Column" } } }, @@ -1935,14 +3660,14 @@ "description": "An unexpected server error occurred." } }, - "summary": "Get a BI asset", - "tags": ["Assets"] + "summary": "Get a column", + "tags": ["Columns"] } }, - "/public/beta/{env_id}/assets/tables": { + "/public/beta/{env_id}/latest-test-executions": { "get": { - "description": "Lists warehouse table assets with their warehouse-specific fields (`data_platform`, `db_name`, `schema_name`, `table_name`, `materialization`). Full scan by default; supports the `synced_since` / `deleted_since` feeds.", - "operationId": "list_table_assets_public_beta__env_id__assets_tables_get", + "description": "Lists the most recent execution of every sub-test \u2014 a full snapshot of current test results. Not an incremental feed: rows are replaced in place, so re-read the snapshot instead of passing `synced_since`. Executions of disabled tests are omitted unless `disabled=true` is passed, and executions whose test was deleted are never returned.", + "operationId": "list_latest_test_executions_public_beta__env_id__latest_test_executions_get", "parameters": [ { "description": "Environment identifier that scopes the request.", @@ -1956,9 +3681,9 @@ } }, { - "description": "Return only table assets with these ids.", + "description": "Return only executions of these sub-tests.", "in": "query", - "name": "ids", + "name": "sub_test_ids", "required": false, "schema": { "anyOf": [ @@ -1973,14 +3698,14 @@ "type": "null" } ], - "description": "Return only table assets with these ids.", - "title": "Ids" + "description": "Return only executions of these sub-tests.", + "title": "Sub Test Ids" } }, { - "description": "Return only table assets from these source types (e.g. `dbt`, `fivetran`).", + "description": "Return only executions of these tests.", "in": "query", - "name": "source_types", + "name": "test_ids", "required": false, "schema": { "anyOf": [ @@ -1995,14 +3720,14 @@ "type": "null" } ], - "description": "Return only table assets from these source types (e.g. `dbt`, `fivetran`).", - "title": "Source Types" + "description": "Return only executions of these tests.", + "title": "Test Ids" } }, { - "description": "Return only table assets tagged with any of these tags.", + "description": "Return only executions of tests on these asset ids.", "in": "query", - "name": "tags", + "name": "asset_ids", "required": false, "schema": { "anyOf": [ @@ -2017,14 +3742,14 @@ "type": "null" } ], - "description": "Return only table assets tagged with any of these tags.", - "title": "Tags" + "description": "Return only executions of tests on these asset ids.", + "title": "Asset Ids" } }, { - "description": "Return only table assets in these databases.", + "description": "Return only executions of tests of these test types.", "in": "query", - "name": "db_names", + "name": "test_types", "required": false, "schema": { "anyOf": [ @@ -2039,14 +3764,14 @@ "type": "null" } ], - "description": "Return only table assets in these databases.", - "title": "Db Names" + "description": "Return only executions of tests of these test types.", + "title": "Test Types" } }, { - "description": "Return only table assets in these schemas.", + "description": "Return only executions of tests of these definition types.", "in": "query", - "name": "schema_names", + "name": "definition_types", "required": false, "schema": { "anyOf": [ @@ -2061,14 +3786,14 @@ "type": "null" } ], - "description": "Return only table assets in these schemas.", - "title": "Schema Names" + "description": "Return only executions of tests of these definition types.", + "title": "Definition Types" } }, { - "description": "Return only table assets with these materializations (e.g. `table`, `view`, `incremental`).", + "description": "Return only executions from these source types (e.g. `dbt`, `elementary_cloud`).", "in": "query", - "name": "materializations", + "name": "source_types", "required": false, "schema": { "anyOf": [ @@ -2083,46 +3808,48 @@ "type": "null" } ], - "description": "Return only table assets with these materializations (e.g. `table`, `view`, `incremental`).", - "title": "Materializations" + "description": "Return only executions from these source types (e.g. `dbt`, `elementary_cloud`).", + "title": "Source Types" } }, { - "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "description": "Return only executions with these statuses, as stored (e.g. `PASS`, `WARN`, `FAIL`, `ERROR`, `SKIPPED`, `NO_DATA`).", "in": "query", - "name": "synced_since", + "name": "statuses", "required": false, "schema": { "anyOf": [ { - "format": "date-time", - "type": "string" + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" }, { "type": "null" } ], - "description": "Upserts feed: assets whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", - "title": "Synced Since" + "description": "Return only executions with these statuses, as stored (e.g. `PASS`, `WARN`, `FAIL`, `ERROR`, `SKIPPED`, `NO_DATA`).", + "title": "Statuses" } }, { - "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "description": "Disabled tests' executions are omitted by default. Pass `true` to return only the disabled ones, `false` for the default (enabled only).", "in": "query", - "name": "deleted_since", + "name": "disabled", "required": false, "schema": { "anyOf": [ { - "format": "date-time", - "type": "string" + "type": "boolean" }, { "type": "null" } ], - "description": "Tombstones feed: assets whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", - "title": "Deleted Since" + "description": "Disabled tests' executions are omitted by default. Pass `true` to return only the disabled ones, `false` for the default (enabled only).", + "title": "Disabled" } }, { @@ -2185,7 +3912,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PaginatedResponse_TableAsset_" + "$ref": "#/components/schemas/PaginatedResponse_TestExecution_" } } }, @@ -2288,23 +4015,23 @@ "description": "An unexpected server error occurred." } }, - "summary": "List table assets", - "tags": ["Assets"] + "summary": "List latest test executions", + "tags": ["Latest test executions"] } }, - "/public/beta/{env_id}/assets/tables/{asset_id}": { + "/public/beta/{env_id}/latest-test-executions/{sub_test_unique_id}": { "get": { - "description": "Fetches a single table asset by id. Returns 404 if it doesn't exist in this environment or isn't a table asset.", - "operationId": "get_table_asset_public_beta__env_id__assets_tables__asset_id__get", + "description": "Fetches the most recent execution of a single sub-test by its `sub_test_unique_id`. Returns 404 if it doesn't exist in this environment or its test was deleted.", + "operationId": "get_latest_test_execution_public_beta__env_id__latest_test_executions__sub_test_unique_id__get", "parameters": [ { - "description": "Asset identifier.", + "description": "Sub-test identifier (`sub_test_unique_id`).", "in": "path", - "name": "asset_id", + "name": "sub_test_unique_id", "required": true, "schema": { - "description": "Asset identifier.", - "title": "Asset Id", + "description": "Sub-test identifier (`sub_test_unique_id`).", + "title": "Sub Test Unique Id", "type": "string" } }, @@ -2325,7 +4052,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TableAsset" + "$ref": "#/components/schemas/TestExecution" } } }, @@ -2428,26 +4155,15 @@ "description": "An unexpected server error occurred." } }, - "summary": "Get a table asset", - "tags": ["Assets"] + "summary": "Get a latest test execution", + "tags": ["Latest test executions"] } }, - "/public/beta/{env_id}/assets/{asset_id}": { + "/public/beta/{env_id}/tests": { "get": { - "description": "Fetches a single asset (common fields) by id. Returns 404 if it doesn't exist in this environment.", - "operationId": "get_asset_public_beta__env_id__assets__asset_id__get", + "description": "Lists test definitions. On a full scan disabled tests are omitted unless `disabled=true` is passed; the `synced_since` and `deleted_since` feeds always include them (with `disabled: true`) so a sync can observe a test being disabled. Full scan by default; pass `synced_since` for the upserts feed or `deleted_since` for the tombstones feed (mutually exclusive). A test's `synced_at` changes when its definition changes \u2014 new executions do not bump it.", + "operationId": "list_tests_public_beta__env_id__tests_get", "parameters": [ - { - "description": "Asset identifier.", - "in": "path", - "name": "asset_id", - "required": true, - "schema": { - "description": "Asset identifier.", - "title": "Asset Id", - "type": "string" - } - }, { "description": "Environment identifier that scopes the request.", "in": "path", @@ -2458,140 +4174,99 @@ "title": "Env Id", "type": "string" } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Asset" - } - } - }, - "description": "Successful Response" - }, - "400": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" - } - } - }, - "description": "Invalid cursor or request parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" - } - } - }, - "description": "Authentication is required." - }, - "403": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" - } - } - }, - "description": "The token does not have permission to access the resource." - }, - "404": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" - } - } - }, - "description": "The requested resource was not found." }, - "422": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" + { + "description": "Return only tests with these ids.", + "in": "query", + "name": "ids", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" } - } - }, - "description": "Request validation failed." + ], + "description": "Return only tests with these ids.", + "title": "Ids" + } }, - "429": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" - } - } - }, - "description": "Rate limit exceeded.", - "headers": { - "RateLimit-Limit": { - "description": "Maximum requests allowed in the current window.", - "schema": { - "type": "integer" - } - }, - "RateLimit-Remaining": { - "description": "Requests remaining in the current window.", - "schema": { - "type": "integer" - } - }, - "RateLimit-Reset": { - "description": "Seconds until the current rate-limit window resets.", - "schema": { - "type": "integer" - } - }, - "Retry-After": { - "description": "Seconds to wait before retrying.", - "schema": { - "type": "integer" + { + "description": "Return only tests running on these asset ids.", + "in": "query", + "name": "asset_ids", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" } - } + ], + "description": "Return only tests running on these asset ids.", + "title": "Asset Ids" } }, - "500": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" + { + "description": "Return only tests of these test types.", + "in": "query", + "name": "test_types", + "required": false, + "schema": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" } - } - }, - "description": "An unexpected server error occurred." - } - }, - "summary": "Get an asset", - "tags": ["Assets"] - } - }, - "/public/beta/{env_id}/column-lineage": { - "get": { - "description": "Lists column-to-column lineage edges, one record per edge (mirroring the asset-lineage shape). Full scan by default; the `synced_since` / `deleted_since` feeds filter on the downstream column's timestamps.", - "operationId": "list_column_lineage_public_beta__env_id__column_lineage_get", - "parameters": [ + ], + "description": "Return only tests of these test types.", + "title": "Test Types" + } + }, { - "description": "Environment identifier that scopes the request.", - "in": "path", - "name": "env_id", - "required": true, + "description": "Return only tests of these definition types.", + "in": "query", + "name": "definition_types", + "required": false, "schema": { - "description": "Environment identifier that scopes the request.", - "title": "Env Id", - "type": "string" + "anyOf": [ + { + "items": { + "type": "string" + }, + "maxItems": 1000, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Return only tests of these definition types.", + "title": "Definition Types" } }, { - "description": "Return only edges whose downstream column is in this set.", + "description": "Return only tests from these source types (e.g. `dbt`, `elementary_cloud`).", "in": "query", - "name": "column_ids", + "name": "source_types", "required": false, "schema": { "anyOf": [ @@ -2606,14 +4281,14 @@ "type": "null" } ], - "description": "Return only edges whose downstream column is in this set.", - "title": "Column Ids" + "description": "Return only tests from these source types (e.g. `dbt`, `elementary_cloud`).", + "title": "Source Types" } }, { - "description": "Return only edges whose downstream column belongs to these asset ids.", + "description": "Return only tests tagged with any of these tags.", "in": "query", - "name": "asset_ids", + "name": "tags", "required": false, "schema": { "anyOf": [ @@ -2628,12 +4303,30 @@ "type": "null" } ], - "description": "Return only edges whose downstream column belongs to these asset ids.", - "title": "Asset Ids" + "description": "Return only tests tagged with any of these tags.", + "title": "Tags" } }, { - "description": "Upserts feed: edges whose downstream column `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "description": "Disabled tests are omitted by default. Pass `true` to return only the disabled ones, `false` for the default (enabled only).", + "in": "query", + "name": "disabled", + "required": false, + "schema": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disabled tests are omitted by default. Pass `true` to return only the disabled ones, `false` for the default (enabled only).", + "title": "Disabled" + } + }, + { + "description": "Upserts feed: tests whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", "in": "query", "name": "synced_since", "required": false, @@ -2647,12 +4340,12 @@ "type": "null" } ], - "description": "Upserts feed: edges whose downstream column `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "description": "Upserts feed: tests whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", "title": "Synced Since" } }, { - "description": "Tombstones feed: edges whose downstream column `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "description": "Tombstones feed: tests whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", "in": "query", "name": "deleted_since", "required": false, @@ -2666,7 +4359,7 @@ "type": "null" } ], - "description": "Tombstones feed: edges whose downstream column `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "description": "Tombstones feed: tests whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", "title": "Deleted Since" } }, @@ -2730,7 +4423,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PaginatedResponse_ColumnLineage_" + "$ref": "#/components/schemas/PaginatedResponse_Test_" } } }, @@ -2833,15 +4526,26 @@ "description": "An unexpected server error occurred." } }, - "summary": "List column lineage", - "tags": ["Column lineage"] + "summary": "List tests", + "tags": ["Tests"] } }, - "/public/beta/{env_id}/columns": { + "/public/beta/{env_id}/tests/{test_id}": { "get": { - "description": "Lists asset columns. Full scan by default; pass `synced_since` for the upserts feed or `deleted_since` for the tombstones feed.", - "operationId": "list_columns_public_beta__env_id__columns_get", + "description": "Fetches a single test by id, including disabled tests. Returns 404 if it doesn't exist in this environment.", + "operationId": "get_test_public_beta__env_id__tests__test_id__get", "parameters": [ + { + "description": "Test identifier.", + "in": "path", + "name": "test_id", + "required": true, + "schema": { + "description": "Test identifier.", + "title": "Test Id", + "type": "string" + } + }, { "description": "Environment identifier that scopes the request.", "in": "path", @@ -2852,33 +4556,151 @@ "title": "Env Id", "type": "string" } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Test" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Invalid cursor or request parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Authentication is required." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The token does not have permission to access the resource." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "The requested resource was not found." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Request validation failed." + }, + "429": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "Rate limit exceeded.", + "headers": { + "RateLimit-Limit": { + "description": "Maximum requests allowed in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Remaining": { + "description": "Requests remaining in the current window.", + "schema": { + "type": "integer" + } + }, + "RateLimit-Reset": { + "description": "Seconds until the current rate-limit window resets.", + "schema": { + "type": "integer" + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + } + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" + } + } + }, + "description": "An unexpected server error occurred." + } + }, + "summary": "Get a test", + "tags": ["Tests"] + } + }, + "/public/beta/{env_id}/tests/{test_id}/executions": { + "get": { + "description": "Lists the execution history of a single test, most recent first. Covers the last 30 days unless `start_time_from` is passed. Not an incremental feed \u2014 page through it with `start_time_from` / `start_time_to`. Returns 404 if the test doesn't exist in this environment or isn't visible to the token.", + "operationId": "list_test_executions_public_beta__env_id__tests__test_id__executions_get", + "parameters": [ + { + "description": "Test identifier.", + "in": "path", + "name": "test_id", + "required": true, + "schema": { + "description": "Test identifier.", + "title": "Test Id", + "type": "string" + } }, { - "description": "Return only columns with these ids.", - "in": "query", - "name": "ids", - "required": false, + "description": "Environment identifier that scopes the request.", + "in": "path", + "name": "env_id", + "required": true, "schema": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "maxItems": 1000, - "type": "array" - }, - { - "type": "null" - } - ], - "description": "Return only columns with these ids.", - "title": "Ids" + "description": "Environment identifier that scopes the request.", + "title": "Env Id", + "type": "string" } }, { - "description": "Return only columns belonging to these asset ids.", + "description": "Return only executions of these sub-tests.", "in": "query", - "name": "asset_ids", + "name": "sub_test_ids", "required": false, "schema": { "anyOf": [ @@ -2893,14 +4715,14 @@ "type": "null" } ], - "description": "Return only columns belonging to these asset ids.", - "title": "Asset Ids" + "description": "Return only executions of these sub-tests.", + "title": "Sub Test Ids" } }, { - "description": "Return only columns with these data types.", + "description": "Return only executions with these statuses, as stored (e.g. `PASS`, `WARN`, `FAIL`, `ERROR`, `SKIPPED`, `NO_DATA`).", "in": "query", - "name": "data_types", + "name": "statuses", "required": false, "schema": { "anyOf": [ @@ -2915,14 +4737,14 @@ "type": "null" } ], - "description": "Return only columns with these data types.", - "title": "Data Types" + "description": "Return only executions with these statuses, as stored (e.g. `PASS`, `WARN`, `FAIL`, `ERROR`, `SKIPPED`, `NO_DATA`).", + "title": "Statuses" } }, { - "description": "Upserts feed: columns whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", + "description": "Return only executions that started at or after this time. Defaults to 30 days ago.", "in": "query", - "name": "synced_since", + "name": "start_time_from", "required": false, "schema": { "anyOf": [ @@ -2934,14 +4756,14 @@ "type": "null" } ], - "description": "Upserts feed: columns whose `synced_at` >= this time (inclusive). Orders by `synced_at`.", - "title": "Synced Since" + "description": "Return only executions that started at or after this time. Defaults to 30 days ago.", + "title": "Start Time From" } }, { - "description": "Tombstones feed: columns whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", + "description": "Return only executions that started at or before this time.", "in": "query", - "name": "deleted_since", + "name": "start_time_to", "required": false, "schema": { "anyOf": [ @@ -2953,8 +4775,8 @@ "type": "null" } ], - "description": "Tombstones feed: columns whose `deleted_at` >= this time (inclusive). Orders by `deleted_at`.", - "title": "Deleted Since" + "description": "Return only executions that started at or before this time.", + "title": "Start Time To" } }, { @@ -2990,14 +4812,14 @@ } }, { - "description": "Sort field for a full scan. Ignored when `synced_since`/`deleted_since` is set (those feeds always order by their own cursor).", + "description": "Sort field for the execution history.", "in": "query", "name": "order_by", "required": false, "schema": { - "$ref": "#/components/schemas/OrderBy", - "default": "id", - "description": "Sort field for a full scan. Ignored when `synced_since`/`deleted_since` is set (those feeds always order by their own cursor)." + "$ref": "#/components/schemas/HistoryOrderBy", + "default": "start_time", + "description": "Sort field for the execution history." } }, { @@ -3007,7 +4829,7 @@ "required": false, "schema": { "$ref": "#/components/schemas/Direction", - "default": "asc", + "default": "desc", "description": "Sort direction for `order_by`." } } @@ -3017,7 +4839,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PaginatedResponse_Column_" + "$ref": "#/components/schemas/PaginatedResponse_TestExecution_" } } }, @@ -3120,23 +4942,34 @@ "description": "An unexpected server error occurred." } }, - "summary": "List columns", - "tags": ["Columns"] + "summary": "List test executions", + "tags": ["Test executions"] } }, - "/public/beta/{env_id}/columns/{column_id}": { + "/public/beta/{env_id}/tests/{test_id}/executions/{execution_id}": { "get": { - "description": "Fetches a single column by id. Returns 404 if it doesn't exist in this environment.", - "operationId": "get_column_public_beta__env_id__columns__column_id__get", + "description": "Fetches a single execution of a test. Returns 404 if the execution or the test doesn't exist in this environment, or if the execution belongs to a different test.", + "operationId": "get_test_execution_public_beta__env_id__tests__test_id__executions__execution_id__get", "parameters": [ { - "description": "Column identifier.", + "description": "Test identifier.", "in": "path", - "name": "column_id", + "name": "test_id", "required": true, "schema": { - "description": "Column identifier.", - "title": "Column Id", + "description": "Test identifier.", + "title": "Test Id", + "type": "string" + } + }, + { + "description": "Test execution identifier.", + "in": "path", + "name": "execution_id", + "required": true, + "schema": { + "description": "Test execution identifier.", + "title": "Execution Id", "type": "string" } }, @@ -3157,7 +4990,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Column" + "$ref": "#/components/schemas/TestExecution" } } }, @@ -3260,8 +5093,8 @@ "description": "An unexpected server error occurred." } }, - "summary": "Get a column", - "tags": ["Columns"] + "summary": "Get a test execution", + "tags": ["Test executions"] } } }, @@ -3272,7 +5105,7 @@ ], "servers": [ { - "url": "https://prod.api.elementary-data.com" + "url": "https://app.elementary-data.com/api" } ], "tags": [ @@ -3295,6 +5128,18 @@ { "description": "Column-level lineage edges.", "name": "Column lineage" + }, + { + "description": "Test definitions and their configuration.", + "name": "Tests" + }, + { + "description": "Most recent execution of every sub-test.", + "name": "Latest test executions" + }, + { + "description": "Execution history of a single test.", + "name": "Test executions" } ] } diff --git a/docs/api/reference/latest-test-executions/get-a-latest-test-execution.mdx b/docs/api/reference/latest-test-executions/get-a-latest-test-execution.mdx index 69765a3c3..7a2b5d5d4 100644 --- a/docs/api/reference/latest-test-executions/get-a-latest-test-execution.mdx +++ b/docs/api/reference/latest-test-executions/get-a-latest-test-execution.mdx @@ -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} --- - - - **Coming soon.** This endpoint is not live yet. The contract below is the - planned shape and may change. Calling it today returns `404`. - - -``` -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" -``` diff --git a/docs/api/reference/latest-test-executions/list-latest-test-executions.mdx b/docs/api/reference/latest-test-executions/list-latest-test-executions.mdx index 2f5993990..93edc19b0 100644 --- a/docs/api/reference/latest-test-executions/list-latest-test-executions.mdx +++ b/docs/api/reference/latest-test-executions/list-latest-test-executions.mdx @@ -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 --- - - - **Coming soon.** This endpoint is not live yet. The contract below is the - planned shape and may change. Calling it today returns `404`. - - -``` -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" -``` diff --git a/docs/api/reference/test-executions/get-a-test-execution.mdx b/docs/api/reference/test-executions/get-a-test-execution.mdx index 9bcaedd79..69be270f2 100644 --- a/docs/api/reference/test-executions/get-a-test-execution.mdx +++ b/docs/api/reference/test-executions/get-a-test-execution.mdx @@ -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} --- - - - **Coming soon.** This endpoint is not live yet. The contract below is the - planned shape and may change. Calling it today returns `404`. - - -``` -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" -``` diff --git a/docs/api/reference/test-executions/list-test-executions.mdx b/docs/api/reference/test-executions/list-test-executions.mdx index e98e0b5fd..746b6b8be 100644 --- a/docs/api/reference/test-executions/list-test-executions.mdx +++ b/docs/api/reference/test-executions/list-test-executions.mdx @@ -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 --- - - - **Coming soon.** This endpoint is not live yet. The contract below is the - planned shape and may change. Calling it today returns `404`. - - -``` -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" -``` diff --git a/docs/api/reference/tests/get-a-test.mdx b/docs/api/reference/tests/get-a-test.mdx index 9a15307fd..b02a9f4bf 100644 --- a/docs/api/reference/tests/get-a-test.mdx +++ b/docs/api/reference/tests/get-a-test.mdx @@ -1,54 +1,3 @@ --- -title: 'Get a test' -description: 'Fetch one test definition by id. Coming soon.' +openapi: api-reference/beta/openapi.json get /public/beta/{env_id}/tests/{test_id} --- - - - **Coming soon.** This endpoint is not live yet. The contract below is the - planned shape and may change. Calling it today returns `404`. - - -``` -GET /public/beta/{env_id}/tests/{test_id} -``` - -Returns a single test definition, or `404` if the id does not exist or is not -visible to this token (same as [assets](/api/authentication)). - -## Response - -Bare object (not wrapped in the list envelope). - -```json -{ - "id": "elementary_cloud.freshness_anomalies.analytics.orders", - "name": "freshness_anomalies", - "test_type": "elementary_cloud", - "definition_type": "freshness_anomalies", - "source_type": "elementary_cloud", - "asset_id": "table.analytics.orders", - "column_name": null, - "severity": "ERROR", - "disabled": false, - "config": { - "sensitivity": "medium" - }, - "tags": [], - "owners": ["data-platform"], - "description": null, - "path": "elementary_cloud/freshness_anomalies", - "project": null, - "updated_at": "2026-08-20T12:00:00Z", - "synced_at": "2026-08-20T12:00:00Z", - "deleted_at": null -} -``` - -Field meanings match [List tests](/api/reference/tests/list-tests). - -## Example - -```bash -curl -H "Authorization: Bearer $ELEMENTARY_TOKEN" \ - "$BASE/$ENV_ID/tests/$TEST_ID" -``` diff --git a/docs/api/reference/tests/list-tests.mdx b/docs/api/reference/tests/list-tests.mdx index 193731047..fa2adee03 100644 --- a/docs/api/reference/tests/list-tests.mdx +++ b/docs/api/reference/tests/list-tests.mdx @@ -1,97 +1,3 @@ --- -title: 'List tests' -description: 'List test definitions in an environment. Coming soon.' +openapi: api-reference/beta/openapi.json get /public/beta/{env_id}/tests --- - - - **Coming soon.** This endpoint is not live yet. The contract below is the - planned shape and may change. Calling it today returns `404`. - - -``` -GET /public/beta/{env_id}/tests -``` - -Returns test **definitions** (monitors and dbt tests) — not execution results. -Join [latest test executions](/api/reference/latest-test-executions/list-latest-test-executions) -on `test_id` for the current run. Table / relation name is a join to -[table assets](/api/reference/assets/list-table-assets) on `asset_id`, not a -field on the test. - -Supports a full scan and incremental feeds (`synced_since` / `deleted_since`), -same contract as [assets](/api/incremental-sync). A new run does **not** bump -`synced_at` on the test. - -## 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. Pass -exactly one of `synced_since` or `deleted_since` — not both. - -| Parameter | Notes | -| ------------------ | ---------------------------------------------------------------------------------------------- | -| `ids` | Test ids. | -| `asset_ids` | Tests on these assets. | -| `test_types` | Extensible. Examples: `elementary_cloud`, `generic`, `singular`, `source_freshness`. | -| `definition_types` | Extensible. Examples: `freshness_anomalies`, `volume_anomalies`, `not_null`, `unique`. | -| `source_types` | Extensible. Examples: `elementary_cloud`, `dbt`, `python_sdk`. | -| `tags` | Any-of tag match. | -| `disabled` | `true` or `false`. | -| `order_by` | `id` (default) or `synced_at`. Incremental feeds force `synced_at` / `deleted_at` ascending. | -| `direction` | `asc` (default) or `desc`. | -| `synced_since` | Upserts feed: tests created or updated at/after this UTC ISO-8601 timestamp. | -| `deleted_since` | Tombstones feed: tests soft-deleted at/after this timestamp. Mutually exclusive with `synced_since`. | - -## Response - -List envelope `{ items, next_cursor, has_more }`. On the `deleted_since` feed, -`deleted_at` is set and other fields are last-known. - -```json -{ - "items": [ - { - "id": "elementary_cloud.freshness_anomalies.analytics.orders", - "name": "freshness_anomalies", - "test_type": "elementary_cloud", - "definition_type": "freshness_anomalies", - "source_type": "elementary_cloud", - "asset_id": "table.analytics.orders", - "column_name": null, - "severity": "ERROR", - "disabled": false, - "config": { - "sensitivity": "medium" - }, - "tags": [], - "owners": ["data-platform"], - "description": null, - "path": "elementary_cloud/freshness_anomalies", - "project": null, - "updated_at": "2026-08-20T12:00:00Z", - "synced_at": "2026-08-20T12:00:00Z", - "deleted_at": null - } - ], - "next_cursor": "eyJ...", - "has_more": true -} -``` - -| Field | Notes | -| ----------------- | ---------------------------------------------------------------------------------------------- | -| `severity` | As stored: `ERROR` or `WARNING` (extensible string). | -| `config` | JSON pass-through (sensitivity, threshold, training period, direction, …). `{}` when none. | -| `path` | Tree path (same idea as asset `path`). Not the dbt file path. | -| `project` | dbt package / namespace, when applicable. | -| `owners` | Display names. | -| `description` | Empty string in storage is returned as `null`. | - -No `column_id` and no embedded latest results. - -## Example - -```bash -curl -H "Authorization: Bearer $ELEMENTARY_TOKEN" \ - "$BASE/$ENV_ID/tests?test_types=elementary_cloud&definition_types=freshness_anomalies,volume_anomalies&limit=500" -```