To integrate Replit with GoToMeeting, register a GoTo developer application to get OAuth 2.0 credentials, store them in Replit Secrets (lock icon π), and call the GoTo REST API from your Python or Node.js backend to create meetings, manage attendees, and retrieve recordings. Deploy with Autoscale for on-demand meeting creation or Reserved VM for scheduled meeting automation.
Why Connect Replit to GoToMeeting?
GoToMeeting is a staple in enterprise environments where compliance, admin controls, and reliability are paramount. Its REST API enables developers to embed video meeting creation and management directly into business applications β scheduling tools, CRMs, LMS platforms, and customer portals β without requiring users to manually log into the GoToMeeting interface.
The GoTo API family (which includes GoToMeeting, GoToWebinar, and GoToTraining) uses a unified OAuth 2.0 authentication system. Once a user authorizes your application, you receive an access token that lets your Replit backend create meetings on their behalf, retrieve attendee data after sessions, and access recordings. This is particularly valuable for automating post-meeting workflows: pulling attendee lists into a CRM, sending follow-up emails, or archiving recordings to cloud storage.
Difference from Zoom: GoToMeeting targets enterprise customers with stronger IT administration features, compliance controls, and integration into the broader GoTo product suite. Its API is more complex to set up (OAuth 2.0 is required even for single-user scenarios) but provides granular control over meeting settings, co-organizer permissions, and dial-in options. Keep all credentials in Replit Secrets (lock icon π) and always exchange tokens server-side β never expose OAuth credentials to client-side code.
Integration method
You connect Replit to GoToMeeting by registering a developer application in the GoTo developer portal to obtain OAuth 2.0 credentials, storing them in Replit Secrets, and calling the GoTo REST API from your server-side Python or Node.js code. The API supports creating and managing meetings, retrieving attendee lists, accessing recordings, and handling webhook events for meeting lifecycle. OAuth 2.0 requires an authorization flow to obtain access tokens on behalf of GoToMeeting organizers.
Prerequisites
- A Replit account with a Python or Node.js project created
- A GoToMeeting organizer account (requires a paid GoToMeeting subscription)
- A developer account at developer.goto.com to create an OAuth application
- Basic familiarity with OAuth 2.0 authorization code flow
- Node.js 18+ or Python 3.10+ (both available on Replit by default)
Step-by-step guide
Register a GoTo Developer Application
Register a GoTo Developer Application
Visit the GoTo Developer Center at developer.goto.com and sign in with your GoToMeeting organizer account. Navigate to 'My Apps' and click 'Create App'. Fill in the application details: - Application Name: a descriptive name like 'Replit Meeting Integration' - Description: briefly describe what your app will do - Redirect URI: your Replit app's OAuth callback URL, for example https://your-repl.your-username.repl.co/oauth/callback (you will deploy this endpoint in a later step) - Scopes: select 'collab:meetings:write' and 'collab:meetings:read' for meeting management, and 'collab:recordings:read' if you need recording access After creating the app, GoTo provides a Client ID and Client Secret. These are your OAuth 2.0 credentials. The Client ID identifies your application; the Client Secret is used server-side to exchange authorization codes for access tokens. Important: GoToMeeting does not support client credentials grant (machine-to-machine) for meeting creation β you must use the authorization code flow where a real GoToMeeting organizer authorizes your app. This is a key difference from APIs like Stripe or Mailchimp that use simple API keys.
Pro tip: Add the redirect URI exactly as it will appear in your deployed Replit app, including the https:// scheme. OAuth redirect URIs must match exactly β any difference in trailing slashes or URL paths will cause authorization failures.
Expected result: You have a GoTo OAuth Client ID and Client Secret from the developer portal, and you have configured the redirect URI to point to your Replit deployment URL.
Store GoTo Credentials in Replit Secrets
Store GoTo Credentials in Replit Secrets
Open your Replit project and click the lock icon π in the left sidebar to open the Secrets pane. Add the following secrets: - Key: GOTO_CLIENT_ID β Value: your GoTo OAuth Client ID - Key: GOTO_CLIENT_SECRET β Value: your GoTo OAuth Client Secret - Key: GOTO_REDIRECT_URI β Value: your OAuth callback URL (e.g., https://your-repl.repl.co/oauth/callback) Once you complete the OAuth flow and obtain tokens (step 3), also add: - Key: GOTO_ACCESS_TOKEN β Value: the access token from the OAuth response - Key: GOTO_REFRESH_TOKEN β Value: the refresh token from the OAuth response Access these in Python with os.environ['GOTO_CLIENT_ID'] and in Node.js with process.env.GOTO_CLIENT_ID. Replit encrypts secrets at rest and they are never exposed in your file tree or version control history. For production integrations where multiple organizers authorize your app, you should store tokens in a database (keyed by organizer user ID) rather than in Replit Secrets, since Secrets only hold a single value per key.
Pro tip: GoTo access tokens expire after one hour. Always implement token refresh logic (using the refresh token with the token endpoint) so your integration does not break overnight. Store the refresh token securely β it is long-lived and can generate new access tokens.
Expected result: GOTO_CLIENT_ID, GOTO_CLIENT_SECRET, and GOTO_REDIRECT_URI appear in the Replit Secrets pane.
Implement OAuth 2.0 Authorization Flow
Implement OAuth 2.0 Authorization Flow
GoToMeeting requires a real user (the meeting organizer) to authorize your application before your backend can create meetings on their behalf. This authorization code flow works as follows: your app redirects the organizer to the GoTo authorization URL, the organizer logs in and approves access, GoTo redirects back to your callback URL with an authorization code, and your backend exchanges that code for access and refresh tokens. The Python Flask code below implements both the redirect endpoint and the callback handler. Install dependencies with pip install flask requests in the Replit shell. After the first authorization, you can store the tokens and use the refresh token to obtain new access tokens automatically without requiring the user to re-authorize.
1import os2import requests3from flask import Flask, redirect, request, jsonify45app = Flask(__name__)67CLIENT_ID = os.environ["GOTO_CLIENT_ID"]8CLIENT_SECRET = os.environ["GOTO_CLIENT_SECRET"]9REDIRECT_URI = os.environ["GOTO_REDIRECT_URI"]1011AUTH_URL = "https://authentication.logmeininc.com/oauth/authorize"12TOKEN_URL = "https://authentication.logmeininc.com/oauth/token"1314# In-memory token storage (use a database in production)15tokens = {}1617@app.route('/oauth/start')18def oauth_start():19 """Redirect organizer to GoTo authorization page."""20 auth_url = (21 f"{AUTH_URL}"22 f"?response_type=code"23 f"&client_id={CLIENT_ID}"24 f"&redirect_uri={REDIRECT_URI}"25 )26 return redirect(auth_url)2728@app.route('/oauth/callback')29def oauth_callback():30 """Handle OAuth callback and exchange code for tokens."""31 code = request.args.get('code')32 if not code:33 return jsonify({'error': 'No authorization code received'}), 4003435 # Exchange authorization code for access + refresh tokens36 response = requests.post(TOKEN_URL, data={37 'grant_type': 'authorization_code',38 'code': code,39 'redirect_uri': REDIRECT_URI,40 'client_id': CLIENT_ID,41 'client_secret': CLIENT_SECRET42 })43 response.raise_for_status()44 token_data = response.json()4546 tokens['access_token'] = token_data['access_token']47 tokens['refresh_token'] = token_data.get('refresh_token', '')48 tokens['organizer_key'] = token_data.get('account_key', '')4950 return jsonify({'message': 'Authorization successful', 'organizer_key': tokens['organizer_key']})5152def refresh_access_token() -> str:53 """Use refresh token to get a new access token."""54 response = requests.post(TOKEN_URL, data={55 'grant_type': 'refresh_token',56 'refresh_token': tokens.get('refresh_token', os.environ.get('GOTO_REFRESH_TOKEN', '')),57 'client_id': CLIENT_ID,58 'client_secret': CLIENT_SECRET59 })60 response.raise_for_status()61 token_data = response.json()62 tokens['access_token'] = token_data['access_token']63 return tokens['access_token']6465if __name__ == '__main__':66 app.run(host='0.0.0.0', port=3000)Pro tip: Visit /oauth/start in a browser while your Replit server is running to kick off the authorization flow. After authorizing, you will be redirected back to /oauth/callback and your tokens will be stored. Copy the access and refresh tokens to Replit Secrets for persistence.
Expected result: Visiting /oauth/start redirects you to GoTo login, and after authorizing, /oauth/callback returns a success message with the organizer key.
Create and Manage GoToMeeting Meetings
Create and Manage GoToMeeting Meetings
With an access token, you can create GoToMeeting sessions, retrieve meeting details, and access attendee reports. The GoTo API base URL for meetings is https://api.getgo.com/G2M/rest. All requests require the Authorization: Bearer {access_token} header. Meeting creation requires the organizer key (from the token response) and specifies the subject, start time, end time, and settings like whether to require passwords or enable recording. After creating a meeting, you receive a meeting ID and a join URL that attendees use to enter the session. The Python module below builds on the OAuth server from step 3 to provide full meeting management.
1import os2import requests3from datetime import datetime, timedelta, timezone4from typing import Optional56API_BASE = "https://api.getgo.com/G2M/rest"78def get_headers(access_token: str) -> dict:9 return {10 "Authorization": f"Bearer {access_token}",11 "Content-Type": "application/json",12 "Accept": "application/json"13 }1415def create_meeting(16 access_token: str,17 organizer_key: str,18 subject: str,19 start_time: datetime,20 end_time: datetime,21 password: str = ""22) -> dict:23 """24 Create a GoToMeeting session.25 Times must be timezone-aware UTC datetimes.26 """27 url = f"{API_BASE}/organizers/{organizer_key}/meetings"28 payload = {29 "subject": subject,30 "starttime": start_time.strftime("%Y-%m-%dT%H:%M:%SZ"),31 "endtime": end_time.strftime("%Y-%m-%dT%H:%M:%SZ"),32 "passwordRequired": bool(password),33 "conferenceCallInfo": "Hybrid",34 "meetingType": "scheduled"35 }36 if password:37 payload["password"] = password3839 response = requests.post(url, json=payload, headers=get_headers(access_token))40 response.raise_for_status()41 return response.json()4243def get_upcoming_meetings(access_token: str, organizer_key: str) -> list:44 """Retrieve all upcoming scheduled meetings for the organizer."""45 url = f"{API_BASE}/organizers/{organizer_key}/upcomingMeetings"46 response = requests.get(url, headers=get_headers(access_token))47 response.raise_for_status()48 return response.json()4950def get_attendees(access_token: str, organizer_key: str, meeting_instance_key: str) -> list:51 """Retrieve attendee list for a completed meeting instance."""52 url = f"{API_BASE}/organizers/{organizer_key}/historicalMeetings/{meeting_instance_key}/attendees"53 response = requests.get(url, headers=get_headers(access_token))54 response.raise_for_status()55 return response.json()5657def delete_meeting(access_token: str, organizer_key: str, meeting_id: str) -> None:58 """Cancel and delete a scheduled meeting."""59 url = f"{API_BASE}/organizers/{organizer_key}/meetings/{meeting_id}"60 response = requests.delete(url, headers=get_headers(access_token))61 response.raise_for_status()6263# Example usage64if __name__ == "__main__":65 ACCESS_TOKEN = os.environ.get("GOTO_ACCESS_TOKEN", "")66 ORGANIZER_KEY = os.environ.get("GOTO_ORGANIZER_KEY", "")6768 if not ACCESS_TOKEN or not ORGANIZER_KEY:69 print("Set GOTO_ACCESS_TOKEN and GOTO_ORGANIZER_KEY in Replit Secrets")70 else:71 start = datetime.now(timezone.utc) + timedelta(hours=2)72 end = start + timedelta(hours=1)73 meeting = create_meeting(74 access_token=ACCESS_TOKEN,75 organizer_key=ORGANIZER_KEY,76 subject="Q2 Sales Review",77 start_time=start,78 end_time=end79 )80 print(f"Meeting created: {meeting}")81 # meeting[0]['joinURL'] contains the attendee join linkPro tip: The create_meeting endpoint returns a list (even for a single meeting) in older API versions. Always access the join URL as meeting[0]['joinURL'] rather than meeting['joinURL'] to avoid key errors.
Expected result: Running the Python script creates a GoToMeeting session and prints the meeting details including the join URL for attendees.
Common use cases
CRM-Driven Client Meeting Scheduling
When a sales rep marks a deal as 'demo scheduled' in your CRM, your Replit backend automatically creates a GoToMeeting session, adds the client as an attendee, and sends the meeting link to both parties. After the meeting, it pulls the attendee report and logs participation data back to the CRM.
Build a Flask webhook endpoint that receives CRM deal update events, creates a GoToMeeting via the GoTo REST API when status changes to 'demo_scheduled', and sends the meeting URL to both the sales rep and the client via email.
Copy this prompt to try it in Replit
Post-Meeting Recording Archival
A Replit scheduled job runs after business hours to retrieve all recordings from GoToMeeting sessions that ended that day, download the recording URLs, and archive them to cloud storage with metadata tags including the organizer name and attendee list.
Create a Python script that fetches all GoToMeeting recordings from the past 24 hours via the GoTo API, retrieves download URLs, and uploads each recording to AWS S3 with metadata about the meeting organizer and attendees.
Copy this prompt to try it in Replit
Automated Training Session Management
An LMS backend built on Replit creates GoToMeeting sessions for live training events, tracks which learners attended by comparing enrollment lists with the GoToMeeting attendee report, and automatically issues completion certificates to those who attended the full session.
Write a Node.js Express server that creates a GoToMeeting for each scheduled LMS training session, retrieves the attendee report after the session ends, and marks learners as complete in the database if they attended for at least 75% of the session duration.
Copy this prompt to try it in Replit
Troubleshooting
OAuth callback returns 'invalid_client' or 'invalid_grant' error
Cause: The Client ID or Client Secret is incorrect, the redirect URI in the OAuth request does not exactly match the one registered in the GoTo developer portal, or the authorization code has already been used (codes are single-use and expire quickly).
Solution: Verify GOTO_CLIENT_ID and GOTO_CLIENT_SECRET in Replit Secrets match the values in your GoTo developer portal app. Ensure the redirect URI in your code exactly matches the registered URI, including the http/https scheme and any trailing slashes. Restart the OAuth flow if the code expired.
1# Ensure redirect URI matches exactly what is registered in GoTo portal2REDIRECT_URI = os.environ["GOTO_REDIRECT_URI"]3# e.g., 'https://your-repl.repl.co/oauth/callback' β no trailing slashMeeting creation returns 401 after the integration worked earlier
Cause: GoTo access tokens expire after one hour. After expiry, all API calls return 401 Unauthorized until the token is refreshed using the refresh token endpoint.
Solution: Implement automatic token refresh: catch 401 responses, call the token refresh endpoint with your refresh token, and retry the original request with the new access token.
1def api_request_with_refresh(method, url, access_token, refresh_fn, **kwargs):2 """Make an API request, refreshing the token on 401."""3 headers = get_headers(access_token)4 resp = requests.request(method, url, headers=headers, **kwargs)5 if resp.status_code == 401:6 new_token = refresh_fn()7 headers = get_headers(new_token)8 resp = requests.request(method, url, headers=headers, **kwargs)9 resp.raise_for_status()10 return resp.json()GET /upcomingMeetings returns an empty list even though meetings exist
Cause: The organizer key used in the URL does not match the organizer who owns the meetings, or the access token belongs to a different user than expected.
Solution: Use the organizer_key returned in the initial OAuth token response, not a hardcoded value. Store it in Replit Secrets as GOTO_ORGANIZER_KEY and verify it matches the authenticated user's key by calling GET /organizers/{organizerKey} first.
1# Get organizer key from OAuth token response2token_data = response.json()3organizer_key = token_data.get('account_key') or token_data.get('organizer_key')4# Store this in Replit Secrets as GOTO_ORGANIZER_KEYMeeting attendee endpoint returns 404 or empty data immediately after a meeting ends
Cause: GoToMeeting takes time (up to 15-30 minutes) to process and publish attendee data after a meeting ends. Polling immediately after meeting end time will return empty results.
Solution: Implement a delay before retrieving attendee data. Use a scheduled job that runs 30-60 minutes after the meeting end time rather than triggering immediately on meeting end. The meeting instance key (different from meeting ID) is required for the historical meetings endpoint.
Best practices
- Store GOTO_CLIENT_ID, GOTO_CLIENT_SECRET, GOTO_ACCESS_TOKEN, and GOTO_REFRESH_TOKEN in Replit Secrets β never hardcode OAuth credentials in source files
- Implement automatic token refresh to catch 401 responses, call the refresh token endpoint, and retry the request with the new access token
- Store the organizer key from the OAuth token response in Replit Secrets as GOTO_ORGANIZER_KEY β it is required for all organizer-scoped API calls
- Use timezone-aware UTC datetimes when creating meetings β GoToMeeting expects ISO 8601 format with the Z suffix
- Wait 30-60 minutes after a meeting ends before retrieving attendee reports β data processing takes time
- For multi-organizer apps, store tokens in a database keyed by user ID rather than relying on single-value Replit Secrets
- Deploy meeting creation endpoints on Replit Autoscale for on-demand HTTP requests, and use Reserved VM for scheduled post-meeting processing jobs
- Validate that meeting start times are in the future before calling the API to provide clear error messages rather than cryptic 400 responses
Alternatives
Zoom has broader consumer adoption and a simpler API with JWT and OAuth options, making it a better choice for apps targeting a general audience rather than enterprise-specific deployments.
Google Meet is managed via the Google Calendar API and is free for Google Workspace users, making it a better fit for organizations already in the Google ecosystem.
Webex targets Cisco enterprise environments with deep networking integrations and hardware room systems, making it better when GoToMeeting's specific compliance features are not required but Cisco infrastructure is in place.
Slack provides huddles and clips for lightweight video communication alongside messaging, making it a better choice if your team already uses Slack and does not need dedicated video conferencing with recording.
Frequently asked questions
How do I connect Replit to GoToMeeting?
Register a developer app at developer.goto.com to get OAuth 2.0 credentials, then add GOTO_CLIENT_ID, GOTO_CLIENT_SECRET, and GOTO_REDIRECT_URI to Replit Secrets. Implement the OAuth authorization code flow to obtain access and refresh tokens, then call the GoTo REST API with Bearer token authentication.
Does GoToMeeting require OAuth for API access?
Yes. The GoTo REST API requires OAuth 2.0 authorization code flow β there is no simple API key option for meeting creation. A real GoToMeeting organizer must authorize your application to create meetings on their behalf. This is different from email APIs that use simple key-based auth.
How do I store GoToMeeting credentials securely in Replit?
Click the lock icon π in the Replit sidebar to open Secrets and add GOTO_CLIENT_ID, GOTO_CLIENT_SECRET, GOTO_ACCESS_TOKEN, GOTO_REFRESH_TOKEN, and GOTO_ORGANIZER_KEY. Access tokens expire after one hour, so implement refresh logic using the refresh token to avoid authentication failures.
Can I create GoToMeeting sessions automatically from my Replit app?
Yes, once you have completed the OAuth flow and obtained an access token. POST to /organizers/{organizerKey}/meetings with the meeting subject, start time, and end time. The response includes a join URL for attendees and a meeting ID for future management operations.
How do I get attendee data from GoToMeeting after a session?
Use GET /organizers/{organizerKey}/historicalMeetings/{meetingInstanceKey}/attendees after the meeting ends. Note that attendee data takes 30-60 minutes to process after meeting completion, so implement a delayed job rather than polling immediately.
What deployment type should I use on Replit for GoToMeeting integrations?
Use Autoscale deployment for HTTP-triggered meeting creation endpoints. Use Reserved VM for continuously running processes that monitor meeting status or run scheduled post-meeting jobs to retrieve attendee reports and process recordings.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation