# Webhook events

> Every event you can subscribe to, by capability domain, with the permission it needs and a sample payload.

> Markdown version of https://kanorio.com/en/developers/webhooks/events. Append `.md` to any developer docs URL for this format. Index: https://kanorio.com/llms.txt · MCP: https://app.kanorio.com/api/mcp

Every event uses the envelope described in [Webhooks](https://kanorio.com/en/developers/webhooks); the samples below show `data`.

## Content & Publishing

### `collections.item.created`

Fired when a collection item is created (includes publicVersion and cacheTags).

- Permission: `collections:manage`
- Filter: `collectionKeys`

```json
{
  "locale": "en-US",
  "collectionId": "col_01",
  "collectionKey": "blog",
  "itemId": "item_01",
  "slug": "hello-world",
  "status": "published",
  "publishedFieldData": {
    "title": "Hello World"
  },
  "channel": "agent",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collection:blog",
    "item:item_01",
    "seo",
    "search"
  ]
}
```

### `collections.item.updated`

Fired when a collection item draft or published payload is updated.

- Permission: `collections:manage`
- Filter: `collectionKeys`

```json
{
  "locale": "en-US",
  "collectionId": "col_01",
  "collectionKey": "blog",
  "itemId": "item_01",
  "slug": "hello-world",
  "status": "published",
  "publishedFieldData": {
    "title": "Hello World"
  },
  "channel": "agent",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collection:blog",
    "item:item_01",
    "seo",
    "search"
  ]
}
```

### `collections.item.published`

Fired when a collection item is published and visible on the Content Delivery API.

- Permission: `collections:manage`
- Filter: `collectionKeys`

```json
{
  "locale": "en-US",
  "collectionId": "col_01",
  "collectionKey": "blog",
  "itemId": "item_01",
  "slug": "hello-world",
  "status": "published",
  "publishedFieldData": {
    "title": "Hello World"
  },
  "channel": "agent",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collection:blog",
    "item:item_01",
    "seo",
    "search"
  ]
}
```

### `collections.item.unpublished`

Fired when a collection item is unpublished and removed from the Content Delivery API.

- Permission: `collections:manage`
- Filter: `collectionKeys`

```json
{
  "locale": "en-US",
  "collectionId": "col_01",
  "collectionKey": "blog",
  "itemId": "item_01",
  "slug": "hello-world",
  "status": "draft",
  "publishedFieldData": null,
  "channel": "agent",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collection:blog",
    "item:item_01",
    "seo",
    "search"
  ]
}
```

### `collections.item.deleted`

Fired when a collection item is permanently deleted.

- Permission: `collections:manage`
- Filter: `collectionKeys`

```json
{
  "locale": "en-US",
  "collectionId": "col_01",
  "collectionKey": "blog",
  "itemId": "item_01",
  "slug": "hello-world",
  "status": "draft",
  "publishedFieldData": null,
  "channel": "agent",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collection:blog",
    "item:item_01",
    "seo",
    "search"
  ]
}
```

### `collections.items.bulkChanged`

Fired once per batch operation (bulkCreate, bulkUpdate, publish/unpublish batch, or CSV/JSON import).

- Permission: `collections:manage`
- Filter: `collectionKeys`

```json
{
  "locale": "en-US",
  "collectionId": "col_01",
  "collectionKey": "blog",
  "operation": "published",
  "itemIds": [
    "item_01",
    "item_02"
  ],
  "count": 2,
  "channel": "agent",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collection:blog",
    "seo",
    "search",
    "item:item_01",
    "item:item_02"
  ]
}
```

### `collections.schema.changed`

Fired when a collection or its field schema is created, updated, or deleted (triggers `kanorio types` regeneration).

- Permission: `collections:manage`
- Filter: `collectionKeys`

```json
{
  "collectionId": "col_01",
  "collectionKey": "teachers",
  "operation": "updated",
  "addedFieldIds": [
    "linkedin_url"
  ],
  "updatedFieldIds": [],
  "removedFieldIds": [],
  "titleFieldId": "name",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collections",
    "collection:teachers",
    "collection:teachers:items"
  ]
}
```

### `content.site.published`

Fired when a site is published, invalidating pages, globals, and redirects caches.

- Permission: `content:edit`

```json
{
  "locale": "en-US",
  "isFirstPublish": false,
  "pageCount": 12,
  "publicVersion": "1729500000000",
  "cacheTags": [
    "site:ws_01",
    "pages",
    "globals",
    "redirects",
    "seo"
  ]
}
```

### `content.page.published`

Fired when a page is published on the site.

- Permission: `content:edit`

```json
{
  "locale": "en-US",
  "pageId": "page_01",
  "slug": "/about",
  "previousSlug": null,
  "title": "About",
  "pageType": "generic",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "pages",
    "page:page_01",
    "seo",
    "search"
  ]
}
```

### `content.page.updated`

Fired when a published page's content or slug is updated (includes previousSlug when renamed).

- Permission: `content:edit`

```json
{
  "locale": "en-US",
  "pageId": "page_01",
  "slug": "/about",
  "previousSlug": "/about-us",
  "title": "About",
  "pageType": "generic",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "pages",
    "page:page_01",
    "seo",
    "search",
    "redirects"
  ]
}
```

### `content.page.unpublished`

Fired when a page is unpublished or hidden.

- Permission: `content:edit`

```json
{
  "locale": "en-US",
  "pageId": "page_01",
  "slug": "/about",
  "previousSlug": null,
  "title": "About",
  "pageType": "generic",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "pages",
    "page:page_01",
    "seo",
    "search"
  ]
}
```

### `content.page.deleted`

Fired when a page is deleted.

- Permission: `content:edit`

```json
{
  "locale": "en-US",
  "pageId": "page_01",
  "slug": "/about",
  "previousSlug": null,
  "title": "About",
  "pageType": "generic",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "pages",
    "page:page_01",
    "seo",
    "search"
  ]
}
```

## Customers, Membership & Entitlements

### `customers.sharedSender.softCap`

Fired once per day when sign-in code and similar emails sent from Kanorio's shared address exceed the site's daily soft cap; the bot check before sign-in is strengthened automatically. Nothing to do.

- Permission: `messaging:settings`

```json
{
  "day": "2026-11-04",
  "level": "T0"
}
```

### `customers.sharedSender.paused`

Fired when those emails are paused for the site because of bounces, complaints or unusual volume; passkey, Google and signed-in customers are unaffected. Kanorio reviews and restores sending.

- Permission: `messaging:settings`

```json
{
  "reason": "volume",
  "level": "T0"
}
```

### `customers.sharedSender.resumed`

Fired when paused sign-in code emails resume after review.

- Permission: `messaging:settings`

```json
{
  "level": "T1"
}
```

### `customers.contact.created`

Fired when a contact is created from any source (checkout, form, import, manual, customer sign-up). Identities are listed by kind only; the data never includes the email address or phone number.

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "channel": "checkout",
  "source": "CHECKOUT",
  "identities": [
    "EMAIL",
    "PHONE"
  ]
}
```

### `customers.contact.updated`

Fired when a contact's fields change (name, tags, note, locale, invoice preference, metadata, external reference, profile attributes). Lists the changed field names; fetch the contact to read the values.

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "channel": "backoffice",
  "fields": [
    "tags",
    "note"
  ]
}
```

### `customers.contact.merged`

Fired when two contacts become one, either automatically (the same person arrived with another identity) or by the owner. mergedContactId no longer exists; move your references to contactId.

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "channel": "form",
  "mergedContactId": "cnt_02",
  "movedIdentities": [
    "PHONE"
  ]
}
```

### `customers.contact.access_changed`

Fired when the owner blocks or unblocks a customer's sign-in. BLOCKED revokes every session and refuses new sign-ins; orders, consent and emails are unaffected.

- Permission: `customers:manage`

```json
{
  "contactId": "cnt_01",
  "channel": "backoffice",
  "status": "BLOCKED",
  "previousStatus": "ACTIVE",
  "reason": "Chargeback fraud",
  "revokedSessions": 2
}
```

### `customers.consent.updated`

Fired when a contact's marketing consent on one channel changes (subscribed, pending confirmation, unsubscribed, bounced, complained).

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "channel": "EMAIL",
  "status": "UNSUBSCRIBED",
  "previousStatus": "SUBSCRIBED",
  "source": "UNSUBSCRIBE_LINK"
}
```

### `deliverables.entitlement.granted`

Fired when a contact is granted access (Entitlement) to a deliverable or unit.

- Permission: `customers:manage`

```json
{
  "entitlementId": "ent_01",
  "contactId": "cnt_01",
  "deliverableId": "deliv_01",
  "unitId": null,
  "source": "ORDER_LINE",
  "endsAt": null,
  "channel": "order"
}
```

### `deliverables.entitlement.revoked`

Fired when a contact's Entitlement is revoked (e.g. refund or manual revocation).

- Permission: `customers:manage`

```json
{
  "entitlementId": "ent_01",
  "contactId": "cnt_01",
  "deliverableId": "deliv_01",
  "unitId": null,
  "source": "ORDER_LINE",
  "endsAt": null,
  "channel": "backoffice"
}
```

## Promotions & Pricing Rules

### `promotions.redeemed`

Fired when a paid order redeems a promotion (automatic discount or discount code). Carries the promotion, the order and how the discount was split across lines; never the buyer email.

- Permission: `marketing:view`

```json
{
  "redemptionId": "prd_01",
  "promotionId": "prm_01",
  "promotionCode": "AUTUMN10",
  "promotionName": "Autumn 10% Off",
  "orderId": "ord_01",
  "orderNumber": 1001,
  "contactId": "ct_01",
  "discountAmount": 290,
  "currency": "USD",
  "lineAllocations": [
    {
      "orderLineId": "line_01",
      "amount": 290
    }
  ]
}
```

### `promotions.redemption_revoked`

Fired when a full refund revokes a redemption (the promotion usage count is given back). Partial refunds do not revoke.

- Permission: `marketing:view`

```json
{
  "redemptionId": "prd_01",
  "promotionId": "prm_01",
  "promotionCode": "AUTUMN10",
  "promotionName": "Autumn 10% Off",
  "orderId": "ord_01",
  "orderNumber": 1001,
  "contactId": "ct_01",
  "discountAmount": 290,
  "currency": "USD",
  "lineAllocations": [
    {
      "orderLineId": "line_01",
      "amount": 290
    }
  ]
}
```

## Reviews & Ratings

### `reviews.submitted`

Fired when a buyer submits or edits a review (it is pending moderation).

- Permission: `commerce:manage`

```json
{
  "reviewId": "rev_01",
  "targetKind": "PRODUCT",
  "targetId": "prod_01",
  "status": "PENDING",
  "rating": 5,
  "source": "BUYER"
}
```

### `reviews.published`

Fired when a review becomes public: approved by the store, or imported.

- Permission: `commerce:manage`

```json
{
  "reviewId": "rev_01",
  "targetKind": "PRODUCT",
  "targetId": "prod_01",
  "status": "APPROVED",
  "rating": 5,
  "source": "BUYER"
}
```

### `reviews.replied`

Fired when the store posts or replaces its public reply to a review.

- Permission: `commerce:manage`

```json
{
  "reviewId": "rev_01",
  "targetKind": "PRODUCT",
  "targetId": "prod_01",
  "status": "APPROVED",
  "rating": 5,
  "source": "BUYER"
}
```

## Transactions & Fulfillment

### `ec.order.paid`

Fired when an order payment succeeds and is captured.

- Permission: `commerce:manage`

```json
{
  "orderId": "ord_01",
  "orderNumber": 1001,
  "amount": 2900,
  "currency": "USD",
  "itemCount": 1,
  "customerName": "Alex Buyer",
  "customerEmail": "buyer@example.com",
  "lines": [
    {
      "id": "line_01",
      "kind": "PRODUCT",
      "refId": "tier_01",
      "productId": "prod_01",
      "title": "Workshop ticket",
      "variantTitle": null,
      "quantity": 1,
      "unitAmount": 2900,
      "lineAmount": 2900,
      "lineDiscountAmount": 0
    }
  ],
  "promotionId": null,
  "promotionCode": null
}
```

### `ec.shipment.statusChanged`

Fired when a shipment status transitions (in transit, arrived at store, delivered, or exception).

- Permission: `commerce:manage`

```json
{
  "orderId": "ord_01",
  "orderNumber": 1001,
  "shipmentId": "shp_01",
  "status": "IN_TRANSIT",
  "carrier": "PAYUNI",
  "trackingNumber": "TRK123456",
  "storeName": null
}
```

### `ec.order.refunded`

Fired once per successful refund (partial or full, issued from the dashboard, at the payment provider, or by a lost chargeback) with the refunded lines and the order's refund status after it.

- Permission: `commerce:manage`

```json
{
  "orderId": "ord_01",
  "orderNumber": 1001,
  "refundId": "rf_01",
  "amount": 2900,
  "currency": "USD",
  "shippingAmount": 0,
  "source": "MERCHANT",
  "reason": "REQUESTED_BY_CUSTOMER",
  "lines": [
    {
      "id": "line_01",
      "quantity": 1,
      "amount": 2900
    }
  ],
  "orderRefundedAmount": 2900,
  "orderFinancialStatus": "REFUNDED",
  "customerName": "Alex Buyer",
  "customerEmail": "buyer@example.com"
}
```

## Protected Deliverables & Progress

### `deliverables.progress.completed`

Fired once when a learner first meets the deliverable's completion rule (completion snapshot; never fires again for that learner even if units are added later).

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "deliverableId": "deliv_01",
  "percent": 100
}
```

### `deliverables.progress.unit_completed`

Fired when a learner completes one unit (video/audio watched to 90%, or marked complete). Use it for per-chapter automations.

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "deliverableId": "deliv_01",
  "unitId": "unit_01"
}
```

### `deliverables.progress.stalled`

Fired by the daily check when a learner stalls: granted access 14+ days ago and never started (not_started), or has progress but no activity for 7+ days (inactive). At most once per learner, deliverable and reason per ISO week. Use it for reminder automations.

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "deliverableId": "deliv_01",
  "unitId": "unit_01",
  "reason": "inactive",
  "days": 9
}
```

### `deliverables.quiz.attempted`

Fired for every graded quiz attempt (score 0–100, passed, attemptNo). A passed attempt also completes the unit.

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "deliverableId": "deliv_01",
  "unitId": "unit_01",
  "attemptNo": 1,
  "score": 80,
  "passed": true
}
```

### `deliverables.certificate.issued`

Fired when a completion certificate is issued (serial); the PDF is fetched through the Customer API.

- Permission: `customers:view`

```json
{
  "contactId": "cnt_01",
  "deliverableId": "deliv_01",
  "serial": "2026-K7P2QW4D"
}
```

## Forms & Data Collection

### `customers.form.submitted`

Fired when a visitor submits an online form (notifies team and webhooks).

- Permission: `marketing:manage`
- Filter: `formIds`

```json
{
  "formId": "form_01",
  "formName": "Contact Us",
  "submissionId": "sub_01",
  "submitter": {
    "name": "Alex",
    "email": "alex@example.com",
    "phone": null
  },
  "answers": [
    {
      "fieldId": "f_name",
      "type": "text",
      "label": "Name",
      "value": "Alex",
      "display": "Alex"
    },
    {
      "fieldId": "f_email",
      "type": "email",
      "label": "Email",
      "value": "alex@example.com",
      "display": "alex@example.com"
    }
  ]
}
```

## Identity, Tenant & Authorization

### `site.subscription.upcomingRenewal`

Fired before an annual plan renews when annual add-ons or pending add-on / platform fees will be charged on the same invoice.

- Permission: `billing:manage`

```json
{
  "periodKey": "2027-01-01T00:00:00.000Z",
  "totalAmountLabel": "US$348.00"
}
```

### `site.subscription.addOnPriceChange`

Fired at least 30 days before add-on prices change for the site, with the per-level price changes and effective date.

- Permission: `billing:manage`

```json
{
  "toVersion": "2027-01"
}
```

### `team.accessRequest.created`

Fired when a team member requests permissions they are missing, so people who manage the team can review it.

- Permission: `members:manage`

```json
{
  "requestId": "areq_01",
  "requesterUserId": "usr_01",
  "permissions": [
    "commerce:refund"
  ]
}
```

## Media & Assets

### `media.asset.ready`

Fired when background processing of a media file (thumbnail, visibility move, transcoding) finishes and the file is ready to use.

- Permission: `media:manage`

```json
{
  "assetId": "ckasset01",
  "fileName": "workbook.pdf",
  "kind": "pdf",
  "mimeType": "application/pdf",
  "visibility": "protected",
  "processingKind": "DOCUMENT_THUMBNAIL",
  "jobId": "ckjob01",
  "errorCode": null
}
```

### `media.asset.failed`

Fired when background processing of a media file fails after retries; the site team also gets an in-app notification.

- Permission: `media:manage`

```json
{
  "assetId": "ckasset01",
  "fileName": "workbook.pdf",
  "kind": "pdf",
  "mimeType": "application/pdf",
  "visibility": "protected",
  "processingKind": "DOCUMENT_THUMBNAIL",
  "jobId": "ckjob01",
  "errorCode": "THUMBNAIL_FAILED"
}
```

### `site.storageQuota.alert`

Fired when site storage reaches 80%, is exhausted, auto-upgrades, or add-on payment fails.

- Permission: `billing:manage`

```json
{
  "reason": "near_limit",
  "usedBytes": 8600000000,
  "quotaBytes": 10737418240
}
```

## Messaging & Reach

### `customers.sendingDomain.degraded`

Fired when a verified custom sender domain fails DNS verification and campaign sending is paused.

- Permission: `messaging:settings`

```json
{
  "domain": "mail.example.com"
}
```

### `customers.messagingQuota.alert`

Fired when monthly messaging quota is exhausted, auto-upgraded, or add-on billing fails.

- Permission: `billing:manage`

```json
{
  "reason": "exhausted",
  "quota": 2000,
  "levels": 0,
  "periodStart": "2026-10-01T00:00:00.000Z"
}
```

### `customers.teamDestination.disabled`

Fired when a team notification destination (webhook or email) is automatically paused after repeated delivery failures.

- Permission: `site:integrations`

```json
{
  "destinationId": "dest_01",
  "failures": 3,
  "lastError": "HTTP 500"
}
```

## Publishing Delivery, Discovery & Measurement

### `site.analytics.milestone`

Fired when cumulative site pageviews reach a milestone.

- Permission: `analytics:view`

```json
{
  "milestone": 100
}
```

### `site.externalFrontend.degraded`

Fired when the daily external frontend health check detects failing core endpoints (unreachable storefront or broken SEO rewrites).

- Permission: `site:manage_settings`

```json
{
  "externalStorefrontUrl": "https://shop.example.com",
  "failedChecks": [
    "storefront_reachable"
  ]
}
```

## Locale & Localization

### `content.translation.published`

Fired when one record's translation in one locale goes live on its own (editor correction, Management API write, incremental or on-demand machine translation). cacheTags carry only that locale's tags. Not fired per record during a full-site translation job; see localization.job.completed.

- Permission: `content:edit`

```json
{
  "entityType": "post",
  "entityId": "item_01",
  "locale": "fr-FR",
  "paths": [
    "title",
    "excerpt",
    "contentMarkdown"
  ],
  "translatedBy": "AGENT",
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collection:blog@fr-FR",
    "item:item_01@fr-FR",
    "seo@fr-FR",
    "search@fr-FR"
  ]
}
```

### `content.translation.deleted`

Fired when a live translation of one record in one locale is deleted; visitors see the primary-locale text until it is translated again.

- Permission: `content:edit`

```json
{
  "entityType": "post",
  "entityId": "item_01",
  "locale": "fr-FR",
  "paths": [],
  "translatedBy": null,
  "publicVersion": "1729500000000",
  "cacheTags": [
    "collection:blog@fr-FR",
    "item:item_01@fr-FR",
    "seo@fr-FR",
    "search@fr-FR"
  ]
}
```

### `localization.locale.published`

Fired when a locale goes live for visitors and the Content Delivery API (a full-site translation job finished, or the owner published it). cacheTags is site:<id>: rebuild the language switcher and hreflang on every page.

- Permission: `site:manage_settings`

```json
{
  "locale": "fr-FR",
  "primaryLocale": "en-US",
  "status": "PUBLISHED",
  "pathPrefix": "fr",
  "change": null,
  "previous": null,
  "removed": false,
  "locales": [
    {
      "locale": "en-US",
      "isPrimary": true,
      "pathPrefix": null
    },
    {
      "locale": "fr-FR",
      "isPrimary": false,
      "pathPrefix": "fr"
    }
  ],
  "publicVersion": "1729500000000",
  "cacheTags": [
    "site:ws_01"
  ]
}
```

### `localization.locale.unpublished`

Fired when a live locale is taken offline or removed (removed: true); its URL prefix now 301-redirects to the primary locale.

- Permission: `site:manage_settings`

```json
{
  "locale": "fr-FR",
  "primaryLocale": "en-US",
  "status": "REMOVED",
  "pathPrefix": "fr",
  "change": null,
  "previous": null,
  "removed": true,
  "locales": [
    {
      "locale": "en-US",
      "isPrimary": true,
      "pathPrefix": null
    }
  ],
  "publicVersion": "1729500000000",
  "cacheTags": [
    "site:ws_01"
  ]
}
```

### `localization.locale.updated`

Fired when a live locale's URL prefix (change: path_prefix, previous holds the old prefix), its position in the language switcher (order) or the site's primary locale (primary) changes.

- Permission: `site:manage_settings`

```json
{
  "locale": "fr-FR",
  "primaryLocale": "en-US",
  "status": "PUBLISHED",
  "pathPrefix": "fr",
  "change": "path_prefix",
  "previous": "fr-fr",
  "removed": false,
  "locales": [
    {
      "locale": "en-US",
      "isPrimary": true,
      "pathPrefix": null
    },
    {
      "locale": "fr-FR",
      "isPrimary": false,
      "pathPrefix": "fr"
    }
  ],
  "publicVersion": "1729500000000",
  "cacheTags": [
    "site:ws_01"
  ]
}
```

### `localization.job.completed`

Fired when a full-site translation job finishes. cacheTags is locale:<code>: every response of that locale may have changed. A locale going live for the first time also fires localization.locale.published.

- Permission: `site:manage_settings`

```json
{
  "jobId": "ltj_01",
  "locale": "fr-FR",
  "kind": "FULL",
  "done": 42,
  "failed": 0,
  "skipped": 3,
  "calls": 11,
  "errorCode": null,
  "publicVersion": "1729500000000",
  "cacheTags": [
    "locale:fr-FR"
  ]
}
```

### `localization.job.failed`

Fired when a full-site translation job fails (the model provider stayed unavailable or retries ran out; the daily limit only pauses a job). Retry it with localization.jobs.retry.

- Permission: `site:manage_settings`

```json
{
  "jobId": "ltj_01",
  "locale": "fr-FR",
  "kind": "FULL",
  "done": 12,
  "failed": 5,
  "skipped": 3,
  "calls": 11,
  "errorCode": "PROVIDER_UNAVAILABLE",
  "publicVersion": "1729500000000",
  "cacheTags": []
}
```

## Automation

### `automations.run.failed`

Fired when a run of an owner-built automation ends in FAILED after retries (compensation already applied). Not fired for test runs or platform-default automations; at most once per automation revision every 30 days.

- Permission: `automations:manage`

```json
{
  "automationId": "auto_01",
  "runId": "run_01",
  "triggerEventKey": "ec.order.paid",
  "error": "HTTP 500 (gave up after 5 attempts)"
}
```

### `automations.flow.paused`

Fired when Kanorio turns an owner-built automation off automatically because its current revision ran more than 20 times in the past 7 days and 95% or more of those runs failed.

- Permission: `automations:manage`

```json
{
  "automationId": "auto_01",
  "revision": 4,
  "runs": 23,
  "failed": 23
}
```
