---
title: Custom Notifications
description: Setting up custom webhook-based push notifications
---

# Custom Notifications

## Preparation

> Custom notifications are considered an advanced feature, and requires basic knowledge of JSON syntax and creating your own scripts/tools to handle sending the payloads.

1. Read through the main [Notifications](/lunasea/notifications) page
2. Copy your device-based or user-based webhook URL from LunaSea

You will need to slightly modify the webhook URL you have copied from any of the modules. Simply replace the name of the module within the webhook URL to custom and you're good to go!

Alternatively, you can copy the content of the URL after the last slash (after `device/` or `user/`) to obtain your Firebase device or user identifier.

## Device-Based

Send a custom notification using a device token to a single device running LunaSea.

<Tabs
  defaultValue="endpoint"
  values={[
    { label: "Endpoint", value: "endpoint" },
    { label: "JSON Body Schema", value: "json_body_schema" },
  ]}
>
<TabItem value="endpoint">
  ```bash
  POST https://notify.lunasea.app/v1/custom/device/:device_id
  ```

  `device_id`: Firebase device identifier
</TabItem>

<TabItem value="json_body_schema">
  ```json
  {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "Device-Based Custom Notification",
    "type": "object",
    "properties": {
      "title": {
        "type": "string",
        "description": "The notification title"
      },
      "body": {
        "type": "string",
        "description": "The notification body content"
      },
      "image": {
        "type": "string",
        "description": "A publicly accessible image to be attached to the notification"
      }
    },
    "required": ["title", "body"]
  }
  ```

  If `title` or `body` are missing in the request, a notification will still be sent but with a default title or body respectively.
</TabItem>
</Tabs>

## User-Based

<Tabs
  defaultValue="endpoint"
  values={[
    { label: "Endpoint", value: "endpoint" },
    { label: "JSON Body Schema", value: "json_body_schema" },
  ]}
>
<TabItem value="endpoint">
  ```bash
  POST https://notify.lunasea.app/v1/custom/user/:user_id
  ```

  `user_id`: Firebase user identifier
</TabItem>

<TabItem value="json_body_schema">
  ```json
  {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "User-Based Custom Notification",
    "type": "object",
    "properties": {
      "title": {
        "type": "string",
        "description": "The notification title"
      },
      "body": {
        "type": "string",
        "description": "The notification body content"
      },
      "image": {
        "type": "string",
        "description": "A publicly accessible image to be attached to the notification"
      }
    },
    "required": ["title", "body"]
  }
  ```

  If `title` or `body` are missing in the request, a notification will still be sent but with a default title or body respectively.
</TabItem>
</Tabs>

## Troubleshooting

- Ensure that the required `title` parameter is a string type
  - If the type is not a string, the notification will fail
  - Sending no value or a null value will result in the title "Unknown Title" being used
- Ensure that the required `body` parameter is a string type
  - If the type is not a string, the notification will fail
  - Sending no value or a null value will result in the body "Unknown Content" being used
- If sending an image, ensure that the content is a valid URL
  - If the content is not a valid URL, the notification will fail
  - The URL must contain the protocol, `http://` or `https://`
  - The URL must be a direct link to the image and does not redirect
  - The URL must be publicly accessible, not requiring any authentication to access
- If sending an image, the image must be a supported image type
  - Supported types include JPGs, PNGs, and animated GIFs
