UiPath Documentation
industry-department-solutions
latest
false
Supply Chain & Retail Solutions API guide

Webhook event reference

Request headers, CloudEvents body, rule outcomes, size limits, retry schedule, and endpoint requirements for the data quality webhook channel.

This page specifies what an endpoint registered as a webhook alert channel receives: the HTTP request, the event body, how rule results map to outcomes, the limits applied to large runs, and how deliveries are retried.

Request​

Each delivery is a POST with a JSON body. Header names are case-insensitive and are sent in lowercase.

POST /hooks/peak HTTP/1.1
content-type: application/json
user-agent: Peak-Webhooks/1.0
webhook-id: evt_1f0c6b2a9d3e4c5f8a7b6c5d4e3f2a1b
webhook-timestamp: 1791191520
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=
x-peak-event-type: ai.peak.data_validation.run.completed
x-env: prod
POST /hooks/peak HTTP/1.1
content-type: application/json
user-agent: Peak-Webhooks/1.0
webhook-id: evt_1f0c6b2a9d3e4c5f8a7b6c5d4e3f2a1b
webhook-timestamp: 1791191520
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=
x-peak-event-type: ai.peak.data_validation.run.completed
x-env: prod
HeaderSentValue
content-typeAlwaysapplication/json
user-agentAlwaysPeak-Webhooks/1.0
webhook-idAlwaysThe event id. Identical on every retry of the same event, so it is the key to deduplicate on.
webhook-timestampAlwaysUnix time in seconds at which this attempt was sent. Fresh on every retry.
webhook-signatureauth.type is hmacv1, followed by the base64 HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<body>. Recomputed on every retry. See Verify the signature.
x-peak-event-typeAlwaysThe event type, for routing before the body is parsed.
authorizationauth.type is bearer-token or basicBearer <token>, or Basic <base64 of username:password>.
<headerName>auth.type is api-keyThe key, in the header named by auth.headerName (default X-API-Key).
Static headersWhen the channel defines headersThe configured names and values, as given.

Event body​

The body is a CloudEvents 1.0 envelope in structured JSON mode. One event is sent per validation run per channel. A run covers one or more tables of a solution, and the event carries the rules of that run which name the channel, narrowed to the outcomes the channel subscribes to, nested under the table each rule checked.

In this example the run covered three tables of orders-pipeline. Three rules name the channel, which subscribes to every outcome: on stage.orders the freshness check failed and the missing-data check produced a warning, and on stage.order_items the foreign-key check passed. No rule on stage.customers names the channel, so that table appears in run.tables only:

{
  "specversion": "1.0",
  "id": "evt_1f0c6b2a9d3e4c5f8a7b6c5d4e3f2a1b",
  "type": "ai.peak.data_validation.run.completed",
  "source": "/peak/prod/data-validation/acme",
  "subject": "orders-pipeline",
  "time": "2026-10-14T09:12:00.123Z",
  "datacontenttype": "application/json",
  "data": {
    "tenant": { "name": "acme", "id": "1234" },
    "run": {
      "id": "e3f1c2a4-9b77-4d21-8c5e-1a2b3c4d5e6f",
      "tables": ["stage.orders", "stage.order_items", "stage.customers"]
    },
    "solution": "orders-pipeline",
    "warehouseType": "snowflake",
    "outcome": "failed",
    "matched": [
      "ai.peak.data_validation.rule.failed",
      "ai.peak.data_validation.rule.passed",
      "ai.peak.data_validation.rule.warned"
    ],
    "summary": { "total": 3, "errored": 0, "failed": 1, "warned": 1, "passed": 1, "skipped": 0 },
    "tables": [
      {
        "table": "stage.orders",
        "outcome": "failed",
        "summary": { "total": 2, "errored": 0, "failed": 1, "warned": 1, "passed": 0, "skipped": 0 },
        "results": [
          {
            "rule": {
              "type": "freshness",
              "severity": "error",
              "column": "order_date",
              "params": { "column": "order_date", "threshold": 24, "unit": "hours" }
            },
            "outcome": "failed",
            "status": "failed",
            "message": "Data is stale: column 'order_date' is 50 hours old (threshold: 24 hours)",
            "observed": 50,
            "errorCodes": ["DI_E_24F01"],
            "details": {
              "last_seen": "2026-10-12 07:12:44.000",
              "threshold": { "value": 24, "unit": "hours" }
            }
          },
          {
            "rule": {
              "type": "missing_data_validation",
              "severity": "warn",
              "column": "order_date",
              "params": { "column": "order_date", "interval": 1, "unit": "days", "minRowCount": 100 }
            },
            "outcome": "warned",
            "status": "failed",
            "message": "Missing data: 2 period(s) of 1 days had fewer than 100 rows",
            "observed": 2,
            "errorCodes": ["DI_W_24M01"],
            "details": {
              "expected_min": 100,
              "slice": { "interval": 1, "unit": "days" },
              "window": { "start": "2026-09-01 00:00:00.000", "end": "2026-10-14 09:11:58.410" },
              "missing_periods": [
                { "start": "2026-10-12 00:00:00.000", "end": "2026-10-13 00:00:00.000", "actual_count": 41 },
                { "start": "2026-10-13 00:00:00.000", "end": "2026-10-14 00:00:00.000", "actual_count": 0 }
              ]
            }
          }
        ],
        "resultsTotal": 2,
        "resultsTruncated": false
      },
      {
        "table": "stage.order_items",
        "outcome": "passed",
        "summary": { "total": 1, "errored": 0, "failed": 0, "warned": 0, "passed": 1, "skipped": 0 },
        "results": [
          {
            "rule": { "type": "async_foreign_key", "severity": "warn" },
            "outcome": "passed",
            "status": "passed"
          }
        ],
        "resultsTotal": 1,
        "resultsTruncated": false
      }
    ],
    "resultsTotal": 3,
    "resultsTruncated": false,
    "links": {
      "dashboard": "https://platform.peak.ai/canvas/assets",
      "run": "https://service.peak.ai/validation-api/api/v1/validations/run/e3f1c2a4-9b77-4d21-8c5e-1a2b3c4d5e6f",
      "docs": "https://docs.uipath.com/industry-department-solutions/automation-cloud/latest/supply-chain-retail-api-guide/webhook-event-reference"
    }
  }
}
{
  "specversion": "1.0",
  "id": "evt_1f0c6b2a9d3e4c5f8a7b6c5d4e3f2a1b",
  "type": "ai.peak.data_validation.run.completed",
  "source": "/peak/prod/data-validation/acme",
  "subject": "orders-pipeline",
  "time": "2026-10-14T09:12:00.123Z",
  "datacontenttype": "application/json",
  "data": {
    "tenant": { "name": "acme", "id": "1234" },
    "run": {
      "id": "e3f1c2a4-9b77-4d21-8c5e-1a2b3c4d5e6f",
      "tables": ["stage.orders", "stage.order_items", "stage.customers"]
    },
    "solution": "orders-pipeline",
    "warehouseType": "snowflake",
    "outcome": "failed",
    "matched": [
      "ai.peak.data_validation.rule.failed",
      "ai.peak.data_validation.rule.passed",
      "ai.peak.data_validation.rule.warned"
    ],
    "summary": { "total": 3, "errored": 0, "failed": 1, "warned": 1, "passed": 1, "skipped": 0 },
    "tables": [
      {
        "table": "stage.orders",
        "outcome": "failed",
        "summary": { "total": 2, "errored": 0, "failed": 1, "warned": 1, "passed": 0, "skipped": 0 },
        "results": [
          {
            "rule": {
              "type": "freshness",
              "severity": "error",
              "column": "order_date",
              "params": { "column": "order_date", "threshold": 24, "unit": "hours" }
            },
            "outcome": "failed",
            "status": "failed",
            "message": "Data is stale: column 'order_date' is 50 hours old (threshold: 24 hours)",
            "observed": 50,
            "errorCodes": ["DI_E_24F01"],
            "details": {
              "last_seen": "2026-10-12 07:12:44.000",
              "threshold": { "value": 24, "unit": "hours" }
            }
          },
          {
            "rule": {
              "type": "missing_data_validation",
              "severity": "warn",
              "column": "order_date",
              "params": { "column": "order_date", "interval": 1, "unit": "days", "minRowCount": 100 }
            },
            "outcome": "warned",
            "status": "failed",
            "message": "Missing data: 2 period(s) of 1 days had fewer than 100 rows",
            "observed": 2,
            "errorCodes": ["DI_W_24M01"],
            "details": {
              "expected_min": 100,
              "slice": { "interval": 1, "unit": "days" },
              "window": { "start": "2026-09-01 00:00:00.000", "end": "2026-10-14 09:11:58.410" },
              "missing_periods": [
                { "start": "2026-10-12 00:00:00.000", "end": "2026-10-13 00:00:00.000", "actual_count": 41 },
                { "start": "2026-10-13 00:00:00.000", "end": "2026-10-14 00:00:00.000", "actual_count": 0 }
              ]
            }
          }
        ],
        "resultsTotal": 2,
        "resultsTruncated": false
      },
      {
        "table": "stage.order_items",
        "outcome": "passed",
        "summary": { "total": 1, "errored": 0, "failed": 0, "warned": 0, "passed": 1, "skipped": 0 },
        "results": [
          {
            "rule": { "type": "async_foreign_key", "severity": "warn" },
            "outcome": "passed",
            "status": "passed"
          }
        ],
        "resultsTotal": 1,
        "resultsTruncated": false
      }
    ],
    "resultsTotal": 3,
    "resultsTruncated": false,
    "links": {
      "dashboard": "https://platform.peak.ai/canvas/assets",
      "run": "https://service.peak.ai/validation-api/api/v1/validations/run/e3f1c2a4-9b77-4d21-8c5e-1a2b3c4d5e6f",
      "docs": "https://docs.uipath.com/industry-department-solutions/automation-cloud/latest/supply-chain-retail-api-guide/webhook-event-reference"
    }
  }
}

Envelope​

FieldDescription
specversionAlways 1.0.
idUnique per event: evt_ followed by 32 hexadecimal characters. Equals the webhook-id header. Two channels notified for the same run receive different ids.
typeAlways ai.peak.data_validation.run.completed. What happened is in data.outcome and data.summary.
source/peak/<environment>/data-validation/<tenant>. <environment> is prod for production, so an endpoint fed by more than one environment can tell them apart.
subject<solution>, the solution the run validated. The tables are listed in data.run.tables.
timeWhen the run completed, in RFC 3339 format, UTC, with millisecond precision.
datacontenttypeAlways application/json.
FieldDescription
tenant.name, tenant.idThe tenant the run belongs to. id is a string.
run.idThe validation run. It is the same in every event sent for that run, whichever channel receives it, so it correlates them. The full report is available from Check a validation run.
run.tablesEvery table the run covered, schema-qualified, in request order, including tables with no result in this event. Compare it with tables to tell a channel that saw part of a run from a run over one table.
solution, warehouseTypeThe solution the run validated and its warehouse, snowflake or redshift.
outcomeThe worst outcome among the carried results across every table, in the order errored, failed, warned, passed.
matchedThe channel's subscribed outcomes that are present in the carried results, as ai.peak.data_validation.rule.<outcome> names, sorted. This is why the channel was notified.
summaryCounts of the carried results across every table by outcome: total, errored, failed, warned, passed, skipped. Complete even when results are capped. Skipped rules are never carried, so skipped is 0.
tablesOne entry per table with a carried result, in the order of run.tables. See Table entry.
resultsTotal, resultsTruncatedThe number of carried results across every table, and whether any table's results holds fewer than its resultsTotal.
links.dashboard, links.run, links.docsThe Canvas asset list where the Data Quality Dashboard lives, the run report endpoint, and this documentation. For a spoke tenant, links.run is on the spoke's service host.

Table entry​

FieldDescription
tableThe schema-qualified table, as tables in the run report names it. A foreign-key result is filed under the child table.
outcomeThe worst outcome among this table's carried results, in the same order as data.outcome.
summaryCounts of this table's carried results by outcome, with the same keys as data.summary. The tables' counts add up to data.summary.
resultsThis table's carried results, ordered errored, failed, warned, passed. The cap applies across the whole event, see Size limits.
resultsTotal, resultsTruncatedThe number of this table's carried results, and whether results holds fewer than that.

Result entry​

FieldPresentDescription
rule.typeAlwaysfreshness, missing_data_validation, or async_foreign_key.
rule.severityAlwayserror or warn, from the validation entry.
rule.columnWhen the rule measures a columnThe column, for freshness and missing_data_validation.
rule.paramsWhen the rule has parametersThe parameters the rule was evaluated with.
outcomeAlwaysfailed, warned, errored, or passed. See Rule outcomes.
statusAlwaysThe raw run status: passed, failed, or error.
messageProblems onlyThe human-readable result, the same text a Slack or email alert shows. For an errored result, why the rule was not evaluated.
observedProblems, when measuredThe measurement: the age of the newest record for freshness, the number of short periods for missing_data_validation, the number of orphan rows for async_foreign_key.
errorCodesProblems onlyThe DI_E_ or DI_W_ codes of the result. See Results.
detailsProblems, when availableRule-specific evidence: last_seen and threshold for freshness; expected_min, slice, window, and missing_periods for missing data; constraints and totalOrphanRows for foreign keys. Lists are sampled, see Size limits.
detailsOmittedWhen details was dropped for sizetrue when a rule's details exceeded 2 KB and were left out.

Passing results carry only rule, outcome, and status, so a receiver sees what was checked without the evidence a problem needs.

Rule outcomes​

A result's outcome is its status read through its severity. The outcome names, prefixed ai.peak.data_validation.rule., are the values a channel's events list accepts.

statusseverityOutcomeSubscription value
failederrorfailedai.peak.data_validation.rule.failed
failedwarnwarnedai.peak.data_validation.rule.warned
erroranyerroredai.peak.data_validation.rule.errored
passedanypassedai.peak.data_validation.rule.passed
skippedanyskippedNone. Skipped rules are never delivered.

The names mean the following:

  • failed: the check ran and failed, and the rule has severity: error.
  • warned: the check ran and failed, and the rule has severity: warn.
  • errored: the rule could not be evaluated. Every rule of a table whose validation timed out or whose configuration is invalid ends this way; message gives the reason, and the service logs have the rest.
  • passed: the check held.

A channel's event carries the rules that name the channel and whose outcome is in its events list, which defaults to all four for a webhook. A run in which none of the carried rules has a listed outcome produces no event. A run whose carried rules all passed has outcome: passed and reaches only channels subscribed to ai.peak.data_validation.rule.passed.

To gate a pipeline on a run, subscribe to all four outcomes. A channel that subscribes to a subset sees only that subset, so a channel subscribed to ai.peak.data_validation.rule.passed alone receives outcome: passed for a run that failed on checks it does not carry.

Size limits​

LimitBehavior
Results per eventAt most 100 across all tables. Beyond that, the 100 worst results in outcome order are kept and placed under their tables; data.resultsTotal has the full count and data.resultsTruncated is true. A table whose results were all cut still appears with its outcome, summary, and resultsTotal, with results empty and resultsTruncated: true.
Lists inside details (missing_periods, missing_dates)Longer than 20 items, the last 20 are kept, with <key>_total and <key>_truncated: true alongside.
details per resultLarger than 2 KB after sampling, the details are replaced by detailsOmitted: true.
Whole bodyAbout 60 KB. If a body is larger, details is dropped from every result; if it is still too large, the results cap is halved repeatedly, down to none. Every table stays listed, and summary and resultsTotal stay complete at both levels.

Delivery and retries​

An event is handed to Peak's delivery service when the run completes. At that point the run report lists the channel in alerts_sent, which records that the event was accepted for delivery, not that your endpoint received it.

AspectBehavior
RequestPOST, with the body serialised once. The endpoint must respond within 10 seconds (5 seconds for the verification test event). The response body is ignored.
SuccessAny 2xx status.
RedirectsNever followed. A 3xx is a permanent failure.
Retried408, 425, 429, any 5xx, a timeout, and connection or TLS failures. Six attempts in total, the retries after 10 seconds, 1 minute, 5 minutes, 30 minutes, and 2 hours. A Retry-After header on a 429 or 5xx response lengthens the wait, within 5 seconds to 1 hour. After the sixth failed attempt the event is dropped.
Not retried3xx, 410, 401 or 403 when a credential was sent, any other 4xx, a hostname that does not resolve, a URL that fails the endpoint requirements, and a credential that is missing, expired, or in the wrong format. Fix the cause; the next run delivers normally.
RetriesCarry the same webhook-id and body, with a new webhook-timestamp and signature. Delivery is at-least-once, so deduplicate on webhook-id.
OrderNot guaranteed. A retried older event can arrive after a newer one; time and data.run.id tell them apart.
Source addressesDeliveries originate from the Peak platform. If your endpoint restricts callers by IP address, contact support for the addresses to allow.

Endpoint requirements​

  • https, on port 443. An explicit :443 is accepted.
  • A public, fully qualified hostname. IP addresses, localhost, single-label names, and names ending in .local, .localhost, .internal, .svc, or .cluster.local are rejected when the channel is registered.
  • Every address the hostname resolves to must be public. A name that resolves to a private, loopback, or link-local address is refused at send time with the reason egress_blocked, and the check is repeated on every delivery.
  • TLS 1.2 or later, with a certificate issued by a public certificate authority. A self-signed certificate fails as a network error.
  • No embedded credentials and no fragment in the URL. A query string is allowed.
  • A 2xx response within the timeout. Accept the event, then process it; a slow handler is retried as a timeout, and the retries repeat the same event.

Verification test event​

Registering, updating, or verifying a channel sends one ai.peak.webhook.ping event to the URL, with the same headers and signature as a delivery and x-peak-event-type: ai.peak.webhook.ping. The channel is stored only if the endpoint answers 2xx within 5 seconds.

{
  "specversion": "1.0",
  "id": "evt_7c1b9e7a-5d2f-4a1e-9b3c-2f6d8e0a4c11",
  "type": "ai.peak.webhook.ping",
  "source": "/peak/prod/notifications/acme",
  "subject": "alerts.example.com",
  "time": "2026-10-05T09:11:58.410Z",
  "datacontenttype": "application/json",
  "data": {
    "message": "Test event sent to verify this webhook destination. No action is required.",
    "tenant": { "id": "1234", "name": "acme" }
  }
}
{
  "specversion": "1.0",
  "id": "evt_7c1b9e7a-5d2f-4a1e-9b3c-2f6d8e0a4c11",
  "type": "ai.peak.webhook.ping",
  "source": "/peak/prod/notifications/acme",
  "subject": "alerts.example.com",
  "time": "2026-10-05T09:11:58.410Z",
  "datacontenttype": "application/json",
  "data": {
    "message": "Test event sent to verify this webhook destination. No action is required.",
    "tenant": { "id": "1234", "name": "acme" }
  }
}

Compatibility​

Fields are only ever added within an event type, so a receiver must ignore fields and enumeration values it does not recognise. id, type, source, subject, data.run.id, data.outcome, and data.summary keep their meaning. A breaking change ships as a new type.

Was this page helpful?

Connect

Need help? Support

Want to learn? UiPath Academy

Have questions? UiPath Forum

Stay updated