Hi 10kartik,
Great questions — this is exactly the right architecture to aim for as you scale. Here's a rundown through each point.
1. Is a single published app with OAuth + application webhooks + React sidebar plugin the recommended pattern?
Yes, this is the correct and recommended architecture for a multi-tenant integration. For published apps on the Front App Store, OAuth is a requirement for receiving data via the Core API or webhooks from customer instances. Application webhooks are preferred over rule-based webhooks because they require no manual configuration by the customer on install , send full event payloads , and work across all Front plan tiers — rule-based webhooks are restricted to Professional+ plans, which would limit your reach.
Your React sidebar plugin (built with the Plugin SDK) pairs naturally with this — it loads contextually in the Front sidebar while your backend receives events via application webhooks, all under a single published app.
2. How do you identify tenants on webhook events?
Every application webhook payload includes an authorization object with the customer's Front company ID:
{
"type": "inbound_received",
"authorization": {
"id": "cmp_abc"
},
"payload": { ... }
}
The authorization.id field is the Front company ID. You record this ID during the OAuth flow (you can also retrieve it by calling GET /me with the access token after OAuth completes ) and map it to your own internal customer/tenant ID. Every subsequent webhook payload will continue to include authorization.id, so you always know which tenant an event belongs to.
3. Is there a native install approval gate — can you approve or reject tenant installations?
There is no built-in install approval gate in Front's platform. Once your app is published on the App Store, any Front customer can install it. If you need to gate access (e.g., only provisioned customers, or a paid tier on your side), you'll need to implement that logic in your own backend — for example, by checking the authorization.id during the OAuth callback and rejecting or flagging tenants that haven't been provisioned with you.
4. How do you handle per-tenant configuration and custom fields?
Front's app framework does not provide a per-tenant config store. You must store all tenant-specific configuration — custom field mappings, preferences, credentials, etc. — in your own backend, keyed by the authorization.id (Front company ID) you capture during OAuth. Your React sidebar plugin can then fetch tenant-specific config from your backend at runtime.
5. How do you migrate from per-customer manual webhook setup to a single published app?
The transition involves a few key steps:
-
Build and publish your app with OAuth enabled and application webhooks configured. Your webhook endpoint must be HTTPS with a valid certificate and must be ready to respond to a validation challenge (Front sends a sync event with an x-front-challenge header; you must respond within 10 seconds).
-
Direct existing customers through the OAuth flow to authorize your published app. Once they complete OAuth, application webhooks will automatically start flowing — no manual rule setup required on their end. Use the authorization.id from the OAuth callback (via GET /me) to map each customer to your internal records.
-
Handle the migration overlap period. During the transition, some tenants may still be sending events via their old manually configured webhooks while others have switched to the published app. Use authorization.id to deduplicate and avoid double-processing events for tenants that complete OAuth early.
-
One important scope note: Application webhooks are scoped to shared inbox events only. If your integration previously received events from private conversations via manually configured per-tenant webhooks, be aware that application webhooks won't cover those. Your OAuth access token, however, can be scoped to access private resources via the Core API — so the event delivery scope (shared inboxes only) and the API access scope (determined by OAuth scopes you configure) are separate concerns.
Operational notes:
-
Token refresh: OAuth access tokens expire; implement a refresh flow using the refresh token so your backend can continue making Core API calls on behalf of each tenant without re-prompting them.
-
Testing limitation: While you're the developer of the app, your own instance runs the local version, which does not deliver application webhooks for private conversations. This is expected behavior and not a bug — webhooks for non-private/shared conversations will work, and once customers from other companies install your published app, there's no such limitation.
-
Stay current: Once live, subscribe to the API News & Updates community space to catch any API changes that could affect your integration.
Hope this helps — happy to answer follow-ups!