Skip to content

Sending Notifications

Mini Apps can send notifications to users who have added the Mini App to their Farcaster client and enabled notifications.

in-app notifications in Warpcast

An in-app notification is sent to a user and launches them into the app

Overview

At a high-level notifications work like so:

  • when a user enables notifications for your app, the Farcaster client (i.e. Warpcast) hosting your app will generate a notification token for that user and send it to your server
  • to send a notification to a user, make a request to host's servers with the notification token and content
  • if a user later disables notifications, you'll receive another event indicating the user is unsubscribed and the notification token is no longer valid

Steps

Listen for events

You'll need a server to receive webhook events and a database to store notification tokens for users:

Add your webhook URL in farcaster.json

If you haven't already, follow the Publishing your app guide to host a farcaster.json on your app's domain.

Define the webhookUrl property in your app's configuration in farcaster.json:

{
  "accountAssociation": {
    "header": "eyJmaWQiOjU0NDgsInR5cGUiOiJjdXN0b2R5Iiwia2V5IjoiMHg2MWQwMEFENzYwNjhGOEQ0NzQwYzM1OEM4QzAzYUFFYjUxMGI1OTBEIn0",
    "payload": "eyJkb21haW4iOiJleGFtcGxlLmNvbSJ9",
    "signature": "MHg3NmRkOWVlMjE4OGEyMjliNzExZjUzOTkxYTc1NmEzMGZjNTA3NmE5OTU5OWJmOWFmYjYyMzAyZWQxMWQ2MWFmNTExYzlhYWVjNjQ3OWMzODcyMTI5MzA2YmJhYjdhMTE0MmRhMjA4MmNjNTM5MTJiY2MyMDRhMWFjZTY2NjE5OTFj"
  },
  "frame": {
    "version": "1",
    "name": "Example App",
    "iconUrl": "https://example.com/icon.png",
    "homeUrl": "https://example.com",
    "imageUrl": "https://example.com/image.png",
    "buttonTitle": "Check this out",
    "splashImageUrl": "https://example.com/splash.png",
    "splashBackgroundColor": "#eeccff",
    "webhookUrl": "https://example.com/api/webhook"
  }
}

Get users to add your app

For a Mini App to send notifications, it needs to first be added by a user to their Farcaster client and for notifications to be enabled (these will be enabled by default).

Use the addFrame action while a user is using your app to prompt them to add it:

Save the notification tokens

When notifications are enabled, the Farcaster client generates a unique notification token for the user. This token is sent webhook endpoint along with a url that the app should call to send a notification.

The token and url need to be securely saved to database so they can be looked up when you want to send a notification to a particular user.

Send a notification

notifications schematic

Once you have a notification token for a user, you can send them a notification by sending a POST request the url associated with that token.

The body of that request must match the following JSON schema:

PropertyTypeRequiredDescriptionConstraints
notificationIdstringYesAn ID that serves as an idempotency key. When the user opens the Mini App from the notification this ID will be included in the context object.Maximum length of 128 characters
titlestringYesTitle of the notification.Max length 32 characters
bodystringYesBody of the notification.Max length 128 characters.
targetUrlstringYesURL to open when the user clicks the notification.Max length 1024 characters.
Must be on the same domain as the Mini App.
tokensstring[]YesArray of notification tokens to send to.Max 100 tokens.

The server should response with an HTTP 200 OK and the following JSON body:

PropertyTypeRequiredDescription
successTokensstring[]YesTokens for which the notification succeeded.
invalidTokensstring[]YesTokens which are no longer valid and should never be used again. This could happen if the user disabled notifications but for some reason the Mini App server has no record of it.
rateLimitedTokensstring[]YesTokens for which the rate limit was exceeded. Mini App server can try later.

When a user clicks the notification, the Farcaster client will:

  • Open your Mini App at targetUrl
  • Set the context.location to a FrameLocationNotificationContext
export type FrameLocationNotificationContext = {
  type: 'notification';
  notification: {
    notificationId: string;
    title: string;
    body: string;
  };
};

Example code to send a notification

Rate Limits

Host servers may impose rate limits per token. The standard rate limits, which are enforced by Warpcast, are:

  • 1 notification per 30 seconds per token
  • 100 notifications per day per token

Receiving webhooks

Users can add and configure notification settings Mini Apps within their Farcaster client. When this happens Farcaster clients will send events your server that include data relevant to the event.

This allows your app to:

  • keep track of what users have added or removed your app
  • securely receive tokens that can be used to send notifications to your users

Events

frame_added

Sent when the user adds the Mini App to their Farcaster client (whether or not this was triggered by an addFrame() prompt).

The optional notificationDetails object provides the token and url if the client equates adding to enabling notifications (Warpcast does this).

Payload
{
  "event": "frame_added",
  "notificationDetails": {
    "url": "https://api.warpcast.com/v1/frame-notifications",
    "token": "a05059ef2415c67b08ecceb539201cbc6"
  }
}

frame_removed

Sent when a user removes a mini app, which means that any notification tokens for that fid and client app (based on signer requester) should be considered invalid:

Payload
{
  "event": "frame_removed"
}

notifications_disabled

Sent when a user disables notifications from e.g. a settings panel in the client app. Any notification tokens for that fid and client app (based on signer requester) should be considered invalid:

Payload
{
  "event": "notifications_disabled"
}

notifications_enabled

Sent when a user enables notifications (e.g. after disabling them). The payload includes a new token and url:

Payload
{
  "event": "notifications_enabled",
  "notificationDetails": {
    "url": "https://api.warpcast.com/v1/frame-notifications",
    "token": "a05059ef2415c67b08ecceb539201cbc6"
  }
}

Handling events

Farcaster clients will POST events to the webhookUrl specified in your farcaster.json.

Your endpoint should:

  • verify the event
  • persist relevant data
  • return a 200 response

If your app doesn't respond with a 200, the Farcaster client will attempt to re-send the event. The exact number of retries is up to each client.

Verifying events

Events are signed by the app key of a user with a JSON Farcaster Signature. This allows Mini Apps to verify the Farcaster client that generated the notification and the Farcaster user they generated it for.

The @farcaster/frame-node library provides a helper for verifying events. To use it, you'll need to supply a validation function that can check the signatures against the latest Farcaster network state.

An implementation that uses Neynar is provided. You can sign up and get an API key on their free tier. Make sure to set NEYNAR_API_KEY environment variable.

Example

import {
  ParseWebhookEvent,
  parseWebhookEvent,
  verifyAppKeyWithNeynar,
} from "@farcaster/frame-node";
 
try {
  const data = await parseWebhookEvent(requestJson, verifyAppKeyWithNeynar);
} catch (e: unknown) {
  const error = e as ParseWebhookEvent.ErrorType;
 
  switch (error.name) {
    case "VerifyJsonFarcasterSignature.InvalidDataError":
    case "VerifyJsonFarcasterSignature.InvalidEventDataError":
      // The request data is invalid
    case "VerifyJsonFarcasterSignature.InvalidAppKeyError":
      // The app key is invalid
    case "VerifyJsonFarcasterSignature.VerifyAppKeyError":
      // Internal error verifying the app key (caller may want to try again)
  }
}

Reference implementation

For a complete example, check out the Mini App V2 Demo has all of the above: