To integrate Lovable with Meetup, build a Supabase Edge Function that proxies the Meetup GraphQL API using OAuth2 access tokens. Store your Meetup OAuth credentials in Cloud → Secrets, call the Edge Function from your React frontend, and use Lovable's chat to generate event discovery UIs, group management dashboards, and RSVP tracking features — no direct browser-to-Meetup API calls needed.
Build event discovery and community management features with the Meetup GraphQL API
Meetup's API gives you programmatic access to the platform's core objects: events, groups, members, and RSVPs. Unlike REST APIs that return a fixed set of fields, Meetup's GraphQL endpoint lets you specify exactly the data your UI needs — fetch event title, date, venue, attendance count, and organizer details in a single request. This makes it ideal for building rich event discovery interfaces, group dashboards, and RSVP management tools inside Lovable apps.
The integration requires OAuth2 — Meetup does not support simple API key authentication for most endpoints. You will register an application in Meetup's developer portal, obtain a client ID and secret, and either implement the authorization code flow for user-specific data or use a server-to-server token for public event data. All OAuth tokens are stored in Cloud → Secrets and accessed exclusively from an Edge Function, keeping credentials completely isolated from your frontend bundle.
Meetup is particularly well suited for community-focused use cases: recurring free or low-cost events, local group management, and member engagement tracking. If your product involves paid ticketing, venue booking with seat maps, or large-scale commercial events, Eventbrite's API is better suited — it was designed from the ground up for ticketed commerce. Meetup's strength is the community layer: groups, members, discussions, and the social graph around who attends what.
Integration method
Meetup uses OAuth2 for authentication and exposes a GraphQL API for events, groups, and RSVPs. Because OAuth access tokens must never be exposed to browser code, all Meetup API calls are proxied through a Supabase Edge Function running on Deno. Your React frontend calls the Edge Function, which fetches data from Meetup's GraphQL endpoint using credentials stored in Cloud → Secrets.
Prerequisites
- A Lovable account with a project that has Lovable Cloud enabled
- A Meetup account with at least one group you manage or access to event data you want to display
- A Meetup OAuth2 application registered at secure.meetup.com/oauth2/clients — you need the client ID and client secret
- An OAuth2 access token for Meetup (either a long-lived token from the OAuth flow or a service account token)
- Basic familiarity with GraphQL queries — Meetup's API uses GraphQL, not REST
Step-by-step guide
Register a Meetup OAuth2 application and obtain credentials
Register a Meetup OAuth2 application and obtain credentials
Before writing any code, you need OAuth2 credentials from Meetup's developer portal. Navigate to secure.meetup.com/oauth2/clients in your browser while logged into your Meetup account. Click 'Create a new consumer'. Fill in the application name (e.g., 'My Lovable App'), your app's description, and the redirect URI. For the redirect URI, use your deployed Lovable app URL followed by /auth/meetup/callback — for example, https://your-app.lovable.app/auth/meetup/callback. You can also add http://localhost:3000/auth/meetup/callback for local development. After creating the application, Meetup shows you a Consumer Key (this is your client ID) and a Consumer Secret (this is your client secret). Copy both values — you will store them as secrets in the next step. For the integration pattern in this tutorial, you also need an access token. If you are building a tool for your own groups (not requiring end-user login), you can generate a personal access token directly: go to secure.meetup.com/oauth2/access and authorize your own application. This produces an access token you can store as a secret and use for all API calls. If you need user-specific data (individual member RSVPs, private group access), you will need to implement the full OAuth2 authorization code flow — which involves a redirect to Meetup's auth page, a callback handler, and token exchange. For most organizer dashboard use cases, the personal access token approach is simpler and sufficient.
Pro tip: Meetup access tokens expire after one hour. For production apps, implement the OAuth2 refresh token flow and store the refresh token in Cloud → Secrets so your Edge Function can automatically renew the access token without user intervention.
Expected result: You have a Meetup Consumer Key, Consumer Secret, and an initial access token. These three values are ready to be stored as secrets in Lovable's Cloud panel.
Store Meetup credentials in Cloud → Secrets
Store Meetup credentials in Cloud → Secrets
With your Meetup OAuth credentials in hand, store them securely in Lovable's encrypted Secrets panel. Open your Lovable project and click the '+' icon at the top of the editor next to the Preview label. This opens the Cloud panel with tabs for Database, Auth, Storage, Edge Functions, Secrets, Logs, and Usage. Click the Secrets tab. Click 'Add new secret' and add the following three secrets: - Name: MEETUP_CLIENT_ID — Value: your Consumer Key from the Meetup developer portal - Name: MEETUP_CLIENT_SECRET — Value: your Consumer Secret from the Meetup developer portal - Name: MEETUP_ACCESS_TOKEN — Value: your OAuth access token If you are implementing the refresh token flow, also add: - Name: MEETUP_REFRESH_TOKEN — Value: your OAuth refresh token Never paste these credentials directly into the Lovable chat prompt. Lovable's security infrastructure blocks approximately 1,200 hardcoded API keys per day, but the safest approach is to never expose credentials in chat at all — free-tier Lovable chat history is publicly visible, and credentials in chat can end up in Git commit history. The Secrets panel encrypts values at rest and makes them accessible only from Edge Functions via Deno.env.get(). Once all secrets are added, verify they appear in the Secrets panel with masked values (shown as asterisks). This confirms they are stored correctly. Edge Functions will reference them by the exact names you entered — any typo in the secret name will cause a runtime error when the function tries to retrieve the value.
Expected result: The Secrets panel shows MEETUP_CLIENT_ID, MEETUP_CLIENT_SECRET, and MEETUP_ACCESS_TOKEN (and optionally MEETUP_REFRESH_TOKEN) with masked values. The secrets are ready to be accessed from Edge Functions.
Create the Meetup GraphQL proxy Edge Function
Create the Meetup GraphQL proxy Edge Function
Now create the Edge Function that proxies requests to Meetup's GraphQL API. This function receives a GraphQL query from your frontend, forwards it to Meetup's API with the OAuth access token, and returns the result. Keeping the token server-side prevents it from appearing in browser network logs or being accessible to client-side JavaScript. In Lovable's chat, describe what you need and paste the code below as a starting point. Prompt Lovable: 'Create a Supabase Edge Function at supabase/functions/meetup-api/index.ts that accepts a POST request with a GraphQL query body, forwards it to https://api.meetup.com/gql with the Meetup access token from Deno.env.get("MEETUP_ACCESS_TOKEN"), and returns the API response.' Lovable will scaffold the function and deploy it to your Cloud. The function handles CORS so your React frontend can call it from the browser, validates that a query was provided, appends the OAuth Bearer token, and returns the parsed response. For production use, add error handling for expired tokens: check if the response status is 401 and if so, use the refresh token to obtain a new access token before retrying the request.
Create a Supabase Edge Function at supabase/functions/meetup-api/index.ts that accepts POST requests with a JSON body containing a 'query' field and optional 'variables' field. Forward the GraphQL query to https://api.meetup.com/gql using the MEETUP_ACCESS_TOKEN secret as a Bearer token. Return the Meetup API response as JSON. Include CORS headers so the frontend can call this function.
Paste this in Lovable chat
1// supabase/functions/meetup-api/index.ts2const MEETUP_GRAPHQL_URL = 'https://api.meetup.com/gql';34Deno.serve(async (req) => {5 // Handle CORS preflight6 if (req.method === 'OPTIONS') {7 return new Response(null, {8 headers: {9 'Access-Control-Allow-Origin': '*',10 'Access-Control-Allow-Methods': 'POST, OPTIONS',11 'Access-Control-Allow-Headers': 'Content-Type, Authorization',12 },13 });14 }1516 if (req.method !== 'POST') {17 return new Response(JSON.stringify({ error: 'Method not allowed' }), {18 status: 405,19 headers: { 'Content-Type': 'application/json' },20 });21 }2223 const accessToken = Deno.env.get('MEETUP_ACCESS_TOKEN');24 if (!accessToken) {25 return new Response(JSON.stringify({ error: 'Meetup access token not configured' }), {26 status: 500,27 headers: { 'Content-Type': 'application/json' },28 });29 }3031 let body: { query: string; variables?: Record<string, unknown> };32 try {33 body = await req.json();34 } catch {35 return new Response(JSON.stringify({ error: 'Invalid JSON body' }), {36 status: 400,37 headers: { 'Content-Type': 'application/json' },38 });39 }4041 if (!body.query) {42 return new Response(JSON.stringify({ error: 'GraphQL query is required' }), {43 status: 400,44 headers: { 'Content-Type': 'application/json' },45 });46 }4748 const meetupResponse = await fetch(MEETUP_GRAPHQL_URL, {49 method: 'POST',50 headers: {51 'Content-Type': 'application/json',52 'Authorization': `Bearer ${accessToken}`,53 },54 body: JSON.stringify({ query: body.query, variables: body.variables }),55 });5657 const data = await meetupResponse.json();5859 return new Response(JSON.stringify(data), {60 status: meetupResponse.status,61 headers: {62 'Content-Type': 'application/json',63 'Access-Control-Allow-Origin': '*',64 },65 });66});Expected result: The Edge Function is deployed and visible in Cloud → Edge Functions. Calling it with a POST request containing a valid GraphQL query returns Meetup data. The function URL follows the pattern https://[project-ref].supabase.co/functions/v1/meetup-api.
Build the event discovery UI with Lovable chat
Build the event discovery UI with Lovable chat
With the Edge Function in place, use Lovable's chat to generate the frontend components. Lovable will create React components that call your Edge Function, display events in a card grid or list, and handle loading and error states — all without you writing any React code manually. The key is to be specific about the UI layout and the GraphQL query you want the component to use. Meetup's GraphQL schema exposes a keywordSearch query for event discovery and a groupByUrlname query for accessing a specific group's events. Describe both the data you need and how you want it displayed. After Lovable generates the initial components, review them in the preview. If the event cards need additional fields (like the group photo or a map link), prompt Lovable to add them: 'Add the group photo and a Google Maps link to the venue on each event card.' If you need filtering by topic or date, describe the filter UI you want. Lovable will update the GraphQL query variables and the filter component together. For RSVP tracking, describe a separate view: 'Add an RSVP management page that shows all attendees who RSVPed yes to a selected event, with their name and join date, fetched from the meetup-api Edge Function.' Lovable will generate the attendee list component and the GraphQL query for fetching RSVP data. If you are building for multiple clients or group organizers, consider caching Meetup API responses in Supabase. Prompt Lovable: 'Store the fetched event data in a Supabase table called meetup_events_cache with a fetched_at timestamp, and only call the Meetup API if the cache is older than 15 minutes.' This reduces API call frequency and keeps your app responsive even during Meetup API slowdowns. For complex multi-tenant organizer dashboards, RapidDev's team can help architect the caching layer and OAuth refresh flow.
Create an event discovery page that calls the meetup-api Edge Function with this GraphQL query: { keywordSearch(filter: { query: $query, lat: $lat, lon: $lon, radius: $radius, source: EVENTS }) { edges { node { result { ... on Event { id title dateTime venue { name city } group { name urlname } going } } } } } }. Show results as cards with event name, date, city, group name, and RSVP count. Add a search bar and a city/radius filter. Handle loading and error states.
Paste this in Lovable chat
Pro tip: Meetup's GraphQL schema uses cursor-based pagination. For event lists longer than 20 items, ask Lovable to implement infinite scroll using the pageInfo.endCursor value returned by the API.
Expected result: A working event discovery page appears in the Lovable preview showing event cards populated from the Meetup API via the Edge Function. Searching by keyword or changing the location filter fetches and displays updated results.
Handle OAuth token refresh and error states
Handle OAuth token refresh and error states
Meetup OAuth access tokens expire after one hour. If your app makes API calls over an extended session or on a scheduled basis, you will eventually hit a 401 Unauthorized response from Meetup's API. Handling this gracefully requires the Edge Function to detect the expired token, exchange the refresh token for a new access token, and retry the original request — all transparently to the frontend user. Update the Edge Function to implement token refresh. Add a helper function that calls Meetup's token endpoint (https://secure.meetup.com/oauth2/access) with your client credentials and refresh token. When the Meetup GraphQL call returns a 401, call the refresh helper, store the new access token (for the scope of this request — Supabase Secrets cannot be updated at runtime, so for long-term persistence you would store tokens in a Supabase table), and retry. For apps that run Edge Functions on a schedule (checking for new RSVPs or event updates), the better pattern is to store OAuth tokens in a Supabase database table with an expires_at column. Before each API call, the Edge Function checks whether the stored token has expired, refreshes it if needed, updates the database record, and then proceeds with the API call. This approach survives Deno cold starts and works correctly across multiple concurrent function invocations. Also handle the case where the Meetup API returns GraphQL errors alongside a 200 HTTP status — Meetup follows the GraphQL convention of returning errors in the response body rather than using HTTP error codes. Check the response for a top-level errors array and surface these to your frontend with a user-friendly message.
Update the meetup-api Edge Function to handle 401 responses from Meetup by refreshing the OAuth token using the MEETUP_CLIENT_ID, MEETUP_CLIENT_SECRET, and MEETUP_REFRESH_TOKEN secrets. Store the new access token in a Supabase table called 'oauth_tokens' with the provider name, token value, and expires_at timestamp. Retry the original GraphQL request after a successful token refresh.
Paste this in Lovable chat
Expected result: The Edge Function handles token expiry gracefully. When a Meetup access token expires, the function automatically refreshes it and retries the request without returning an error to the frontend. Token refresh events are logged in Cloud → Logs.
Common use cases
Event discovery dashboard for a local community app
Build a searchable map and list view showing upcoming Meetup events near a given location, filtered by topic, group, or date. Users can browse events, see attendance counts, and click through to RSVP on Meetup. This is useful for local news sites, neighborhood apps, or community portals that want to surface relevant events without building their own event system.
Create an event discovery page that calls my meetup-proxy Edge Function with a city and radius parameter. Display results in a card grid showing event name, date, location, group name, and RSVP count. Add filters for date range and topic category. Each card should link to the Meetup event page.
Copy this prompt to try it in Lovable
Group organizer dashboard for managing multiple Meetups
Give Meetup group organizers a centralized view of their upcoming events, pending RSVPs, and attendance history across multiple groups. The dashboard aggregates data from Meetup's GraphQL API and stores snapshots in Supabase for trend analysis and export.
Build a group organizer dashboard that fetches my Meetup groups and their upcoming events from the meetup-api Edge Function. Show a table of events with RSVP counts, waitlist numbers, and attendance rate from previous events. Add a button to export the attendee list for a selected event as CSV.
Copy this prompt to try it in Lovable
RSVP tracking and reminder notifications
Sync Meetup RSVP data into Supabase on a schedule and send reminder notifications to attendees via email or SMS. The Edge Function polls Meetup's API for RSVP changes, upserts records into a Supabase table, and triggers notification workflows for events happening within 24 hours.
Create an Edge Function that fetches RSVPs for my upcoming Meetup events and stores them in a Supabase 'meetup_rsvps' table. Then build a UI that shows who has RSVPed for each event, with a button to send a reminder email to all confirmed attendees using the Resend integration.
Copy this prompt to try it in Lovable
Troubleshooting
Edge Function returns 401 Unauthorized from the Meetup API
Cause: The OAuth access token stored in MEETUP_ACCESS_TOKEN has expired. Meetup access tokens are valid for only one hour.
Solution: Generate a fresh access token by re-authorizing your OAuth application at secure.meetup.com/oauth2/access. Update the MEETUP_ACCESS_TOKEN value in Cloud → Secrets with the new token. For a long-term fix, implement the refresh token flow described in Step 5 so the Edge Function automatically renews tokens.
GraphQL query returns empty data or 'field does not exist' errors
Cause: Meetup's GraphQL schema uses specific field names and union types. Querying fields that do not exist on the result type (for example, treating all keywordSearch results as Events when they can also be Groups) will silently return null or throw schema errors.
Solution: Use GraphQL inline fragments to handle union types. When querying keywordSearch, wrap event fields in '... on Event { }' and group fields in '... on Group { }'. Test your queries directly against Meetup's GraphQL explorer at api.meetup.com/gql before adding them to your Edge Function.
1// Correct union type handling in Meetup GraphQL2const query = `3 query SearchEvents($query: String!) {4 keywordSearch(filter: { query: $query, source: EVENTS }) {5 edges {6 node {7 result {8 ... on Event {9 id10 title11 dateTime12 going13 venue { name city }14 group { name urlname }15 }16 }17 }18 }19 }20 }21`;CORS error when the frontend calls the Edge Function
Cause: The Edge Function is not returning the correct Access-Control-Allow-Origin headers, or the OPTIONS preflight request is not being handled before the authentication check.
Solution: Ensure the Edge Function handles OPTIONS requests at the very beginning of the handler, before any authentication or logic. Return the CORS headers on every response, including error responses. The code in Step 3 shows the correct pattern — make sure the OPTIONS handler returns a 200 response with the CORS headers and exits before reaching any other logic.
Meetup OAuth application shows 'Redirect URI mismatch' error during authorization
Cause: The redirect URI used in the OAuth authorization request does not exactly match one of the redirect URIs registered in your Meetup OAuth application settings.
Solution: Go to secure.meetup.com/oauth2/clients and edit your application. Add the exact redirect URI your app is using, including the correct protocol (https, not http), domain, and path. Redirect URIs are case-sensitive and must match character-for-character. If you deployed to a custom domain, add that URL in addition to the default lovable.app URL.
Best practices
- Store all OAuth credentials — client ID, client secret, access token, and refresh token — in Cloud → Secrets, never in frontend code or Lovable chat prompts
- Implement token refresh logic in the Edge Function so expired tokens do not cause user-facing errors; store refreshed tokens in a Supabase table with an expires_at column
- Cache Meetup API responses in Supabase for at least 15 minutes to reduce API call volume and improve page load speed, especially for public event discovery pages
- Use GraphQL inline fragments (... on Event, ... on Group) when querying Meetup's keywordSearch endpoint to correctly handle the union return type
- Always test GraphQL queries in Meetup's API explorer before embedding them in Edge Functions to catch schema errors before deployment
- Handle Meetup API rate limits (typically 200 requests per hour) by tracking request counts in Supabase and surfacing a friendly message when the limit is approached
- Use cursor-based pagination for event lists to avoid loading all results at once — request the pageInfo.endCursor field and implement infinite scroll on the frontend
Alternatives
Choose Eventbrite if your use case involves paid ticketing, seat maps, or large commercial events — Eventbrite was built for ticketed commerce while Meetup focuses on recurring community gatherings.
Choose Vimeo if you need to stream or host recordings of your events rather than discover and manage RSVPs — Vimeo is a video platform, not an event discovery service.
Choose Buffer if you need to promote your Meetup events across social media channels on a publishing schedule rather than manage the events themselves.
Frequently asked questions
Does the Meetup API require OAuth2 for all requests?
Most Meetup API queries — including event search, group data, and RSVP counts — require a valid OAuth2 access token. There is no public unauthenticated API tier for most data. You will need to register an OAuth application and obtain an access token before querying the API. For read-only access to public event data, a personal access token is sufficient and simpler than implementing the full authorization code flow.
Can Lovable users sign in with their Meetup accounts?
Lovable's native authentication is Supabase Auth, which supports Google, GitHub, Apple, and email logins but not Meetup as a social login provider. If you want users to authenticate with Meetup to access their personal RSVPs and group memberships, you would need to implement Meetup's OAuth2 authorization code flow as a custom auth layer alongside Supabase Auth — storing the Meetup OAuth token in the user's Supabase profile after they authorize. This is an advanced pattern that requires custom Edge Functions for the OAuth callback and token storage.
Why use an Edge Function instead of calling Meetup's API directly from React?
Meetup's API requires an OAuth Bearer token in the Authorization header. If you call the Meetup API directly from browser JavaScript, this token is visible in browser developer tools and network logs. Any user of your app could extract the token and use it to make API calls on your behalf. The Edge Function proxy keeps the token server-side, never exposing it to the browser. Additionally, Edge Functions eliminate CORS issues that arise when calling third-party APIs from browser code.
How do I handle Meetup API rate limits?
Meetup enforces rate limits at the OAuth application level, typically around 200 requests per hour for standard applications. To stay within limits, cache API responses in Supabase (store results with a fetched_at timestamp and return cached data if it is less than 15 minutes old), batch GraphQL queries to fetch multiple resources in a single request, and avoid polling for updates — instead use Meetup's webhook feature (available for group organizers) to receive push notifications when events or RSVPs change.
What is the difference between Meetup and Eventbrite for building integrations?
Meetup and Eventbrite serve different event models. Meetup is built around recurring community groups where events are typically free or low-cost, with a social graph of members who follow groups. Eventbrite is built around one-off ticketed events with paid entry, seat maps, and attendee check-in flows. If your app needs ticket sales, payment processing for event access, or QR code check-in, use Eventbrite's API. If your app needs group discovery, member engagement, and recurring event tracking, use Meetup's API.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation