UiPath Documentation
industry-department-solutions
latest
false
Supply Chain & Retail Solutions API guide
  • Overview
    • Introduction
    • Getting Started
    • Integration walkthrough
    • API Guide
    • Schema lifecycle
    • Object-level validations
    • Data quality alerts
    • Scheduled ingestion
    • Bulk CSV upload
    • Historical data ingestion
    • Data Quality Dashboard
    • Customizations
    • Data Onboarding Checklist
  • API Resources

Data quality alerts

Register Slack and email alert channels, then attach them to object-level validations so a failing check notifies your team.

Data quality alerts notify your team when an object-level validation fails, without anyone having to watch the Data Quality Dashboard. You register alert channels once for your tenant, then name them on the validations that should trigger them.

An alert is sent when a check finishes in a failed or error state. A check that passes sends nothing.

Before you start

  • At least one table has been rolled out with object-level validations (see Object-level validations).
  • You have a Personal Access Token (see Getting Started).
  • You know whether your tenant is on the hub (https://ingestion.peak.ai) or a spoke cluster (https://ingestion.<cluster-identifier>.peak.ai). Spoke tenants must use their spoke host.
  • For a Slack channel, you have an incoming webhook URL. Only https URLs on hooks.slack.com are accepted.
  • For an email channel, the recipient domain is allowed for your tenant. Alerts cannot be sent to an arbitrary address, so contact support to have a domain added before you register the channel.

Channel types

TypeparamsNotes
emailemail_addresses, an array of one or more addressesEvery address receives the same message. Each address must belong to a domain allowed for your tenant.
slackwebhook, an incoming webhook URLRegistration posts a test message to the webhook, so a working URL confirms itself immediately.

Register a channel

Each channel has a name that you use later on your validations. Names are unique within a tenant.

curl -X POST "https://ingestion.peak.ai/api/v2/alert-configs" \
  -H "Authorization: $PEAK_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "email",
    "name": "data-team",
    "params": { "email_addresses": ["data-team@example.com"] }
  }'
curl -X POST "https://ingestion.peak.ai/api/v2/alert-configs" \
  -H "Authorization: $PEAK_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "email",
    "name": "data-team",
    "params": { "email_addresses": ["data-team@example.com"] }
  }'

A Slack channel is registered the same way, with a webhook instead of addresses:

curl -X POST "https://ingestion.peak.ai/api/v2/alert-configs" \
  -H "Authorization: $PEAK_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "slack",
    "name": "data-alerts-channel",
    "params": { "webhook": "https://hooks.slack.com/services/T000/B000/XXXX" }
  }'
curl -X POST "https://ingestion.peak.ai/api/v2/alert-configs" \
  -H "Authorization: $PEAK_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "slack",
    "name": "data-alerts-channel",
    "params": { "webhook": "https://hooks.slack.com/services/T000/B000/XXXX" }
  }'

A successful request returns 201 Created with the stored channel and "verified": true:

{
  "type": "slack",
  "name": "data-alerts-channel",
  "params": { "webhook": "https://hooks.slack.com/services/T000/B000/XXXX" },
  "verified": true,
  "verifiedAt": 1787136239267
}
{
  "type": "slack",
  "name": "data-alerts-channel",
  "params": { "webhook": "https://hooks.slack.com/services/T000/B000/XXXX" },
  "verified": true,
  "verifiedAt": 1787136239267
}

Verification is part of registering a Slack channel. If the webhook does not return a success response, the channel is rejected with 400 Bad Request and nothing is stored, so you find out about a wrong URL straight away.

Allowed recipient domains

Email recipients are checked against a list of domains allowed for your tenant. An address outside that list is rejected with 400 Bad Request and the channel is not stored, so a customer domain has to be allowed before alerts can reach it. A domain can be allowed in full, or narrowed to specific addresses within it. Contact support to add one.

Alert emails also count towards your tenant's daily email quota, alongside any other email the platform sends on your behalf. A validation that keeps failing sends a message on every run, so a persistently failing check contributes to that total.

Manage channels

MethodPathPurpose
GET/api/v2/alert-configsList every channel registered for the tenant.
GET/api/v2/alert-configs/{name}Fetch one channel.
PUT/api/v2/alert-configs/{name}Replace a channel's type and params, then re-run verification.
DELETE/api/v2/alert-configs/{name}Delete a channel.
POST/api/v2/alert-configs/{name}/verifyRe-run verification using the stored params.

Updating a channel replaces its type and params, so send the full set of recipients rather than only the ones you are adding:

curl -X PUT "https://ingestion.peak.ai/api/v2/alert-configs/data-team" \
  -H "Authorization: $PEAK_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "email",
    "params": { "email_addresses": ["data-team@acme.com", "oncall@acme.com"] }
  }'
curl -X PUT "https://ingestion.peak.ai/api/v2/alert-configs/data-team" \
  -H "Authorization: $PEAK_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "email",
    "params": { "email_addresses": ["data-team@acme.com", "oncall@acme.com"] }
  }'

The channel is identified by the path, so a name in an update body is optional and cannot differ from it. To rename a channel, register a new one and repoint your validations.

An update re-runs verification. Changing a Slack channel's webhook to one that does not accept messages is rejected with 400 Bad Request and the stored channel is left as it was.

Use verify to confirm a Slack webhook still works, for example after someone changes the app in Slack. A webhook that no longer accepts messages returns 400 Bad Request.

Deleting a channel that a validation still names returns 409 Conflict, and the response identifies the table holding the reference. Remove the name from the validation first.

Attach channels to a validation

Add an alerts array to any freshness or missing_data_validation entry in objectValidations, listing the channel names to notify. Set it when you save a schema or update it later with Patch a solution's schema.

"objectValidations": [
  { "type": "freshness",
    "params": { "column": "order_date", "threshold": 24, "unit": "hours" },
    "enabled": true, "severity": "error",
    "alerts": ["data-team", "data-alerts-channel"] },
  { "type": "missing_data_validation",
    "params": { "column": "order_date", "interval": 1, "unit": "days", "minRowCount": 100 },
    "enabled": true, "severity": "warn",
    "alerts": ["__ALL__"] }
]
"objectValidations": [
  { "type": "freshness",
    "params": { "column": "order_date", "threshold": 24, "unit": "hours" },
    "enabled": true, "severity": "error",
    "alerts": ["data-team", "data-alerts-channel"] },
  { "type": "missing_data_validation",
    "params": { "column": "order_date", "interval": 1, "unit": "days", "minRowCount": 100 },
    "enabled": true, "severity": "warn",
    "alerts": ["__ALL__"] }
]

To add alerts to a table that is already live, send the entry through Patch a solution's schema:

curl -X PATCH "https://ingestion.peak.ai/api/v2/schema/solutions" \
  -H "Authorization: $PEAK_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "solutionName": "orders-pipeline",
    "tables": [
      {
        "objectName": "orders",
        "objectValidations": [
          { "type": "freshness",
            "params": { "column": "order_date", "threshold": 24, "unit": "hours" },
            "enabled": true, "severity": "error",
            "alerts": ["data-team"] }
        ]
      }
    ]
  }'
curl -X PATCH "https://ingestion.peak.ai/api/v2/schema/solutions" \
  -H "Authorization: $PEAK_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "solutionName": "orders-pipeline",
    "tables": [
      {
        "objectName": "orders",
        "objectValidations": [
          { "type": "freshness",
            "params": { "column": "order_date", "threshold": 24, "unit": "hours" },
            "enabled": true, "severity": "error",
            "alerts": ["data-team"] }
        ]
      }
    ]
  }'

objectValidations replaces the table's existing list rather than merging into it, so include every rule you want to keep, not only the one you are changing.

__ALL__ is a reserved name that expands to every channel registered for the tenant, so a new channel starts receiving those alerts without editing any schema. Mixing __ALL__ with an explicit name does not duplicate the message.

A name that does not match a registered channel is rejected with 400 Bad Request when you save the validation, so a typo surfaces immediately.

What an alert contains

Both channels carry the same facts, so an alert reads the same in a mailbox or a Slack channel:

FieldDescription
Tenant, Solution, TableWhere the failure happened.
CheckThe rule that failed, for example Freshness or Missing data.
Alert levelError or Warning, from the rule's severity.
MeasurementThe observed value, labelled by rule. Freshness reports the age of the newest record; missing data reports how many periods fell short.
Validation criteriaWhat the rule required, in words, for example Data must be no more than 24 hours old (order_date).
Triggered byThe caller who started the run, or Peak platform for a run with no caller.
Detected atWhen the failure was recorded, in UTC.
Run IDThe validation run, for cross-referencing with the dashboard.

Example alert

For a freshness check on stage.orders that requires data no older than 24 hours, where the newest record is 50 hours old, the email arrives with the subject [ERROR] Data validation failed: stage.orders and these details:

Tenantacme
Solutionorders-pipeline
Tablestage.orders
CheckFreshness
Alert levelError
Latest record age50 hours
Validation criteriaData must be no more than 24 hours old (order_date)
Triggered bydana@acme.com
Detected at31 Aug 2026, 09:12 UTC

The Slack message carries the same details, led by the table name so it is readable in a busy channel:

❌ Data validation failed: stage.orders

Data is stale: column 'order_date' is 50 hours old (threshold: 24 hours)

Tenant             acme                 Solution           orders-pipeline
Table              stage.orders         Check              Freshness
Alert level        Error                Latest record age  50 hours
Triggered by       dana@acme.com        Detected at        31 Aug 2026, 09:12 UTC

Validation criteria
Data must be no more than 24 hours old (order_date)

Run e3f1c2a4-9b77-4d21-8c5e-1a2b3c4d5e6f
❌ Data validation failed: stage.orders

Data is stale: column 'order_date' is 50 hours old (threshold: 24 hours)

Tenant             acme                 Solution           orders-pipeline
Table              stage.orders         Check              Freshness
Alert level        Error                Latest record age  50 hours
Triggered by       dana@acme.com        Detected at        31 Aug 2026, 09:12 UTC

Validation criteria
Data must be no more than 24 hours old (order_date)

Run e3f1c2a4-9b77-4d21-8c5e-1a2b3c4d5e6f

A missing_data_validation alert reads the same way, with Missing data as the check and a count of periods in place of the record age, for example 3 of 24 hourly periods.

Behavior to expect

  • One message is sent per failing check per channel. Two failing checks with two channels produce four messages from a single run.
  • A check that keeps failing alerts again on every run, until it passes.
  • The run report lists the channels notified for each result in alerts_sent, which is useful for confirming that a new channel is wired up.
  • A channel that cannot be reached does not fail the validation run. The run completes, and the channel is left out of alerts_sent.

Was this page helpful?

Connect

Need help? Support

Want to learn? UiPath Academy

Have questions? UiPath Forum

Stay updated