> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.fynapse.app/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.fynapse.app/_mcp/server.

# Custom Email Subscriptions

> Learn how to configure custom email subscriptions for different type of events in Fynapse.

## Overview

Email subscriptions, similarly to webhooks, are a method of communicating a selected event occurred in Fynapse.

Such subscriptions for email notifications can be configured for:

* Approval Workflow events
* Ingestion events
* Extraction events

> **Warning**
>
> Email notifications for approval workflows are exclusively managed on the [**Email Notifications** screen](/documentation/instance-management/email-notifications).

You can create custom email subscriptions for different [Event Types](/api-reference/getting-started/webhooks/event-types) using REST API endpoints.

> **Info**
>
> Custom email notifications for ingestion and extraction events appear on the **Email Notifications** screen, where they can be enabled or disabled.
> However, they are created and can also be managed via REST API endpoints covered in this article.

> **Info**
>
> Email subscriptions are released under a feature flag.
> Please note that when you enable the feature flag, it covers both the default and custom email subscriptions.

> **Info**
>
> Email subscriptions are not available for `balance.extracted` event.

## Email Subscriptions REST API Endpoints

| Method   | Path                                                            | Purpose                                                                                                                                            |
| -------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET`    | `/email-subscriptions`                                          | Returns a paginated list of existing email subscriptions.                                                                                          |
| `GET`    | `/email-subscriptions/{id}`                                     | Returns the details of a given email subscription identified by ID.                                                                                |
| `POST`   | `/email-subscriptions`                                          | Creates a new email subscription.                                                                                                                  |
| `DELETE` | `/email-subscriptions/{id}`                                     | Deletes an email subscription.                                                                                                                     |
| `POST`   | `/email-subscriptions/{id}/activate` \| `/deactivate`           | Enables/disables a given email subscription identified by ID.                                                                                      |
| `POST`   | `/email-subscriptions/by-name/{name}/activate` \| `/deactivate` | Enables/disables a given email subscription identified by name.                                                                                    |
| `PATCH`  | `/email-subscriptions/{id}`                                     | Partially updates an email subscription. Only fields present in the body are changed; an absent field or explicit null leaves the value untouched. |

### Security Permissions

Working with email subscriptions REST API endpoints requires a user with relevant permissions granted:

* GET calls require email_subscription_read permission
* POST, PATCH and DELETE calls require email_subscription_edit permission

## Template for a Custom Email Subscription

To create a custom email subscription you need to include the following subscription fields in the payload for the `email-subscriptions` endpoint:

| Field           | Notes                                                                                                                                                                               |   |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| `name`          | Unique name of the subscription.                                                                                                                                                    |   |
| `eventTypes[]`  | At least one; validated against the known event-type set. **Balance events (`balance.extracted`) are rejected** — email is not permitted for balances.                              |   |
| `subject`       | Email subject line; supports `{{placeholder}}` tokens filled from the event payload.                                                                                                |   |
| `previewText`   | Optional inbox-preview text; also supports placeholders.                                                                                                                            |   |
| `emailTemplate` | Required HTML **fragment** (title / body / CTA). The doctype, `<head>`, wrapper, header logo and footer are added by the sender — subscriptions never store the full HTML document. |   |
| `recipients[]`  | Required, non-empty. Each entry is either a literal address or a token (see next).                                                                                                  |   |
| `description`   | Free text for admin UIs.                                                                                                                                                            |   |

> **Tip**
>
> Different groups of Event Types have different data fields.
> All Event Types of one subscription have to belong to one group, e.g. you cannot create a subscription with ingestion and extraction events.

### Sample Payload

**Sample 1**

```json
{
  "name": "Ingestion successful",
  "eventTypes": [
    "ingestion.processing.succeeded"
  ],
  "subject": "File {{ingestionId}} ingested",
  "previewText": "File was successfully ingested",
  "emailTemplate": "<p>Ingestion successful,</p><br /><p>File: {{ingestionId}} was ingested successfully</p><p>Completed on: {{finishedOn}}</p>",
  "recipients": [
    "ops@example.com"
  ],
  "description": "Notification email informing file ingestion was successful."
}
```

### Recipient Token Grammar

Each entry in `recipients[]` is one of:

* **Literal** — e.g. `ops@example.com`. Sent as-is.
* **User** — `{{u::<payload-field>}}`, e.g. `{{u::requestor}}`. The field's value (user id/username from the payload) is resolved to an email address via the identity service at send time.
* **Group** — `{{g::<payload-field>}}`, e.g. `{{g::approverGroup}}`. The field's value (group name) is resolved and expanded to every member's address at send time.

### Delivery Behaviour

* A placeholder with a present but null field renders as empty text.
* A placeholder or recipient token with a field missing from the event stops the whole email. The delivery ends as dead letter .
* An unknown user or group also stops the email.
* A recipient token with a null field adds no recipient. Users and group members without an email address are skipped.
* When no recipient is left, nothing is sent and the delivery ends as cancelled.

### Rendering

* The contents of the payload are wrapped in a graphic design provided by Fynapse.
* Every email is auto-converted to a plain-text alternative for clients that don't render HTML.
* Transport: SMTP via SendGrid.
* The default `From` address is `no-reply@fynapse.aptitudecloud.com` (env-dependent).

Sample Email

**Example 1**

![Sample\_notification2](file:docs/pages/api-reference/getting-started/images/Sample_notification2.png "Sample_notification2")