Push subscriptions allow you to receive a POST request from Sailhouse when you send an event to a topic. They’re great for serverless applications, hosted on platforms like Netlify, Vercel, Cloudflare or Google Cloud Run.

Handling the request

Sailhouse sends a POST request to the endpoint specified in the subscription. In the screenshot above, you can see this defined as https://api.acme.dev/api/send-welcome/email.

The data of your event is sent within the body, alongside some additional headers.

  • sh-signature - App-specific signature to verify the source of the request
  • identifier - Checksum combining the event ID, subscription and time sent - globally unique for your application
  • event-id - ID of the event
import express from 'express';

const app = express();

app.use(express.json());

app.post("/api/send-welcome-email", async (req, res) => {
    const event = req.body;
})

Security

To ensure the request has come from Sailhouse, you can check the sh-signature header of the incoming request against the Signature visible in your app settings.

This is a sensitive value that should not be publically available. You can always re-generate this signature.

To view your app’s signature in the dashboard, navigate to Home -> Apps -> Select your app -> Settings.

Use this value within your application, as you would with any other secret. This could be via environment variables, or a managed solution like Google Secrets Manager.

import express from 'express';

const app = express();

app.use(express.json());

app.post("/api/send-welcome-email", async (req, res) => {
    const event = req.body;
    const shSignature = req.headers['sh-signature'];
    const sailhouseSignature = process.env.SAILHOUSE_SIGNATURE;

    if (shSignature !== sailhouseSignature) {
        return res.status(403).json({ error: 'Unauthorized' });
    }

    // ...
})

If Sailhouse receives a 403 in response to a push subscription endpoint, it will retry as normal before placing in the Dead Letter Queue.

Considerations

Timeout

Sailhouse will consider, and then cancel, a request if it is taking long than 5 seconds. This is configurable up to 15 minutes via contacting support.

Payload size

Sailhouse has a limitation of 4MB when receiving events, so your application should be able to process requests of that size.

Idempotency

The identifer header passed contains a checksum built up of the following data.

  • Event ID
  • Subscription
  • Timestamp of the published event

Although Sailhouse aims to deliver once, technically it is regarded as atleast-once. This identifier header value can be used to check if you have processed this event for this subscription before.

You should use this value over the event-id header, as that value is the same across all subscriptions for a topic.