> For the complete documentation index, see [llms.txt](https://developer.celigo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.celigo.com/api/api-reference/notifications.md).

# Notifications

Notification subscriptions control which users receive alerts for resource-level events (errors, status changes, completions) on flows, connections, integrations, and syncs. Each subscription routes alerts to the email of the subscribed user.

Subscriptions are account-scoped — an account admin can manage subscriptions on behalf of any user, not just their own.

### Notification schema

## The Notification object

```json
{"openapi":"3.2.0","info":{"title":"Notifications","version":"1.0.0"},"components":{"schemas":{"Notification":{"type":"object","required":["_id","type","lastModified"],"description":"A notification subscription linking a user email to a single resource\n(flow, connection, integration, or sync). When the resource emits an\nalert (error, state change, etc.), the subscribed user is notified.","allOf":[{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"type":{"type":"string","enum":["flow","connection","integration","sync"],"description":"Which resource class this subscription targets. Implies which of\n`_flowId` / `_connectionId` / `_integrationId` / `_syncId` is populated."},"_flowId":{"type":"string","format":"objectId","description":"Flow id when `type: flow`."},"_connectionId":{"type":"string","format":"objectId","description":"Connection id when `type: connection`."},"_integrationId":{"type":"string","format":"objectId","description":"Integration id when `type: integration`."},"_syncId":{"type":"string","format":"objectId","description":"Sync id when `type: sync`."},"subscribedByUser":{"type":"object","description":"Minimal user descriptor for whoever owns this subscription.","properties":{"name":{"type":"string","description":"Display name of the subscribed user."},"email":{"type":"string","format":"email","description":"Email address the notifications are routed to."}}}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]}}}}
```

## List notification subscriptions

> Returns notification subscriptions for flows, connections, integrations,\
> and syncs in the account. Without the \`users=all\` query parameter, the response is\
> scoped to the caller's own subscriptions. With \`users=all\`, every user's\
> subscriptions in the account are returned.\
> \
> Returns an empty response when the caller has no subscriptions in the\
> current scope. With \`users=all\`, an empty array is returned only in\
> accounts with zero subscriptions across all users.

```json
{"openapi":"3.2.0","info":{"title":"Notifications","version":"1.0.0"},"tags":[{"name":"Notifications","description":"Notification subscriptions control which users receive alerts for\nresource-level events (errors, status changes, completions) on flows,\nconnections, integrations, and syncs. Each subscription routes alerts\nto the email of the subscribed user.\n\nSubscriptions are account-scoped — an account admin can manage\nsubscriptions on behalf of any user, not just their own.\n\n## Notification schema\n\n{% openapi-schemas spec=\"notification\" schemas=\"Notification\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Notification":{"type":"object","required":["_id","type","lastModified"],"description":"A notification subscription linking a user email to a single resource\n(flow, connection, integration, or sync). When the resource emits an\nalert (error, state change, etc.), the subscribed user is notified.","allOf":[{"$ref":"#/components/schemas/ResourceResponse"},{"type":"object","properties":{"type":{"type":"string","enum":["flow","connection","integration","sync"],"description":"Which resource class this subscription targets. Implies which of\n`_flowId` / `_connectionId` / `_integrationId` / `_syncId` is populated."},"_flowId":{"type":"string","format":"objectId","description":"Flow id when `type: flow`."},"_connectionId":{"type":"string","format":"objectId","description":"Connection id when `type: connection`."},"_integrationId":{"type":"string","format":"objectId","description":"Integration id when `type: integration`."},"_syncId":{"type":"string","format":"objectId","description":"Sync id when `type: sync`."},"subscribedByUser":{"type":"object","description":"Minimal user descriptor for whoever owns this subscription.","properties":{"name":{"type":"string","description":"Display name of the subscribed user."},"email":{"type":"string","format":"email","description":"Email address the notifications are routed to."}}}}}]},"ResourceResponse":{"type":"object","description":"Response","properties":{"_id":{"type":"string","format":"objectId","readOnly":true,"description":"Unique identifier for the resource. Format is a 24-character hexadecimal string."},"createdAt":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was created. Set automatically and cannot be modified."},"lastModified":{"type":"string","format":"date-time","readOnly":true,"description":"Timestamp when the resource was last updated. Changes whenever any property is modified."},"deletedAt":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp when the resource was soft-deleted. When null or absent, the resource is active."}},"required":["_id"]},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/notifications":{"get":{"operationId":"listNotifications","tags":["Notifications"],"summary":"List notification subscriptions","description":"Returns notification subscriptions for flows, connections, integrations,\nand syncs in the account. Without the `users=all` query parameter, the response is\nscoped to the caller's own subscriptions. With `users=all`, every user's\nsubscriptions in the account are returned.\n\nReturns an empty response when the caller has no subscriptions in the\ncurrent scope. With `users=all`, an empty array is returned only in\naccounts with zero subscriptions across all users.","parameters":[{"name":"users","in":"query","required":false,"schema":{"type":"string","enum":["all"]},"description":"When set to `all`, returns subscriptions for every user in the\naccount. When omitted, returns only the caller's own subscriptions."}],"responses":{"200":{"description":"Array of notification subscriptions.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}}}}},"204":{"description":"Caller has no subscriptions in the current scope (default scope when\n`users=all` is omitted). Not the same as 200 with `[]`."},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```

## Subscribe / unsubscribe users to resource notifications

> Upserts a batch of notification subscriptions. Each item targets exactly one\
> resource (\`\_flowId\`, \`\_connectionId\`, or \`\_integrationId\`) plus a\
> \`subscribedByUserEmail\`. \`subscribed: true\` creates (or keeps) the\
> subscription; \`subscribed: false\` removes it.\
> \
> Returns a parallel array of per-item results — one entry per request item,\
> in the same order. Each result carries \`statusCode\` (\*\*201\*\* when a subscription\
> was created, \*\*200\*\* when updated or removed, 422 when a referenced resource\
> doesn't exist) plus an \`errors\[]\` array on failures. An empty request body\
> returns an empty array.\
> \
> The body is a bare array (maximum 500 items). Each item must carry\
> exactly one of \`\_flowId\` / \`\_connectionId\` / \`\_integrationId\` /\
> \`\_syncId\`. The response is a per-item status array; referencing a\
> non-existent resource fails that item with \`statusCode: 422\` but\
> does not fail the whole request.

```json
{"openapi":"3.2.0","info":{"title":"Notifications","version":"1.0.0"},"tags":[{"name":"Notifications","description":"Notification subscriptions control which users receive alerts for\nresource-level events (errors, status changes, completions) on flows,\nconnections, integrations, and syncs. Each subscription routes alerts\nto the email of the subscribed user.\n\nSubscriptions are account-scoped — an account admin can manage\nsubscriptions on behalf of any user, not just their own.\n\n## Notification schema\n\n{% openapi-schemas spec=\"notification\" schemas=\"Notification\" grouped=\"true\" %}"}],"servers":[{"url":"https://api.integrator.io","description":"Production (US / default region)"},{"url":"https://api.eu.integrator.io","description":"Production (EU region)"},{"url":"https://api.au.integrator.io","description":"Production (AU region)"},{"url":"https://api.ca.integrator.io","description":"Production (CA region)"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"NotificationsUpsertRequest":{"type":"array","maxItems":500,"description":"Bare array (no wrapping envelope) of upsert items. Each item targets a\nsingle resource and flips subscription state on or off for one user.","items":{"type":"object","description":"A single subscribe / unsubscribe directive. Set exactly one of\n`_flowId`, `_connectionId`, `_integrationId`, or `_syncId`.","oneOf":[{"required":["_flowId"]},{"required":["_connectionId"]},{"required":["_integrationId"]},{"required":["_syncId"]}],"properties":{"_flowId":{"type":"string","format":"objectId","description":"Flow id to subscribe / unsubscribe. Set exactly one of `_flowId` / `_connectionId` / `_integrationId` / `_syncId`."},"_connectionId":{"type":"string","format":"objectId","description":"Connection id to subscribe / unsubscribe."},"_integrationId":{"type":"string","format":"objectId","description":"Integration id to subscribe / unsubscribe."},"_syncId":{"type":"string","format":"objectId","description":"Sync id to subscribe / unsubscribe."},"subscribed":{"type":"boolean","description":"`true` creates the subscription (or no-ops if it already exists);\n`false` removes it."},"subscribedByUserEmail":{"type":"string","format":"email","description":"Email of the user whose subscription is being modified. Must match a\nuser in the account — unknown emails are silently ignored (no-op)."}},"required":["subscribed","subscribedByUserEmail"]}},"Error":{"type":"object","description":"Standard error response envelope returned by integrator.io APIs.","properties":{"errors":{"type":"array","description":"List of errors that occurred while processing the request.","items":{"type":"object","properties":{"code":{"oneOf":[{"type":"string"},{"type":"integer"}],"description":"Machine-readable error code. Usually a string like\n`invalid_ref`, `missing_required_field`, or `unauthorized`;\nmay be an **integer** when the error mirrors an upstream HTTP\nstatus (e.g. `500`) — most commonly returned by connection-ping\nand adaptor-proxy responses."},"message":{"type":"string","description":"Human-readable description of the error."},"field":{"type":"string","description":"Optional pointer to the document field that caused the error.\nUsed by structural validation errors (`missing_required_field`,\n`invalid_ref`) to indicate which field is at fault\n(e.g. `_id`, `type`, `http.baseURI`)."},"source":{"type":"string","description":"Optional origin layer for the error — e.g. `application` when\nthe error came from the remote system the adaptor called,\n`connector` when the adaptor itself rejected the request."}},"required":["message"]}}},"required":["errors"]}},"responses":{"400-bad-request":{"description":"Bad request. The server could not understand the request because of malformed syntax or invalid parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401-unauthorized":{"description":"Unauthorized. The request lacks a valid bearer token, or the provided token\nfailed to authenticate.\n\nNote: the 401 response is produced by the auth middleware **before** the\nrequest reaches the endpoint handler, so it does **not** follow the\nstandard `{errors: [...]}` envelope. Instead the body is a bare\n`{message: string}` object with no `code`, no `errors` array. Callers\nhandling 401s should key off the HTTP status and the `message` string,\nnot try to destructure an `errors[]`.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Human-readable description of the auth failure. Known values:\n- `\"Unauthorized\"` — no `Authorization` header on the request.\n- `\"Bearer Authentication Failed\"` — header present but token\n  is invalid, revoked, or expired."}},"required":["message"]}}}}}},"paths":{"/v1/notifications":{"put":{"operationId":"upsertNotifications","tags":["Notifications"],"summary":"Subscribe / unsubscribe users to resource notifications","description":"Upserts a batch of notification subscriptions. Each item targets exactly one\nresource (`_flowId`, `_connectionId`, or `_integrationId`) plus a\n`subscribedByUserEmail`. `subscribed: true` creates (or keeps) the\nsubscription; `subscribed: false` removes it.\n\nReturns a parallel array of per-item results — one entry per request item,\nin the same order. Each result carries `statusCode` (**201** when a subscription\nwas created, **200** when updated or removed, 422 when a referenced resource\ndoesn't exist) plus an `errors[]` array on failures. An empty request body\nreturns an empty array.\n\nThe body is a bare array (maximum 500 items). Each item must carry\nexactly one of `_flowId` / `_connectionId` / `_integrationId` /\n`_syncId`. The response is a per-item status array; referencing a\nnon-existent resource fails that item with `statusCode: 422` but\ndoes not fail the whole request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationsUpsertRequest"}}}},"responses":{"200":{"description":"Per-item result array (parallel to the request). Each entry is\n`{statusCode, errors?}` — `statusCode: 200` on success, or a non-200\nstatus with an `errors[]` array on per-item failures. Overall HTTP is\nstill 200 even when individual items fail.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","description":"Per-item upsert result.","properties":{"statusCode":{"type":"integer","description":"Per-item outcome: 200 when the subscription was created,\nupdated, or left unchanged; 422 when the referenced\nresource doesn't exist (details in `errors[]`)."},"errors":{"type":"array","description":"Per-item error details — present on non-200 results.","items":{"type":"object","properties":{"field":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}},"400":{"$ref":"#/components/responses/400-bad-request"},"401":{"$ref":"#/components/responses/401-unauthorized"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developer.celigo.com/api/api-reference/notifications.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
