Skip to content

Latest commit

 

History

History
394 lines (282 loc) · 15.8 KB

File metadata and controls

394 lines (282 loc) · 15.8 KB

:material-api:{ .middle style="color: var(--q-brick)" } Anomalies API

This page documents the REST endpoints for working with anomalies in Qualytics. All endpoints share the base URL of your deployment (for example, https://your-instance.qualytics.io/api) and require a Bearer token.

Sections below are grouped by what you are trying to do. The same anomaly object is exchanged across reads and writes: see the Anomaly schema section for the field reference.

!!! tip For complete API documentation, including request/response schemas, visit the API docs{:target="_blank"}.

!!! note "Permissions" All endpoints require the Member global role. Most reads need the Viewer team permission on the anomaly's datastore; writes need Author (or higher), with description edits additionally requiring Editor. Ticket-link writes need the Manager global role plus Author on the datastore. Per-endpoint requirements are called out below.

Anomaly schema

Every read endpoint that returns an anomaly emits the same shape. The most relevant fields are:

Field Type Notes
id int Numeric primary identifier.
uuid string (UUID) Stable, globally unique identifier.
type "record" | "shape" Anomaly category. See Types{:target="_blank"}.
status string One of Active, Acknowledged, Resolved, Duplicate, Invalid, Discarded. See Status{:target="_blank"}.
weight int Severity score.
anomalous_records_count int Number of records flagged for record anomalies.
description string User-editable business description.
created string (ISO 8601) When the anomaly was detected.
fingerprint int Used to deduplicate recurring anomalies. See Fingerprints{:target="_blank"}.
global_tags Tag[] Tags applied to the anomaly.
assignees UserStub[] Users assigned to the anomaly. See Assignees{:target="_blank"}.
failed_checks FailedCheck[] Checks that produced the anomaly.
datastore, container, partition_scan refs Source location of the anomaly.

??? example "Example response (abbreviated)"

```json
{
  "id": 12345,
  "uuid": "8e8b9f8b-1234-4abc-9def-012345678901",
  "type": "record",
  "status": "Active",
  "weight": 54,
  "anomalous_records_count": 1,
  "description": "Customer ID is missing for new orders",
  "created": "2026-05-15T17:22:08Z",
  "fingerprint": 9182736455,
  "global_tags": [{ "id": 7, "name": "High" }],
  "assignees": [
    { "id": 42, "name": "Alice Lee", "email": "alice@example.com" }
  ],
  "failed_checks": [{ "id": 778, "rule_type": "notNull", "message": "..." }]
}
```

List and retrieve

List anomalies

Returns a paginated list of anomalies sorted by creation timestamp and severity (most recent first).

Endpoint: GET /api/anomalies

Permission: Member. Results are scoped to datastores the caller can see.

Common query parameters (all optional, most accept multiple values):

Parameter Type Description
search string Substring match on the anomaly message or ID.
status AnomalyStatusType[] Filter by status (Active, Acknowledged, Resolved, Duplicate, Invalid, Discarded).
anomaly_type "record" | "shape" Filter by anomaly type.
datastore, container int[] Scope to specific datastores or containers.
field, quality_check, rule_type varies Scope to specific fields, checks, or rule types.
tag string[] Filter by tag names.
assignee int[] Filter by anomaly assignee user IDs.
archived "include" | "only" Include or restrict to archived anomalies.
timeframe, created_date, start_date, end_date varies Time-based filters.
related_to_id int Return anomalies that share a fingerprint with the given anomaly.
sort_id, sort_created, sort_weight, sort_anomalous_records_count "asc" | "desc" Sort options.

??? example "Example request"

```bash
curl -X GET "https://your-instance.qualytics.io/api/anomalies?status=Active&assignee=42&tag=High&sort_weight=desc" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

Returns active anomalies assigned to user 42 with the tag `High`, sorted by severity descending.

Get a single anomaly

Endpoint: GET /api/anomalies/{id}

{id} accepts either the numeric ID or the UUID. Pass include_deleted=true to surface anomalies that have been soft-deleted.

??? example

```bash
curl -X GET "https://your-instance.qualytics.io/api/anomalies/12345" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

Get failed checks for an anomaly

Returns the list of checks that produced the anomaly, with the message text and the rule type for each.

Endpoint: GET /api/anomalies/{id}/failed-checks

Update

Update a single anomaly

Updates the writable fields of an anomaly. Only the fields you include in the body are changed; omitted fields are left untouched.

Endpoint: PUT /api/anomalies/{id}

Permission: Member role + Author team permission on the anomaly's datastore. Description updates additionally require Editor.

Body fields:

Field Type Description
status "Active" | "Acknowledged" Change the open-state of the anomaly. Use the delete endpoint to archive.
description string User-editable business description.
tags string[] Tag names. Replaces the current set; pass [] to clear.
assignee_ids int[] User IDs assigned to the anomaly. Replaces the current set; pass [] to unassign everyone. Each user must have at least Viewer on the datastore.

??? example "Example request"

```bash
curl -X PUT "https://your-instance.qualytics.io/api/anomalies/12345" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "Acknowledged",
    "description": "Investigating with the data engineering team",
    "tags": ["High", "Customer-Impact"],
    "assignee_ids": [42, 57]
  }'
```

Bulk update anomalies

Applies the same changes to many anomalies in one call.

Endpoint: PATCH /api/anomalies

Permission: Member role + Author team permission on each anomaly's datastore. Description updates additionally require Editor on the corresponding datastore.

Body: A list of bulk-update entries, each with the anomaly identifier plus the fields to change. Per-entry fields match the single-update body, with the addition of:

Field Type Description
id int or UUID The anomaly to update.

??? example

```bash
curl -X PATCH "https://your-instance.qualytics.io/api/anomalies" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    { "id": 12345, "status": "Acknowledged" },
    { "id": 12346, "assignee_ids": [42] },
    { "id": 12347, "tags": [] }
  ]'
```

Manage assignees

Assignees are managed via the standard update endpoints. The assignee_ids field is replace-only, so pass the full target set on every write rather than the changes you want to apply.

Endpoints:

  • PUT /api/anomalies/{id} with assignee_ids in the body for a single anomaly.
  • PATCH /api/anomalies with assignee_ids per entry for many anomalies.
  • GET /api/anomalies?assignee=<id> to filter the list by assignee.

Behavior:

  • Each user passed in assignee_ids must have at least Viewer on the anomaly's datastore. Users without access are rejected.
  • Pass assignee_ids: [] to unassign everyone.
  • To add a user to an existing set, read assignees first and submit the union. The API does not support append.
  • Auto-assignment from a check's default assignee runs only at anomaly creation and is not reachable through this endpoint. See Deep Dive · Anomaly Assignees · Inheritance{:target="_blank"}.

??? example "Set or replace the assignee list"

```bash
curl -X PUT "https://your-instance.qualytics.io/api/anomalies/12345" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "assignee_ids": [42, 57] }'
```

??? example "Clear all assignees"

```bash
curl -X PUT "https://your-instance.qualytics.io/api/anomalies/12345" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "assignee_ids": [] }'
```

??? example "Bulk-replace assignees across many anomalies"

```bash
curl -X PATCH "https://your-instance.qualytics.io/api/anomalies" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    { "id": 12345, "assignee_ids": [42, 57] },
    { "id": 12346, "assignee_ids": [42] },
    { "id": 12347, "assignee_ids": [] }
  ]'
```

See Deep Dive · Anomaly Assignees{:target="_blank"} for inheritance rules, notification behavior, and history tracking.

Archive and delete

The single-anomaly endpoint covers both the archive flow (mark with a resolution status and keep for audit) and the hard-delete flow (remove the record entirely). Bulk versions follow the same pattern.

Archive or delete a single anomaly

Endpoint: DELETE /api/anomalies/{id}

Permission: Member role + Author team permission on the anomaly's datastore.

Query parameters:

Parameter Type Description
status "Resolved" | "Duplicate" | "Invalid" | "Discarded" The archived status to apply. Required when archive=true.
archive bool true (default) archives the anomaly; false hard-deletes it. Hard-delete only works on already-archived anomalies.

Body (optional): Lets you attach a comment and tag teammates when archiving.

Field Type Description
status ArchivedAnomalyStatusType Same as the query parameter; either may be used.
comment string Comment posted to the anomaly's history when archiving.
mentioned_user_ids int[] Users to notify via @mention in the comment.

??? example "Example request: archive with a resolution comment"

```bash
curl -X DELETE "https://your-instance.qualytics.io/api/anomalies/12345?archive=true&status=Resolved" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "comment": "Resolved after backfill, see @[Alice Lee](42)",
    "mentioned_user_ids": [42]
  }'
```

??? example "Example request: hard-delete an archived anomaly"

```bash
curl -X DELETE "https://your-instance.qualytics.io/api/anomalies/12345?archive=false" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

Bulk archive or delete

Endpoint: DELETE /api/anomalies

Permission: Member role + Author team permission on each anomaly's datastore.

Body: A list of entries combining the anomaly ID with the same fields used in the single-anomaly delete (status, comment, mentioned_user_ids, archive).

??? example

```bash
curl -X DELETE "https://your-instance.qualytics.io/api/anomalies" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    { "id": 12345, "archive": true, "status": "Resolved" },
    { "id": 12346, "archive": true, "status": "Duplicate" },
    { "id": 12347, "archive": false }
  ]'
```

History and comments

Get the anomaly history

Returns the paginated change log for an anomaly: status changes, description edits, tag updates, assignee changes, and comments. Each entry carries the user who made the change and a timestamp.

Endpoint: GET /api/anomalies/{id}/history

??? example "Example response (abbreviated)"

```json
[
  {
    "transaction_id": 9876,
    "user": { "id": 1, "name": "Alice Lee" },
    "timestamp": "2026-05-15T17:22:08Z",
    "changeset": {
      "status": ["Active", "Acknowledged"],
      "assignees": [
        [{ "id": 42, "name": "Alice Lee" }],
        [{ "id": 42, "name": "Alice Lee" }, { "id": 57, "name": "Bob Patel" }]
      ]
    }
  }
]
```

Each changeset field is a [before, after] tuple, so you can reconstruct the audit trail offline.

Get comments

Returns the comments on an anomaly, newest first.

Endpoint: GET /api/anomalies/{id}/comments

Query parameters:

Parameter Type Description
start_date datetime (ISO 8601, inclusive) Lower bound on created.
end_date datetime (ISO 8601, exclusive) Upper bound on created. Lets you fetch back-to-back ranges without overlap.
include_deleted bool (default false) When true, deleted comments are included in the response.

Source records

Source records are the raw rows from the source data that contributed to a record anomaly. Two formats are available: JSON for inline display and CSV for export.

Get source records as JSON

Endpoint: GET /api/anomalies/{id}/source-record

Query parameters:

Parameter Type Description
limit int (≥1, default 10) Maximum number of rows returned.
include_masked bool (default false) When true, returns raw values for masked fields. Requires Editor permission on the container, and the platform writes an audit-log entry naming the masked fields you accessed.

Download source records as CSV

Endpoint: GET /api/anomalies/{id}/source-record/download

Streams a CSV file (source_records_<id>.csv). Same query parameters as the JSON endpoint.

!!! note Source records are cached for up to 8 hours. If you need fresher data, see the Refresh Source Records{:target="_blank"} section.

Tickets

Manage the link between an anomaly and an external ticket (Jira, ServiceNow). Linking does not call the external system; it just records the association so the UI can render the linked ticket.

List ticket links

Endpoint: GET /api/anomalies/{anomaly_id}/ticket-links

Create a ticket link

Endpoint: POST /api/anomalies/{anomaly_id}/ticket-links

Permission: Manager global role + Author team permission on the anomaly's datastore.

Body fields:

Field Type Description
integration_id int The ticketing integration that owns this ticket.
ticket_id string External ticket identifier (e.g., the ServiceNow sys_id).
ticket_number string Human-readable ticket number (e.g., INC0010001).
ticket_url string (optional) Direct URL to the ticket.
status string Current external status of the ticket.
ticket_metadata object (optional) Additional metadata to store alongside the link.

??? example

```bash
curl -X POST "https://your-instance.qualytics.io/api/anomalies/12345/ticket-links" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_id": 3,
    "ticket_id": "abc123sys",
    "ticket_number": "INC0010001",
    "ticket_url": "https://example.service-now.com/incident.do?sys_id=abc123sys",
    "status": "New"
  }'
```

Delete a ticket link

Endpoint: DELETE /api/anomalies/{anomaly_id}/ticket-links/{link_id}

Permission: Manager global role + Author team permission on the anomaly's datastore. Removes the association only; the external ticket is left untouched.