Before you start
- Use production unless development or staging is explicitly scoped, and keep the same authorized organization throughout. Reading this guide does not execute an action.
- Discover the current published action and validate/plan exact input before any later execution. Confirm the actual mutation and its provider/audit effects.
- Required published permission: app_topolo_engage.workspace:write.
- Select the organization resource separately from action input. Mutations require the verified organization admin’s own bearer and Notify webhook-management authority; service credentials are not a substitute. Status itself does not call the mutation-only ready guard.
Effects and limits
-
Creates a Notify webhook subscription for each missing Nexus email event type with the organization's derived signing secret.
-
On create failure, cleanup of already created Notify subscriptions is best effort. Failed cleanup or a lost response can leave external effects without complete local rows; local absence does not prove no external subscription.
-
Connecting also retires locally tracked active legacy event types: Notify removal is best effort, then the local legacy row is revoked. This can happen even when created is false; local revocation does not prove the remote legacy subscription was removed.
Request
POST /api/events/delivery/connect
Inputs below are source-derived synthetic examples, not approval to execute. Discover resource context separately.
Input fields
| Field | Required | Type and constraints |
|---|---|---|
| No body fields | — | Use the empty object {}; keep organization selection outside the body. |
Worked examples
Every request/response below is synthetic and unrun, authored from reviewed source and retained published schemas. It is not a captured local or production response. Fixture identities and timestamps authorize nothing.
Create missing subscriptions
SOURCE-DERIVED SYNTHETIC UNRUN example. This is authored illustration, not a captured response, live authorization, provider result or test pass.
Request:
{}
Response illustration:
{
"delivery": {
"connected": true,
"status": "active",
"eventTypes": [
{
"eventType": "nexus.email.delivered",
"status": "active",
"notifySubscriptionId": "whsub_example_1",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.bounced.hard",
"status": "active",
"notifySubscriptionId": "whsub_example_2",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.bounced.soft",
"status": "active",
"notifySubscriptionId": "whsub_example_3",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.complained",
"status": "active",
"notifySubscriptionId": "whsub_example_4",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.replied",
"status": "active",
"notifySubscriptionId": "whsub_example_5",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.auto_reply",
"status": "active",
"notifySubscriptionId": "whsub_example_6",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.unsubscribed",
"status": "active",
"notifySubscriptionId": "whsub_example_7",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
}
]
},
"created": true,
"results": [
{
"eventType": "nexus.email.delivered",
"outcome": "created"
},
{
"eventType": "nexus.email.bounced.hard",
"outcome": "created"
},
{
"eventType": "nexus.email.bounced.soft",
"outcome": "created"
},
{
"eventType": "nexus.email.complained",
"outcome": "created"
},
{
"eventType": "nexus.email.replied",
"outcome": "created"
},
{
"eventType": "nexus.email.auto_reply",
"outcome": "created"
},
{
"eventType": "nexus.email.unsubscribed",
"outcome": "created"
}
]
}
Compare every returned event type with a same-organization status read. Source skips locally active types; this is not a concurrent/provider idempotency guarantee.
Reconnect when current types are already locally active
SOURCE-DERIVED SYNTHETIC UNRUN example. This is authored illustration, not a captured response, live authorization, provider result or test pass.
Request:
{}
Response illustration:
{
"delivery": {
"connected": true,
"status": "active",
"eventTypes": [
{
"eventType": "nexus.email.delivered",
"status": "active",
"notifySubscriptionId": "whsub_example_1",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.bounced.hard",
"status": "active",
"notifySubscriptionId": "whsub_example_2",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.bounced.soft",
"status": "active",
"notifySubscriptionId": "whsub_example_3",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.complained",
"status": "active",
"notifySubscriptionId": "whsub_example_4",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.replied",
"status": "active",
"notifySubscriptionId": "whsub_example_5",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.auto_reply",
"status": "active",
"notifySubscriptionId": "whsub_example_6",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
},
{
"eventType": "nexus.email.unsubscribed",
"status": "active",
"notifySubscriptionId": "whsub_example_7",
"createdBy": "user_original_example",
"createdAt": "2026-10-20T00:00:00.000Z",
"rotatedAt": null
}
]
},
"created": false,
"results": [
{
"eventType": "nexus.email.delivered",
"outcome": "existing"
},
{
"eventType": "nexus.email.bounced.hard",
"outcome": "existing"
},
{
"eventType": "nexus.email.bounced.soft",
"outcome": "existing"
},
{
"eventType": "nexus.email.complained",
"outcome": "existing"
},
{
"eventType": "nexus.email.replied",
"outcome": "existing"
},
{
"eventType": "nexus.email.auto_reply",
"outcome": "existing"
},
{
"eventType": "nexus.email.unsubscribed",
"outcome": "existing"
}
]
}
Current locally active types are skipped, but this remains a mutation: legacy tracked rows may be retired even when created is false. Local revocation does not prove remote legacy removal; no concurrency/provider idempotency guarantee is established.
A Notify failure can follow partial or uncertain effects
SOURCE-DERIVED SYNTHETIC UNRUN example. This is authored illustration, not a captured response, live authorization, provider result or test pass.
Request:
{}
Response illustration:
{
"error": {
"code": "notify_unavailable",
"message": "Notify could not be reached. Try again.",
"details": {
"eventType": "nexus.email.bounced.hard"
}
}
}
Retain the failing eventType and reconcile both local state and separately authorized Notify state. Do not infer nothing changed or blindly repeat.
Verify the result
- Call events.delivery.status and check delivery.status and each eventTypes[].status.
- The status read is a local projection only; separately authorized provider checks are required for remote consistency. This guide neither performs them nor grants extra permission.
Errors and recovery
- 401
user_credential_required: Call it as a signed-in organization admin, not with an app or service token. - 403
notify_admin_required: Ask an organization admin with app_topolo_notify.webhooks:manage to run it. - 403
permission_denied: Stop and ask the authorized application owner to review the exact permission requirement; do not automatically widen scopes or change context. - 409
event_delivery_not_connected: Connect event delivery first. - 422
notify_refused: Inspect the structured eventType/notifyCode, preserve possible partial effects and reconcile current local/remote state before any separately authorized retry. The source does not support a blanket nothing-changed assertion. - 502
notify_unavailable: Inspect the structured eventType/notifyCode, preserve possible partial effects and reconcile current local/remote state before any separately authorized retry. The source does not support a blanket nothing-changed assertion. - 503
event_delivery_not_configured: The deploy lacks ENGAGE_EVENT_SECRET_KEY, TOPOLO_NOTIFY_URL or ENGAGE_APP_URL.
No safe automatic inverse is published. After failure or response loss, preserve the exact action/error/eventType and read local events.delivery.status in the same organization, then reconcile remote Notify effects through its current authorized read contract with the owner. Local rows or a failed compensation do not prove no change. Never blindly connect/rotate/disconnect to test recovery or widen credentials. Any further mutation needs its own reviewed intent.
Evidence and change log
- 2026-10-20: Prepared this paired guide from source
767d2d83713809e984559eee562a2c9f7ffcfa4dand the retained production contract snapshot. Independent source/content/audience review is complete. Examples remain explicitly synthetic and unrun; no original response capture or business execution is claimed. - Source-reviewed guidance preserves partial/uncertain subscription effects and local-only status; current catalogue recovery/scope/actor wording is under owner review.
Published contract wording under review
The retained catalogue description/recovery text includes stronger no-change or automatic-undo wording than this source supports. The published schema annotations are retained exactly for comparison; they are not a guarantee that compensation or provider delivery succeeds. Follow the source-qualified limits above.
Exact published-field qualifications
/outputSchema/properties/delivery/properties/eventTypes/items/properties/createdBy/description: Source-qualified limit: createdBy is the stored connection creator for that row, not the rotation actor. A later rotatedAt does not identify who rotated it./outputSchema/properties/delivery/properties/connected/description: Source-qualified limit: connected classifies whether all seven current local rows are active. It does not prove remote subscription existence, health, signature agreement or event delivery./outputSchema/properties/delivery/properties/status/description: Source-qualified limit: status classifies the seven current local rows only. not_connected is not proof that the organization has never connected in the past; legacy rows are excluded from this view.
The original published schema annotations remain evidence under review. Validation types/enums are unchanged; these guide qualifications do not assert a corrected catalogue publication or remote state.