generated: '2026-07-31' method: derived source: >- openapi/anomalo-public-api-openapi.yml + openapi/anomalo-unstructured-openapi.yml (path structure and id-reference parameters), enriched with field lists read verbatim from the first-party MCP server's tool docstrings note: >- Entity-relationship graph for the Anomalo platform, derived from path nesting and id-reference parameters across 100 operations. Anomalo publishes no object reference, so entity FIELDS are only listed where a first-party artifact enumerates them (the MCP tool docstrings do, for organizations, labels, checks, check results, data profiles and document collections). Entities without a published field list are described by their relationships and addressing only, rather than inventing a schema. root: Organization entities: - name: Organization description: >- A tenant within an Anomalo deployment. The root scoping entity: API calls resolve against the caller's ACTIVE organization, which is sticky server-side state rather than a request parameter. addressing: - GET /organizations - GET /organization - PUT /organization - POST /deployment/organization - path segment /orgs/{org_id}/ (unstructured endpoints only) fields: - name: id type: integer - name: name type: string - name: is_active type: boolean note: Computed by the MCP server, not returned by the API. fields_source: get_organizations MCP tool docstring relationships: - has_many: Warehouse - has_many: Label - has_many: User - has_many: AccessGroup - has_many: NotificationChannel - has_many: DocumentCollection via: /orgs/{org_id}/document_collections - name: Warehouse description: >- A connected data warehouse or lakehouse (Snowflake, Databricks, BigQuery, Redshift and similar). Crawled to discover schemas and tables. addressing: - GET /list_warehouses - GET /warehouse/{warehouse_id} - POST /warehouse - PUT /warehouse/{warehouse_id} - DELETE /warehouse/{warehouse_id} - PUT /warehouse/{warehouse_id}/refresh - PUT /warehouse/{warehouse_id}/refresh/new relationships: - belongs_to: Organization - has_many: Table via: warehouse_id - name: Table description: >- A table in a connected warehouse. The central entity of the platform: monitoring, profiling, checks, labels, documentation, lineage and access control all hang off it. addressing: - GET /tables - GET /configured_tables - GET /get_table_information - POST /tables - POST /configure_table - POST /tables/configure - GET /tables/{table_id}/config - PATCH /tables/{table_id}/config identifiers: - name: table_id type: integer primary: true - name: fully qualified name pattern: warehouse_name.schema.table_name note: Accepted as an alternative to table_id by get_table_information and get_table_profile. fields: - name: id - name: name - name: full_name - name: description - name: monitored - name: url - name: warehouse_id - name: warehouse_name - name: warehouse_type fields_source: find_tables_with_label MCP prompt schema relationships: - belongs_to: Warehouse via: warehouse_id - has_many: Check via: table_id - has_one: DataProfile via: table_id - has_many: Label via: /tables/{table_id}/labels - has_one: TableDocumentation via: /tables/{table_id}/documentation - has_many: LineageEdge via: /tables/{table_id}/lineage/upstream and /downstream - has_many: AccessGroup via: /tables/{table_id}/access_groups - has_many: SensitiveColumn - name: Check description: >- A data quality check configured on a table. Either declaratively configured or generated by Anomalo's unsupervised anomaly detection. addressing: - GET /get_checks_for_table - POST /create_check - POST /delete_check - POST /clone_check - PATCH /tables/{table_id}/checks/id/{check_id} - PATCH /tables/{table_id}/checks/static_id/{static_id} - PATCH /tables/{table_id}/checks/ref/{ref} identifiers: - name: check_id type: integer primary: true note: Does not survive delete-and-recreate. - name: check_static_id type: string durable: true note: >- User-set durable identifier, explicitly designed so external systems can reference a check across delete-and-recreate cycles. - name: ref type: string note: A third addressing mode for updates. fields: - name: check_id - name: check_static_id - name: name - name: description - name: active - name: severity fields_source: get_checks_for_table MCP tool docstring relationships: - belongs_to: Table via: table_id - has_many: Label via: /checks/{check_id}/labels - has_many: CheckResult - name: CheckRun description: >- One execution of some or all of a table's checks. Triggered asynchronously; polled to completion. addressing: - POST /run_checks - GET /get_run_result - GET /get_check_intervals - GET /get_run_result_triage_history identifiers: - name: check_run_id - name: job_id note: The client accepts either when fetching results. execution_status: [pending, running, completed, failed] relationships: - belongs_to: Table via: table_id - has_many: CheckResult - has_many: TriageHistoryEntry - name: CheckResult description: >- The outcome of one check within one check run, including root cause analysis and links to sample rows. fields: - name: check_id - name: check_run_id - name: execution_status - name: completed_at - name: labels - name: check_errored - name: check_skipped - name: check_passed - name: check_failed - name: result_message - name: exception_msg - name: check_history_message - name: statistic_name - name: statistic_value - name: statistic_context - name: url_for_csv_of_sample_of_bad_rows - name: sql_for_bad_rows - name: url_for_csv_of_sample_of_good_rows - name: sql_for_good_rows fields_source: get_table_check_status MCP tool docstring note: >- The CSV URLs require an authenticated browser session and cannot be fetched programmatically — a real constraint for any agent consuming failed-check evidence. relationships: - belongs_to: CheckRun via: check_run_id - belongs_to: Check via: check_id - name: DataProfile description: >- Anomalo's statistical profile of a monitored table, computed from sampled data. addressing: - GET /get_table_profile fields: - name: table_id - name: table_name - name: description - name: column_value_samples - name: data_profile_details - name: column_value_image_url - name: data_profile_image_url column_statistics: - data type - 'null %' - uniqueness - min - max - mean - median - standard deviation - skew - kurtosis fields_source: get_table_data_profile MCP tool docstring relationships: - belongs_to: Table via: table_id - name: Label description: >- An organization-level tag applied to tables and/or checks. Scoped to tables, checks, or both. addressing: - GET /org_labels - POST /org_labels - PATCH /org_labels/{label_id} - DELETE /org_labels/{label_id} - POST /org_labels/{destination_label_id}/merge fields: - name: id - name: name - name: slug note: URL-friendly, unique version of the name. - name: scope note: Whether the label applies to tables, checks, or both. fields_source: get_labels MCP tool docstring relationships: - belongs_to: Organization - has_many: Table via: /tables/{table_id}/labels - has_many: Check via: /checks/{check_id}/labels - name: LineageEdge description: A directed upstream/downstream relationship between two tables. addressing: - POST /table_lineage_edge - DELETE /table_lineage_edge - GET /tables/{table_id}/lineage/upstream - GET /tables/{table_id}/lineage/downstream parameters: - max_hops - limit - offset relationships: - belongs_to: Table via: table_id cardinality: self-referential many-to-many - name: User description: A user or service account in the deployment. addressing: - GET /users - POST /users - GET /users/{user_id} attributes: - name - email - role - is_service_account attributes_source: add_new_user client method signature relationships: - belongs_to: Organization - has_many: ApiKey via: /users/{user_id}/api-keys - has_many: AccessGroup via: /users/{user_id}/access_groups - name: ApiKey description: An API secret token issued to a user, with a description and an expiry. addressing: - GET /api-keys - POST /api-keys - DELETE /api-keys/{api_key_id} - GET /users/{user_id}/api-keys - POST /users/{user_id}/api-keys - DELETE /users/{user_id}/api-keys/{api_key_id} attributes: - description - expires relationships: - belongs_to: User via: user_id - name: AccessGroup description: >- The authorization primitive. Binds users and tables to policies. The largest single capability in the API — 22 of 100 operations. addressing: - GET /access_groups - POST /access_groups - GET /access_groups/{access_group_id} - PUT /access_groups/{access_group_id} - DELETE /access_groups/{access_group_id} relationships: - belongs_to: Organization - has_many: User via: /access_groups/{access_group_id}/users - has_many: Table via: /access_groups/{access_group_id}/tables - has_many: AccessGroupPolicy via: /access_groups/{access_group_id}/policies - name: AccessGroupPolicy description: A reusable permission policy that can be attached to access groups. addressing: - GET /access_group_policies - POST /access_group_policies - GET /access_group_policies/{policy_id} - PUT /access_group_policies/{policy_id} - DELETE /access_group_policies/{policy_id} relationships: - has_many: AccessGroup via: /access_groups/{access_group_id}/policies cardinality: many-to-many - name: NotificationChannel description: >- An outbound alerting destination (Slack, Microsoft Teams, email and similar). Anomalo's event egress mechanism — there is no HTTP webhook contract. addressing: - GET /list_notification_channels - GET /notification_channels/{channel_id} - POST /notification_channels - PATCH /notification_channels/{channel_id} - DELETE /notification_channels/{channel_id} relationships: - belongs_to: Organization - name: SensitiveColumn description: A column marked sensitive, governing how Anomalo samples and displays its values. addressing: - GET /sensitive_columns - PUT /sensitive_column - DELETE /sensitive_column relationships: - belongs_to: Table - name: Task description: A generic asynchronous job handle, polled to completion. addressing: - GET /task/{task_id} - name: DocumentCollection description: >- A set of unstructured documents Anomalo monitors, sourced from an object storage bucket or a warehouse table column. Experimental surface. status: experimental addressing: - GET /orgs/{org_id}/document_collections - GET /orgs/{org_id}/document_collections/{collection_id} fields: - id - name - description - organization_id - source_type - bucket_name - path_prefix - mime_types - ai_model fields_source: get_unstructured_collections MCP tool docstring relationships: - belongs_to: Organization via: org_id - has_many: Document - has_many: DocumentIssue - has_many: CollectionCheckRun - name: Document description: An individual unstructured document analyzed within a collection. status: experimental addressing: - GET /orgs/{org_id}/documents relationships: - belongs_to: DocumentCollection - has_many: DocumentIssue - name: DocumentIssue description: A data quality issue detected in unstructured content. status: experimental addressing: - GET /orgs/{org_id}/document_issues - GET /orgs/{org_id}/issues - GET /orgs/{org_id}/document_collections/{collection_id}/issues relationships_summary: - Organization has_many Warehouse - Warehouse has_many Table - Table has_many Check - Table has_one DataProfile - Table has_many LineageEdge (self-referential) - Check has_many CheckResult - CheckRun has_many CheckResult - Organization has_many User - User has_many ApiKey - AccessGroup has_many User (many-to-many) - AccessGroup has_many Table (many-to-many) - AccessGroup has_many AccessGroupPolicy (many-to-many) - Label has_many Table (many-to-many) - Label has_many Check (many-to-many) - Organization has_many DocumentCollection - DocumentCollection has_many Document observations: - >- The graph has two distinct halves. The data-plane half (Organization → Warehouse → Table → Check → CheckRun → CheckResult) is a clean hierarchy. The control-plane half (User, ApiKey, AccessGroup, AccessGroupPolicy) is a many-to-many authorization mesh that accounts for a third of the API. - >- Table is the hub: eight of the seventeen entities relate to it directly. - >- `check_static_id` is the only durable, user-controlled identifier in the model, and it exists specifically so external systems survive check recreation. Any integration should key on it rather than on `check_id`. - >- The unstructured entities are the only ones addressed with an explicit `/orgs/{org_id}/` path segment; the rest rely on the implicit sticky active organization.