Restrict an On-Premise Installation by IP
This page is for operators of an on-premise MonoChat installation. It explains how to limit the web app to your own networks at the network level (nginx or a firewall) without blocking the services that must call MonoChat from the internet.
MonoChat has no IP allowlist of its own. The restriction lives in your nginx, load balancer or firewall and applies to the whole installation, not to a single tenant.
What to restrict, what to keep open
| Keep restricted to your networks | Keep reachable from the internet |
|---|---|
| The web app and everything not listed on the right | The webhook and callback paths in the tables below |
The DDP/WebSocket endpoint the web app connects to (/websocket) |
Restrict the web UI and the WebSocket endpoint together: the app uses both. Allow only the paths below for everyone else, and block the rest.
Paths that external services call
Every path below is registered by the MonoChat server. A path built from a setting is the hookPath you configured on the server (in channelConnectors.<name> or paymentSystemConnectors.<name> in the server settings); the suffix is added by the code. Open only the connectors you use.
Channels
| Path | Called by | Defined in |
|---|---|---|
<hookPath>/webhooks (POST) | omni-message, for WhatsApp Cloud, WhatsApp Gupshup, Instagram, Messenger, Telegram, TikTok, Twilio SMS and Varan OTP | packages/app-connectors-om2-*/src/webhooks/webhook.ts; hookPath from channelConnectors.whatsappBusinessVegaCloud, whatsappBusinessVegaGupshup, instagramCastor, messengerRigel, telegramBotRegulus, tikTokTimir, twilioSms, varanOtp |
<hookPath>/webhooks, <hookPath>/sessions, <hookPath>/messages (POST) | Your own systems, through the Messages API channel | channelConnectors.messagesApi.hookPath, packages/app-connectors-messages-api/src/webhooks/webhook.ts |
<hookPath>/message, <hookPath>/info (POST) | Chatwoot | channelConnectors.chatwoot.hookPath, packages/app-connectors-chatwoot/src/webhook.ts |
<hookPath>/inbound (POST) | The SIP provider (generic SIP and Sonitel SIP channels) | channelConnectors.genericSip.hookPath, channelConnectors.sonitelSip.hookPath |
/api/facebook/channels/:channelId/flows/:flowId (POST) | WhatsApp, for WhatsApp Flows | server/api/whatsapp-flow.js |
The channel providers (Meta, Telegram, TikTok, Twilio) do not call MonoChat directly. They call the omni-message webhook listener, which forwards to the /webhooks path above. If you run omni-message yourself, its webhook listener must be reachable from the internet on these paths: /webhooks/meta-messenger, /webhooks/instagram-business, /webhooks/wab-cloud, /webhooks/wab-gupshup/:channelId, /webhooks/wab-360-dialog/:channelId, /webhooks/telegram-bot/:channelId, /webhooks/tiktok and /webhooks/twilio-sms/:channelId (apps/webhook-listener/src/modules/webhook-listeners/webhook-listeners.controller.ts in omni-message). MonoChat itself must be reachable from omni-message on the /webhooks paths above.
Payment systems
Payment providers call back when a customer pays, and send the customer back to MonoChat afterwards. Both must work from outside your network.
| Connector | Paths under its hookPath (paymentSystemConnectors.<name>.hookPath) |
|---|---|
| Stripe | /webhook/:clientId (POST), /return/success/:paymentSystemId, /return/cancel/:paymentSystemId |
| HyperPay | /pay/:clientId/:paymentSystemOrderId, /result/:clientId/:paymentSystemOrderId |
| Mamo | /webhook/:clientId (POST), /return/:clientId/:paymentSystemOrderId |
| Midtrans | /webhook/:clientId (POST), /return/:paymentSystemOrderId |
| Paymob | /webhook/:clientId (POST), /return/:paymentSystemOrderId |
| PayTabs | /callback/:clientId/:paymentSystemOrderId (POST), /return/:paymentSystemOrderId |
| Tabby | /webhook/:clientId (POST), /return/:paymentSystemOrderId/:status |
| Tamara | /webhook/:clientId (POST), /return/:paymentSystemOrderId/:status |
| Tap | /webhook/:clientId (POST), /return/:clientId/:paymentSystemOrderId |
| Telr | /webhook/:clientId/:paymentSystemOrderId (POST), /return/:paymentSystemOrderId/:status |
| Ziina | /return/:clientId/:paymentSystemOrderId/:status |
| iyzico | /:transactionId (POST) |
| JCC | /:status |
| MyFatoorah | the hookPath itself (POST), /:paymentSystemOrderId/:status (POST) |
| N-Genius | the hookPath itself (POST), /:paymentSystemOrderId/:status |
| Paywall | /:paymentSystemOrderId/:status |
| UniqoPay | the hookPath itself (POST), /:paymentSystemOrderId/:status (POST) |
| VakıfBank Sanal POS | /:status (GET and POST) |
| İş Yerim POS | the hookPath itself (GET and POST) |
The simplest rule is to open <hookPath> and everything below it for each payment connector you use. Each source is packages/app-connectors-<name>/src/webhook.ts.
Other server endpoints
| Path | Used for | Defined in |
|---|---|---|
/api/:slug/custom-functions/… (POST) | Calling a custom function over HTTP with an access token | lib/managers/custom-function-sdk/_/server/endpoint.js |
/api/ai-agent/mcp, /api/ai-agent/events (POST) | AI agent runs reporting back to MonoChat | server/api/ai-agent.ts |
/api/channels-manager/facebook/auth, /api/channels-manager/tiktok/auth (GET) | The pop-up that returns after connecting a Facebook or TikTok account | packages/app-managers-channel/src/webhook.ts |
/l/:_id (GET) | Short links that you send to customers | server/api/short-link.js |
/api/status (GET) | The mobile app checks the server and its sign-in options | server/api/status.js |
/.well-known/assetlinks.json, /.well-known/apple-app-site-association (GET) | Android and iOS app links | server/api/assetlinks.js, server/api/apple-app-site-association.js |
Open /api/:slug/custom-functions, /api/ai-agent, /l/ and the two channel pop-up paths if you use those features from outside your network. The channel pop-up paths are opened in the browser of the person connecting the account, so they can stay restricted if only people on your network connect channels. Open /api/status and the two /.well-known files only if your agents use the MonoChat mobile app from outside your network.
Sign-in with a provider (OAuth)
When a sign-in provider redirects the browser back to MonoChat, the redirect is a normal browser request from the person signing in, so it follows the same restriction as the web app. Keep the redirect paths reachable for the people who sign in this way. The paths are the redirectPath values in public.oauth.<provider> in the server settings (the default examples are /api/oauth/google/redirect, /api/oauth/microsoft/redirect, /api/oauth/facebook/redirect and /api/oauth/apple/redirect). Apple sign-in sends the browser back with a POST (responseMode: form_post), which the same path accepts. For the mobile app, the server also answers /api/oauth/facebook/mobile, /api/oauth/microsoft/mobile and /auth/oauth-callback/<provider> (server/configs/oauth/mobile.ts).
If you use the Microsoft Marketplace integration, the path in microsoftMarketplace.redirectWebhookPath receives the Microsoft Marketplace request and must be reachable from the internet (server/configs/microsoft-marketplace/webook.ts).
Pass the real client IP through the proxy
MonoChat records the client IP for sessions and status logs. Behind a reverse proxy or load balancer it sees the proxy's address unless you pass the real one on.
- Make nginx (or your load balancer) send the original address in the
X-Forwarded-Forheader, for exampleproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;. - Set the environment variable
HTTP_FORWARDED_COUNTon the MonoChat server to the number of proxies in front of the app. It is read by the Meteor framework, not by MonoChat code, so it belongs in your deployment settings and not in the settings JSON.
Check your setup
- From a network that is not allowed, open the web app. It must be refused.
- From an allowed network, sign in and open the inbox. Messages must load, which proves the WebSocket endpoint is open to you.
- Send a test message to a connected channel from outside your network and confirm it arrives in the inbox.
- Create a payment link for a small test order, pay it, and confirm the order shows as paid.
Test the paths after every change to your proxy rules. A blocked webhook path does not show an error in MonoChat: the messages and payment confirmations simply stop arriving.