Connect FlutterFlow to Kajabi by combining a webhook-to-database sync with Firebase or Supabase and Kajabi's limited direct API. Because Kajabi's native API surface is thin, the durable architecture is: Kajabi webhooks fire on events like member grants and offer purchases, a Firebase Cloud Function receives and stores them in Firestore, and your FlutterFlow app reads from Firestore — gating premium content based on membership flags synced from Kajabi.
| Fact | Value |
|---|---|
| Tool | Kajabi |
| Category | Education |
| Method | FlutterFlow API Call |
| Difficulty | Intermediate |
| Time required | 60 minutes |
| Last updated | July 2026 |
Building a Kajabi Membership Companion App in FlutterFlow
Kajabi is a powerful knowledge-commerce platform, but its public developer API is comparatively limited versus dedicated LMS tools. Rather than direct API polling at runtime, the robust FlutterFlow pattern treats Kajabi as an event source: Kajabi fires webhooks on member grants and offer purchases, a Firebase Cloud Function receives and stores the access state in Firestore, and your FlutterFlow app reads exclusively from Firestore to gate content. This is faster, more scalable, and more reliable than live Kajabi API queries.
The architecture: webhook event fires → Cloud Function verifies signature and updates Firestore member document → FlutterFlow reads Firestore natively → UI shows gated content based on access flag. For product catalog display, a Kajabi API Group (proxied through the Cloud Function) surfaces available offers and products in the app; members click through to Kajabi's hosted course player via a deep link for actual learning.
Kajabi is a paid-only platform — no free tier means you need an active paid account to test. Verify all API endpoints and webhook event names in Kajabi's current developer documentation, as the API is actively evolving and some details change between platform versions.
Integration method
Kajabi's public REST API surface is limited and evolving — verify each endpoint in Kajabi's developer documentation before building against it. The more reliable integration architecture uses Kajabi's webhook events (offer.purchased, member.granted, member.revoked) delivered to a Firebase Cloud Function that syncs the access state into Firestore, which FlutterFlow reads natively. For product catalog data available via the Kajabi API, an API Group with a Cloud Function proxy surfaces it in the app. All API tokens and webhook secrets are stored server-side only.
Prerequisites
- An active paid Kajabi account (no free tier — verify your plan includes API and webhook access)
- Kajabi API credentials or access token from your Kajabi account settings (verify current location in Kajabi's dashboard)
- A Firebase project with Cloud Functions enabled and Firestore configured
- A FlutterFlow project with Firebase Auth and Firestore integration configured
- Basic understanding of how webhooks work (Kajabi sends events to your server when things happen)
Step-by-step guide
Configure Kajabi webhook credentials and set up a Cloud Function receiver
The foundation of this integration is the webhook pipeline. In your Kajabi admin panel, navigate to the developer or integrations settings and find the Webhooks section. Create a new webhook and select the events you care about: at minimum `offer.purchased`, `member.granted`, and `member.revoked`. Kajabi provides a webhook signing secret that allows your Cloud Function to verify that incoming requests are genuinely from Kajabi — copy this secret immediately and store it in Firebase Functions config: `firebase functions:config:set kajabi.webhook_secret='YOUR_WEBHOOK_SECRET'`. Deploy a Firebase Cloud Function called `kajabiWebhook` as an HTTP endpoint (onRequest). The function should: parse the raw request body, verify the Kajabi webhook signature using the signing secret (check Kajabi's documentation for the exact HMAC verification method they use), then extract the member email and offer/product details from the event payload. Based on the event type, write to Firestore: for `member.granted` or `offer.purchased`, set `hasAccess: true` on the Firestore document keyed by the member's email. For `member.revoked`, set `hasAccess: false`. Because Kajabi emails are the key, make sure your FlutterFlow Firebase Auth also uses email-based login — this is the bridge between systems. Note: the exact webhook event names, payload structure, and signature verification method depend on your Kajabi plan and version. Consult Kajabi's current developer documentation for precise details — do not rely solely on this tutorial for payload field names.
1// Firebase Cloud Function: functions/index.js2const functions = require('firebase-functions');3const admin = require('firebase-admin');4const crypto = require('crypto');5const cors = require('cors')({ origin: true });6admin.initializeApp();78exports.kajabiWebhook = functions.https.onRequest(async (req, res) => {9 // Verify Kajabi webhook signature10 // Note: verify the exact header name and HMAC method in Kajabi's docs11 const webhookSecret = functions.config().kajabi.webhook_secret;12 const signature = req.headers['x-kajabi-signature'];13 const body = JSON.stringify(req.body);1415 const expectedSig = crypto16 .createHmac('sha256', webhookSecret)17 .update(body)18 .digest('hex');1920 if (signature !== expectedSig) {21 return res.status(401).json({ error: 'Invalid signature' });22 }2324 const { event, data } = req.body;25 const memberEmail = data?.member?.email || data?.email;2627 if (!memberEmail) {28 return res.status(400).json({ error: 'No member email in payload' });29 }3031 const db = admin.firestore();32 const memberRef = db.collection('kajabi_members').doc(memberEmail);3334 if (event === 'member.granted' || event === 'offer.purchased') {35 await memberRef.set(36 { hasAccess: true, offerId: data?.offer?.id, updatedAt: Date.now() },37 { merge: true }38 );39 } else if (event === 'member.revoked') {40 await memberRef.set(41 { hasAccess: false, updatedAt: Date.now() },42 { merge: true }43 );44 }4546 return res.json({ received: true });47});48Pro tip: Configure the webhook URL in Kajabi to point to your deployed Cloud Function URL. Test it using Kajabi's webhook test feature (if available) or simulate an event with a test purchase on Kajabi before going live.
Expected result: The `kajabiWebhook` Cloud Function is deployed and reachable. When Kajabi sends a test webhook, the function verifies the signature and writes the member access record to Firestore.
Configure Kajabi API access and deploy a proxy for product data
In addition to webhooks, Kajabi provides a direct REST API for reading product and offer data. Navigate to your Kajabi admin settings and find the API section — look for API Keys or Access Tokens in the developer or integrations area. Generate an API token. Store this token in Firebase Functions config: `firebase functions:config:set kajabi.api_token='YOUR_API_TOKEN'`. Extend your Cloud Function (or create a new one) to also proxy Kajabi API requests for product catalog data. The Cloud Function accepts a path parameter from FlutterFlow, injects the Kajabi API token as an Authorization header, and returns the response. Because Kajabi's public API surface is limited and the specific endpoints available depend on your plan and Kajabi's current API version, verify each endpoint in Kajabi's developer documentation before building against it. Common endpoints may include product listings and offer details, but do not assume availability. Add CORS headers to all Cloud Function responses so they work in FlutterFlow's web preview as well as on native devices.
1// Add to index.js: Kajabi API proxy2exports.kajabiApiProxy = functions.https.onRequest((req, res) => {3 cors(req, res, async () => {4 const apiToken = functions.config().kajabi.api_token;5 // Verify the exact Kajabi API base URL and auth format in Kajabi's docs6 const { path } = req.query;78 if (!path) {9 return res.status(400).json({ error: 'Missing path parameter' });10 }1112 try {13 const response = await axios.get(14 `https://kajabi.com/api/v1/${path}`, // Verify this base URL in Kajabi docs15 {16 headers: {17 Authorization: `Bearer ${apiToken}`,18 'Content-Type': 'application/json',19 },20 }21 );22 return res.json(response.data);23 } catch (err) {24 const status = err.response ? err.response.status : 500;25 return res.status(status).json({ error: err.message });26 }27 });28});29Pro tip: Because Kajabi's API is evolving, add robust error handling that surfaces meaningful error messages to FlutterFlow. A 404 from the Cloud Function almost certainly means the Kajabi endpoint does not exist at the assumed path — check the docs.
Expected result: The `kajabiApiProxy` Cloud Function is deployed and returns Kajabi product data when called with a valid `path` query parameter.
Create the 'Kajabi' API Group in FlutterFlow
In FlutterFlow, click API Calls in the left nav → + Add → Create API Group. Name it 'Kajabi'. Set the Base URL to your `kajabiApiProxy` Cloud Function's HTTPS URL. Add a group-level variable `path` of type String. Create the following API Calls inside the group: - 'GetProducts': Method GET, no additional endpoint, query param `path` = `products`. This returns the list of Kajabi products/courses your account has. - 'GetOffers': Method GET, query param `path` = `offers`. Returns available offers with pricing. In the Response & Test tab for each call, run a test (after your Cloud Function is deployed) and generate JSON Paths from the real Kajabi response. The exact JSON structure varies by Kajabi API version — generate paths from actual data rather than guessing field names. In FlutterFlow's left nav, also configure a Firestore collection listener. The `kajabi_members` Firestore collection (written by your webhook function) will serve as the primary data source for membership gating — FlutterFlow's native Firestore integration reads this far more efficiently than an API call on every page load.
Pro tip: If certain Kajabi API endpoints return a 404 or are not available on your plan, fall back to hardcoding static product data in Firestore and syncing it via webhook events instead of polling the API.
Expected result: The 'Kajabi' API Group is configured in FlutterFlow. GetProducts and GetOffers calls return Kajabi data via the Cloud Function proxy.
Implement content gating based on Firestore membership status
The core of the FlutterFlow app experience is showing different content to members versus non-members. With Firebase Auth set up for email/password login, you can look up the logged-in user's email in the `kajabi_members` Firestore collection to check their `hasAccess` field. In FlutterFlow, create a Firestore query on the page or widget level: query the `kajabi_members` collection where the document ID equals the logged-in user's email address. Bind the `hasAccess` field to a page state boolean variable `isMember`. Use conditional visibility on your widgets: - Show the premium content section only when `isMember == true`. - Show a 'Join Kajabi' or 'Enroll Now' button only when `isMember == false`. This button uses a Launch URL action that deep-links to your Kajabi offer checkout page or sales page: `https://your-school.kajabi.com/offers/YOUR_OFFER_SLUG`. For the deep-link to the actual course content on Kajabi, add a 'Continue Learning' button that opens `https://your-school.kajabi.com/products/YOUR_PRODUCT_SLUG` in a browser. The actual course player is hosted on Kajabi — your FlutterFlow app is the membership portal and content gateway, not the course delivery system itself.
Pro tip: Add a loading state while the Firestore membership query resolves. Display a loading spinner during the lookup and only show the member/non-member content after the `hasAccess` value is confirmed to avoid a flash of un-gated content.
Expected result: Members see premium content and 'Continue Learning' deep-links. Non-members see preview content and a 'Join' button linking to Kajabi checkout. The gating updates automatically when Kajabi fires a webhook that changes the Firestore record.
Handle authentication and the edge case of new members before the first webhook
There is an important edge case in the webhook-sync architecture: a member might purchase an offer on Kajabi, open the FlutterFlow app within seconds, and find their access not yet granted because the webhook has not been processed yet. Handle this gracefully. The solution is a two-layer check. First, FlutterFlow reads the Firestore `kajabi_members` document (fast, real-time). If `hasAccess` is false but the user believes they are a member, add a 'Refresh Access' button. This button calls a Cloud Function that queries the Kajabi API directly for that user's current offer access status (if the Kajabi API supports it for your plan) and updates Firestore immediately — acting as an on-demand sync that bridges the webhook delay. For Firebase Auth integration, use email/password login in FlutterFlow so the logged-in email can be matched to the Kajabi member record. Alternatively, configure Google sign-in if your Kajabi members commonly use Gmail. When a new user signs up in the FlutterFlow app with an email that exists in `kajabi_members` (because they already purchased on Kajabi), the gating check will work immediately. When a new user signs up before purchasing, they see non-member content until a Kajabi purchase webhook arrives. Store Kajabi API tokens and webhook secrets exclusively in Firebase Functions config. If you'd rather have RapidDev set up this webhook-sync architecture for you, book a free scoping call at rapidevelopers.com/contact — the team builds FlutterFlow integrations like this every week.
Pro tip: Add a 'Refresh Membership Status' button that calls your Cloud Function to re-check Kajabi API access and update Firestore. This handles the webhook delay and gives members a manual way to unlock access after a purchase.
Expected result: The app handles new members gracefully with a manual refresh option. Members who purchased through Kajabi see their correct access level in the FlutterFlow app within seconds of tapping 'Refresh'.
Common use cases
Mobile membership app for a Kajabi community and course bundle
A branded mobile companion for a Kajabi creator's community offering. When a new member buys an offer on Kajabi, the webhook updates their Firestore access record. The FlutterFlow app shows premium content modules only to members with an active access flag, and deep-links to the full course player on kajabi.com for video lessons.
Build a mobile app for my Kajabi membership where members log in with their email, see which courses they have access to, and tap to continue their course on Kajabi's website. Non-members see a preview with a 'Join Now' button that opens my Kajabi sales page.
Copy this prompt to try it in FlutterFlow
Kajabi coaching program client portal
A private portal app for a coaching program where clients see their session schedule, access downloadable resources stored in Firebase Storage, and check off milestones in their coaching journey — all synced from their Kajabi membership status. Coaches see an admin view of all active clients and their progress.
Create a coaching client portal in FlutterFlow where clients who have purchased my Kajabi coaching offer see their weekly session schedule, can download PDF resources, and track their progress through the program milestones.
Copy this prompt to try it in FlutterFlow
Kajabi product discovery app for prospective members
A public-facing discovery app that shows Kajabi products and courses available for purchase, with preview content, testimonials, and pricing pulled from the Kajabi API (where available) or hardcoded for products not yet in the API. Visitors tap 'Enroll' to go to the Kajabi offer checkout page.
Build a FlutterFlow app that showcases all my Kajabi courses and membership tiers to prospective buyers. Each product card shows the title, description, price, and a button linking to the Kajabi checkout page.
Copy this prompt to try it in FlutterFlow
Troubleshooting
Kajabi webhook events are not arriving at the Cloud Function
Cause: The webhook URL in Kajabi is incorrect, the Cloud Function is not deployed, or Kajabi's webhook delivery is failing silently.
Solution: In the Kajabi admin settings, confirm the webhook URL points exactly to your deployed Cloud Function's HTTPS URL. Check Firebase Console → Functions → Logs for any incoming requests. Use Kajabi's webhook test feature (if available) to send a test payload and confirm the Cloud Function receives and logs it.
Webhook signature verification fails with 401 even though the webhook secret is correct
Cause: Kajabi may send the raw body as a string while the Cloud Function is parsing it as JSON before verification, changing the exact bytes used for the HMAC calculation.
Solution: Access the raw request body for signature verification before JSON.parse(). In Firebase Cloud Functions with Express-style onRequest, use `rawBody` from the `req` object if available, or configure body-parser to preserve the raw body: `express.json({ verify: (req, res, buf) => { req.rawBody = buf; } })`. Verify with `req.rawBody` not `JSON.stringify(req.body)`.
1// Use rawBody for HMAC verification2const expectedSig = crypto3 .createHmac('sha256', webhookSecret)4 .update(req.rawBody)5 .digest('hex');Kajabi API returns 404 for an endpoint path found in third-party tutorials
Cause: Kajabi's public API surface is limited and the available endpoints depend on your plan tier. Some endpoints documented elsewhere may not exist in the current Kajabi API version or may require a higher plan tier.
Solution: Consult Kajabi's official developer documentation for your current plan's available API endpoints. Do not rely on third-party tutorials for exact endpoint paths. If an endpoint is unavailable, fall back to syncing product data via webhooks or hardcoding it in Firestore.
Member purchased on Kajabi but the FlutterFlow app still shows non-member content
Cause: The Kajabi webhook has not fired yet (delivery can take seconds to minutes after a purchase), or the member email in Kajabi does not match the email used for Firebase Auth login in the FlutterFlow app.
Solution: Add a 'Refresh Membership Status' button that triggers an on-demand sync via a Cloud Function. Verify that the email used for Kajabi purchase matches the email used for Firebase Auth sign-in exactly (case-insensitive comparison). Check Kajabi's webhook delivery log for any failed deliveries.
Best practices
- Treat Kajabi's webhook events as the primary data source for membership status — polling the API on every screen load is unreliable and wastes API quota.
- Never store Kajabi API tokens, webhook secrets, or offer slugs in FlutterFlow App Values or Dart code — use Firebase Functions config exclusively.
- Verify Kajabi webhook signatures to prevent fraudulent webhook injection that could grant unauthorized membership access.
- Add a manual 'Refresh Access' mechanism for members who purchased on Kajabi but experience a webhook delivery delay.
- Use Firebase Auth email/password login so member emails match cleanly between Kajabi records and Firestore documents.
- Always deep-link to Kajabi's hosted course player for actual content delivery — do not attempt to stream Kajabi course videos inside the FlutterFlow app.
- Verify each Kajabi API endpoint exists and is available on your plan before building against it — the API is evolving and availability varies by tier.
- Plan a fallback for Kajabi API downtime: store the last known product catalog in Firestore so the app can display products even if the Kajabi API is temporarily unavailable.
Alternatives
Teachable has a more mature and complete REST API that can be queried directly, making it easier to build a course catalog app without relying on webhooks as the primary data sync mechanism.
LearnWorlds offers a more comprehensive API with dual-header OAuth2 authentication and built-in certificate generation — better for white-label branded academies that need full course data access.
Moodle gives complete control over the LMS data via its Web Services API, including grades and quiz data, which makes it more suitable for institutions that need deep data access rather than a knowledge-commerce storefront.
Frequently asked questions
Can FlutterFlow receive Kajabi webhook events directly?
No. FlutterFlow apps run on users' devices and do not have a public HTTPS endpoint that can receive inbound webhook POST requests. You need a Firebase Cloud Function or Supabase Edge Function as the webhook receiver — it listens for Kajabi events and writes the results to Firestore, which FlutterFlow then reads natively via its Firestore integration.
Does Kajabi have a free plan I can use to test the integration?
No. Kajabi is a paid-only platform with no free tier. You need an active paid Kajabi subscription to access the API, webhooks, and course creation features. Kajabi offers a free trial period — use it to test the integration end-to-end before committing. Check kajabi.com for current trial terms and plan pricing.
Can I stream Kajabi course videos inside the FlutterFlow app?
Not in the standard integration pattern. Kajabi's course videos are hosted on Kajabi's platform and protected behind their authentication system. You should deep-link members to the Kajabi-hosted course player in a browser rather than attempting to embed or stream the video content inside your Flutter app. This also means you do not need to manage video streaming infrastructure.
What happens when a member's Kajabi subscription expires — will the app update automatically?
Yes, if you have configured the `member.revoked` webhook event. When Kajabi revokes access (subscription expired, refund issued), it fires the webhook, your Cloud Function sets `hasAccess: false` in Firestore, and FlutterFlow's real-time Firestore listener updates the UI the next time the member opens the app. There may be a delay between the Kajabi event and webhook delivery — check Kajabi's webhook reliability documentation for your plan.
Can I build multiple membership tiers with different content access levels?
Yes. Instead of a single `hasAccess` boolean, store an offer ID or tier name in the Firestore member document when each webhook event fires. In FlutterFlow, check the tier field and use conditional visibility to show different content sections for 'basic', 'pro', and 'vip' members. Each Kajabi offer/product purchase updates the tier field in Firestore via the webhook handler.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation