meetupr is an R package that provides a client for the Meetup.com GraphQL API. It allows you to search for groups, retrieve event information, get member lists, and access other Meetup data directly from R. This vignette will guide you through setup, authentication, and common use cases.
Start by running meetupr_sitrep() to check your
authentication status or set up authentication:
meetupr_sitrep()
#>
#> ── meetupr Situation Report ────────────────────────────────────────────────────
#>
#> ── Active Authentication Method ──
#>
#> ✔ Authentication available
#> ℹ Active method: jwt
#> ℹ Client name: rladies
#> ✔ JWT token: Available and valid
#> ✔ JWT issuer: 251470805
#> ✔ Client key: sr9210...
#>
#> ── API Connectivity Test ──
#>
#> ✔ API Connection: Working
#> ℹ Authenticated as: R-Ladies GlobalThis function shows you:
The function provides actionable feedback, telling you exactly what to do if authentication isn’t working.
Authentication is required to access the Meetup API. meetupr automatically detects whether you’re working interactively or in an automated environment:
This detection uses rlang::is_interactive() to determine
the context and switch authentication flows accordingly.
When working interactively:
# First time: browser opens for authorization
get_group("rladies-lagos")
# Subsequent calls: uses cached token (no browser)
get_group_events("rladies-lagos")When running non-interactively (GitHub Actions, cron jobs):
# Load token from environment variables (set via CI secrets)
meetupr_encrypt_load()
# All API calls use the loaded token
get_group_events("rladies-lagos")The package handles the switching automatically — you don’t need to change your code between environments.
For interactive use (exploring data, one-off analyses), simply authenticate when prompted:
# Authenticate interactively (opens browser)
meetupr_auth()
# Check authentication status
meetupr_auth_status()When you run meetupr_auth():
The OAuth token is stored locally in your httr2 cache directory.
Token files follow the naming pattern:
{hash}-token.rds.enc. These files are encrypted and
specific to your system.
You only need to authenticate once. The token will be reused in future R sessions until it expires (typically after 90 days).
meetupr also supports secure, non-interactive authentication for automated workflows (such as GitHub Actions, GitLab CI, and other CI/CD systems). This allows you to run scripts and scheduled jobs without manual login.
For details on setting up meetupr in CI/CD, including secure token management and advanced authentication options, see the Advanced Authentication vignette.
After authenticating, verify the setup:
meetupr_sitrep()
#>
#> ── meetupr Situation Report ────────────────────────────────────────────────────
#>
#> ── Active Authentication Method ──
#>
#> ✔ Authentication available
#> ℹ Active method: jwt
#> ℹ Client name: rladies
#> ✔ JWT token: Available and valid
#> ✔ JWT issuer: 251470805
#> ✔ Client key: sr9210...
#>
#> ── API Connectivity Test ──
#>
#> ✔ API Connection: Working
#> ℹ Authenticated as: R-Ladies GlobalThe output shows:
Once authenticated, you can start querying the Meetup API. All functions return tibbles (data frames) for easy manipulation with dplyr and other tidyverse packages.
Retrieve detailed information about a specific group using its URL
name (the part after meetup.com/ in the URL):
group_info <- get_group("rladies-lagos")
str(group_info)
#> List of 13
#> $ id : chr "32612004"
#> $ name : chr "R-Ladies Lagos"
#> $ description : chr "R-Ladies is a world-wide organization to promote gender diversity in the R community.\nR-Ladies welcomes member"| __truncated__
#> $ urlname : chr "rladies-lagos"
#> $ link : chr "https://www.meetup.com/rladies-lagos"
#> $ location :List of 2
#> ..$ city : chr "Lagos"
#> ..$ country: chr "ng"
#> $ timezone : chr "Africa/Lagos"
#> $ created : POSIXct[1:1], format: "2019-08-16 10:45:21"
#> $ members : int 893
#> $ total_events: int 13
#> $ organizer :List of 2
#> ..$ id : chr "251470805"
#> ..$ name: chr "R-Ladies Global"
#> $ category :List of 2
#> ..$ id : chr "546"
#> ..$ name: chr "Technology"
#> $ photo_url : chr "https://secure-content.meetupstatic.com/images/classic-events/"
#> - attr(*, "class")= chr [1:2] "meetupr_group" "list"The result includes:
Get events for a specific group. By default, this returns upcoming events:
events <- get_group_events("rladies-lagos")
head(events)
#> # A tibble: 6 × 23
#> id title event_url created_time status date_time duration description
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 264156061 satRda… https://… 2019-08-20T… PAST 2019-09-… PT7H "satRday-L…
#> 2 266757265 Data M… https://… 2019-11-26T… PAST 2019-12-… PT7H "Hi there …
#> 3 267804814 Gettin… https://… 2020-01-10T… PAST 2020-02-… PT7H "Hi there …
#> 4 284322273 Data N… https://… 2022-02-28T… PAST 2022-03-… PT2H "**About t…
#> 5 284612394 R Ladi… https://… 2022-03-14T… PAST 2022-05-… PT1H "Join us f…
#> 6 292261535 Women … https://… 2023-03-15T… PAST 2023-03-… PT2H "Join us f…
#> # ℹ 15 more variables: group_id <chr>, group_name <chr>, group_urlname <chr>,
#> # venues_id <list>, venues_name <list>, venues_address <list>,
#> # venues_city <list>, venues_state <list>, venues_postal_code <list>,
#> # venues_country <list>, venues_lat <list>, venues_lon <list>,
#> # venues_venue_type <list>, rsvps_count <int>, featured_event_photo_url <chr>Each row represents an event with:
To retrieve historical events, use the status
parameter:
past_events <- get_group_events(
"rladies-lagos",
status = "past",
max_results = 10
)
head(past_events)
#> # A tibble: 6 × 23
#> id title event_url created_time status date_time duration description
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 264156061 satRda… https://… 2019-08-20T… PAST 2019-09-… PT7H "satRday-L…
#> 2 266757265 Data M… https://… 2019-11-26T… PAST 2019-12-… PT7H "Hi there …
#> 3 267804814 Gettin… https://… 2020-01-10T… PAST 2020-02-… PT7H "Hi there …
#> 4 284322273 Data N… https://… 2022-02-28T… PAST 2022-03-… PT2H "**About t…
#> 5 284612394 R Ladi… https://… 2022-03-14T… PAST 2022-05-… PT1H "Join us f…
#> 6 292261535 Women … https://… 2023-03-15T… PAST 2023-03-… PT2H "Join us f…
#> # ℹ 15 more variables: group_id <chr>, group_name <chr>, group_urlname <chr>,
#> # venues_id <chr>, venues_name <chr>, venues_address <chr>,
#> # venues_city <chr>, venues_state <chr>, venues_postal_code <chr>,
#> # venues_country <chr>, venues_lat <dbl>, venues_lon <dbl>,
#> # venues_venue_type <chr>, rsvps_count <int>, featured_event_photo_url <chr>You can filter events within a specific date range:
# Events from 2024 onwards
recent_events <- get_group_events(
"rladies-lagos",
status = "past",
date_after = "2024-01-01T00:00:00Z"
)
head(recent_events)
#> # A tibble: 3 × 23
#> id title event_url created_time status date_time duration description
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 300026594 Build … https://… 2024-03-26T… PAST 2024-04-… PT3H "**🚀 Build…
#> 2 300356000 Intern… https://… 2024-04-11T… PAST 2024-04-… PT5H "**Celebra…
#> 3 300027094 Intern… https://… 2024-03-26T… PAST 2024-04-… PT3H "About thi…
#> # ℹ 15 more variables: group_id <chr>, group_name <chr>, group_urlname <chr>,
#> # venues_id <list>, venues_name <list>, venues_address <list>,
#> # venues_city <list>, venues_state <list>, venues_postal_code <list>,
#> # venues_country <list>, venues_lat <list>, venues_lon <list>,
#> # venues_venue_type <list>, rsvps_count <int>, featured_event_photo_url <chr>Dates must be in ISO 8601 format with timezone (typically UTC:
YYYY-MM-DDTHH:MM:SSZ).
Retrieve detailed information about a specific event using its ID:
event <- get_event(id = "103349942")
event
#>
#> ── Meetup Event ──
#>
#> • ID: "103349942"
#> • Title: Ecosystem GIS & Community Building
#> • Status: "PAST"
#> • Date/Time: 2013-02-18T18:30:00-05:00
#> • Duration: PT2H
#> • RSVPs: 97
#>
#> ── Group:
#> • Data Visualization DC ("data-visualization-dc")
#>
#> ── Venue:
#> • Name: Browsermedia/NClud
#> • Location: Washington, DC, us
#>
#> <https://www.meetup.com/data-visualization-dc/events/103349942/>The print() method displays a formatted summary. Access
individual fields with $ notation:
See who has RSVP’d to an event:
rsvps <- get_event_rsvps(id = "103349942")
head(rsvps)
#> # A tibble: 6 × 9
#> id member_id member_name member_bio member_url member_photo_url
#> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 683104152 12251810 Sean Moore Gonzalez "Backgrou… https://w… https://secure-…
#> 2 683108312 482161 Harlan Harris "" https://w… https://secure-…
#> 3 683109202 6382386 Harnam Rai "" https://w… https://secure-…
#> 4 683114012 70383262 Dario Rivera "" https://w… https://secure-…
#> 5 683114892 8783792 Aaron M "" https://w… https://secure-…
#> 6 683118132 10948775 Sam "" https://w… https://secure-…
#> # ℹ 3 more variables: member_organized_group_count <int>, guests_count <int>,
#> # status <chr>Each row represents one RSVP with:
This is useful for analyzing attendance patterns or contacting attendees (with appropriate permissions).
List members of a group:
members <- get_group_members("rladies-lagos", max_results = 10)
head(members)
#> # A tibble: 6 × 8
#> id name member_url member_photo_url status role join_time
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 251470805 R-Ladies Global https://w… https://secure-… LEADER ORGA… 2019-08-…
#> 2 225839690 EYITAYO ALIMI https://w… https://secure-… LEADER COOR… 2019-08-…
#> 3 236466773 Adedamilola Adek… https://w… https://secure-… ACTIVE MEMB… 2019-08-…
#> 4 255806325 Helen https://w… https://secure-… ACTIVE MEMB… 2019-08-…
#> 5 287781170 Alvin https://w… https://secure-… ACTIVE MEMB… 2019-08-…
#> 6 266271010 ijeoma benson https://w… <NA> ACTIVE MEMB… 2019-08-…
#> # ℹ 1 more variable: last_access_time <chr>Member data includes:
Note: Due to privacy settings, some member information may be limited.
Find groups matching a search term:
r_groups <- find_groups("R programming")
head(r_groups)
#> # A tibble: 6 × 14
#> id name urlname city state country lat lon memberships_count
#> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <int>
#> 1 38267718 R User Gr… r-nvsu Mani… "" ph 14.6 121. 3
#> 2 24890872 Warwick R… warwic… Cove… "43" gb 52.4 -1.56 918
#> 3 18574545 Johannesb… joburg… Joha… "" za -26.2 28.0 1587
#> 4 2906882 Birmingha… Birmin… Birm… "43" gb 52.5 -1.9 810
#> 5 2727002 Vienna<-R ViennaR Vien… "" at 48.2 16.4 812
#> 6 38263588 R 程式交流組 R… r-prog… Hong… "" hk 22.3 114. 8
#> # ℹ 5 more variables: founded_date <dttm>, timezone <chr>, join_mode <chr>,
#> # is_private <lgl>, membership_status <chr>Search results include:
This is useful for discovering groups in your area or analyzing group networks.
The Meetup API limits how many results can be returned in a single
request. The max_results parameter controls pagination:
# Get up to 50 events (may require multiple API calls)
many_events <- get_group_events(
"rladies-san-francisco",
status = "past",
max_results = 50
)
cli::cli_alert_info("Retrieved {nrow(many_events)} events")
#> ℹ Retrieved 50 eventsmeetupr automatically handles pagination behind the scenes. It makes multiple API requests if needed and combines the results into a single tibble.
The Meetup API rate limit is 500 requests per 60 seconds. meetupr automatically throttles requests to stay under this limit. For large batch operations, consider adding explicit delays:
If you have a Meetup Pro account, you can access network-wide data using the Pro functions. These functions require appropriate permissions and will error if you don’t have Pro access.
# Get upcoming events across all groups in network
upcoming <- get_pro_events("rladies", status = "upcoming")
head(upcoming)
# Get cancelled events
cancelled <- get_pro_events("rladies", status = "cancelled")
head(cancelled)Pro functions return data for all groups in your network with a single API call, which is more efficient than querying each group individually.
Sometimes issues arise due to misconfiguration or unexpected API behavior. Enabling debug mode shows the exact GraphQL queries being sent to the API.
local_meetupr_debug(1)
meetupr_sitrep()
#>
#> ── meetupr Situation Report ────────────────────────────────────────────────────
#>
#> ── Active Authentication Method ──
#>
#> ✔ Authentication available
#> ℹ Active method: jwt
#> ℹ Client name: rladies
#> ✔ JWT token: Available and valid
#> ✔ JWT issuer: 251470805
#> ✔ Client key: sr9210...
#>
#> ── API Connectivity Test ──
#>
#> ℹ Using GraphQL template: '/private/var/folders/y5/zlbbcqn56gx1tcg6xfb425100000gp/T/Rtmpgge72m/Rinst1a4b4da4fe20/meetupr/graphql/get_self.graphql'
#> ℹ Using jwt token authentication
#> ✔ API Connection: Working
#> ℹ Authenticated as: R-Ladies Global
find_groups("R programming")
#> ℹ Using GraphQL template: '/private/var/folders/y5/zlbbcqn56gx1tcg6xfb425100000gp/T/Rtmpgge72m/Rinst1a4b4da4fe20/meetupr/graphql/find_groups.graphql'
#> ℹ Using jwt token authentication
#> # A tibble: 200 × 14
#> id name urlname city state country lat lon memberships_count
#> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <int>
#> 1 38267718 R User … r-nvsu Mani… "" ph 14.6 121. 3
#> 2 24890872 Warwick… warwic… Cove… "43" gb 52.4 -1.56 918
#> 3 18574545 Johanne… joburg… Joha… "" za -26.2 28.0 1587
#> 4 2906882 Birming… Birmin… Birm… "43" gb 52.5 -1.9 810
#> 5 2727002 Vienna<… ViennaR Vien… "" at 48.2 16.4 812
#> 6 38263588 R 程式交流組… r-prog… Hong… "" hk 22.3 114. 8
#> 7 29568404 adminR:… adminR Bern "" ch 47.0 7.44 581
#> 8 1696476 Denver … Denver… Denv… "CO" us 39.8 -105. 1476
#> 9 21760043 R-Ladie… rladie… Buen… "" ar -34.6 -58.4 1966
#> 10 37281989 Cape To… cape-t… Cape… "" za -33.9 18.5 112
#> # ℹ 190 more rows
#> # ℹ 5 more variables: founded_date <dttm>, timezone <chr>, join_mode <chr>,
#> # is_private <lgl>, membership_status <chr>Debug output includes:
This is invaluable when queries fail unexpectedly or you’re unsure what data is being returned.
To turn it off again, set it to 0:
local_meetupr_debug(0)
meetupr_sitrep()
#>
#> ── meetupr Situation Report ────────────────────────────────────────────────────
#>
#> ── Active Authentication Method ──
#>
#> ✔ Authentication available
#> ℹ Active method: jwt
#> ℹ Client name: rladies
#> ✔ JWT token: Available and valid
#> ✔ JWT issuer: 251470805
#> ✔ Client key: sr9210...
#>
#> ── API Connectivity Test ──
#>
#> ✔ API Connection: Working
#> ℹ Authenticated as: R-Ladies Global
find_groups("R programming")
#> # A tibble: 200 × 14
#> id name urlname city state country lat lon memberships_count
#> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <int>
#> 1 38267718 R User … r-nvsu Mani… "" ph 14.6 121. 3
#> 2 24890872 Warwick… warwic… Cove… "43" gb 52.4 -1.56 918
#> 3 18574545 Johanne… joburg… Joha… "" za -26.2 28.0 1587
#> 4 2906882 Birming… Birmin… Birm… "43" gb 52.5 -1.9 810
#> 5 2727002 Vienna<… ViennaR Vien… "" at 48.2 16.4 812
#> 6 38263588 R 程式交流組… r-prog… Hong… "" hk 22.3 114. 8
#> 7 29568404 adminR:… adminR Bern "" ch 47.0 7.44 581
#> 8 1696476 Denver … Denver… Denv… "CO" us 39.8 -105. 1476
#> 9 21760043 R-Ladie… rladie… Buen… "" ar -34.6 -58.4 1966
#> 10 37281989 Cape To… cape-t… Cape… "" za -33.9 18.5 112
#> # ℹ 190 more rows
#> # ℹ 5 more variables: founded_date <dttm>, timezone <chr>, join_mode <chr>,
#> # is_private <lgl>, membership_status <chr>For persistent debugging across R sessions, set the environment
variable in your .Renviron file:
MEETUPR_DEBUG=1
Error: Authentication required
Solution: Run meetupr_sitrep() to
diagnose the issue. Common causes include:
meetupr_auth())meetupr_auth())meetupr_token
and meetupr_token_file)Warning: Multiple tokens found in cache
Solution: Clear old tokens and re-authenticate:
This happens when tokens from different OAuth applications accumulate in your cache directory.
Error: Rate limit exceeded
Solution: The Meetup API limits you to 500 requests per 60 seconds. If you hit this limit:
Sys.sleep(0.5))max_results to minimize paginationmeetupr automatically throttles requests, but aggressive batch operations may still hit limits.
Error: Group not found
Solution: Verify the group URL name. The URL name is
the part after meetup.com/ in the group’s URL. For example,
for https://www.meetup.com/rladies-san-francisco/, the URL
name is rladies-san-francisco.
Now that you’re set up, explore more advanced features:
For package updates and issues, visit the GitHub repository.
If you encounter issues:
meetupr_sitrep() for
authentication diagnosticslocal_meetupr_debug(1)) to see API queriesreprex::reprex())When reporting issues, include:
meetupr_sitrep()sessionInfo())This helps maintainers diagnose and fix problems quickly.