Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with GoToWebinar

To integrate GoToWebinar with Bolt.new, create a GoTo developer app to get your OAuth 2.0 credentials, then build a Next.js API route that handles token exchange and calls GoToWebinar's REST API for creating webinars, managing registrants, and fetching recordings. The OAuth callback URL requires a deployed domain — test with static webinar data in Bolt's preview, then deploy to Netlify or Bolt Cloud to complete the authorization flow.

What you'll learn

  • How to create a GoTo developer app and configure OAuth 2.0 credentials
  • How to implement the OAuth 2.0 authorization code flow in a Next.js API route
  • How to create webinars and manage registrants through GoToWebinar's REST API
  • How to build a webinar management dashboard showing upcoming events and registration counts
  • Why OAuth callbacks require a deployed URL and how to structure your Bolt app for this requirement
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate13 min read30 minutesCommunicationApril 2026RapidDev Engineering Team
TL;DR

To integrate GoToWebinar with Bolt.new, create a GoTo developer app to get your OAuth 2.0 credentials, then build a Next.js API route that handles token exchange and calls GoToWebinar's REST API for creating webinars, managing registrants, and fetching recordings. The OAuth callback URL requires a deployed domain — test with static webinar data in Bolt's preview, then deploy to Netlify or Bolt Cloud to complete the authorization flow.

Building Webinar Management Features with GoToWebinar and Bolt.new

GoToWebinar is purpose-built for hosting webinars at scale — it handles registration pages, attendee limits, interactive polls, Q&A moderation, and post-event recordings automatically. Its REST API lets you programmatically create webinars, retrieve registrant lists, embed registration forms, and access recording URLs, making it possible to build a complete webinar management interface directly inside a Bolt.new app.

The core challenge with GoToWebinar in Bolt.new is OAuth 2.0. Unlike APIs that use simple API keys, GoToWebinar uses the OAuth 2.0 authorization code flow where the user clicks 'Authorize' in their GoToWebinar account, and GoToWebinar redirects back to your app's callback URL with an authorization code. Bolt's WebContainer has no stable public URL, so this redirect cannot complete during development. The practical approach: build the API routes and UI in Bolt, deploy to Netlify or Bolt Cloud, then complete the OAuth authorization from the deployed site.

Once authorized, you store the access token and refresh token server-side (in your database or as encrypted session data). The access token is valid for one hour; the refresh token is used to obtain a new access token without re-authorization. Building a token refresh mechanism into your API routes is essential for production reliability — GoToWebinar will reject requests with expired access tokens, and requiring users to re-authorize hourly is not acceptable UX. Rate limiting is 100 requests per minute per token, which is sufficient for most dashboard use cases but requires caching for high-traffic applications.

Integration method

Bolt Chat + API Route

GoToWebinar integrates with Bolt.new through its REST API using OAuth 2.0 authorization. You create webinars, manage registrants, and access recordings via Next.js API routes that hold the OAuth access and refresh tokens server-side. The OAuth authorization flow requires a stable callback URL, so the initial token exchange must happen on a deployed site. Once authorized, you can store tokens in your database and use them for all subsequent API calls. GoToWebinar's rate limit is 100 requests per minute per access token.

Prerequisites

  • A GoToWebinar account (GoTo Pro plan required for API access — free trials are available)
  • A GoTo developer app created at developer.goto.com with OAuth 2.0 credentials (client ID and client secret)
  • Your GoToWebinar Organizer Key (found in your GoToWebinar account settings after API authorization)
  • A deployed URL for the OAuth callback — GoToWebinar OAuth cannot complete in the Bolt WebContainer preview
  • A Bolt.new project using Next.js for server-side API routes and session management

Step-by-step guide

1

Create a GoTo Developer App and Configure OAuth

GoToWebinar uses the GoTo developer platform for all API access. Go to developer.goto.com and sign in with your GoToWebinar account credentials. Click 'Add App' to create a new developer application. Give it a name like 'Webinar Manager' and select 'GoToWebinar' as the product. Under 'OAuth Settings', set the authorization type to 'Authorization Code'. You need to add a redirect URI — this is the URL where GoToWebinar sends the authorization code after the user approves access. Enter your deployed URL here (e.g., https://your-app.netlify.app/api/gotowebinar/callback). You cannot use localhost or WebContainer URLs for OAuth — GoToWebinar validates that the redirect URI matches exactly what's registered. After creating the app, copy your Client ID and Client Secret. These are your OAuth credentials. The Client Secret is sensitive — store it server-side only. Also note that GoToWebinar organizer keys (accountKey) are returned as part of the OAuth token response and identify which organizer's webinars you're managing. Scope your access by requesting 'collab:webinar:create collab:webinar:read' in your authorization URL.

Pro tip: Register multiple redirect URIs in your GoTo developer app — add both your Netlify URL and your Bolt Cloud URL so you can switch deployment targets without reconfiguring OAuth.

Expected result: You have a GoTo developer app with a Client ID, Client Secret, and a registered redirect URI pointing to your deployed Next.js API route.

2

Implement OAuth 2.0 Authorization Flow

GoToWebinar uses OAuth 2.0 authorization code flow, which has two steps: redirecting the user to GoToWebinar's authorization page, then exchanging the returned authorization code for access and refresh tokens. Create two API routes: one that generates the authorization URL and redirects the user, and one that handles the callback and exchanges the code for tokens. The access token expires in 3,600 seconds (1 hour). Store both the access token and refresh token in your database alongside their expiry time. Build a token refresh helper that checks if the current access token is expired and automatically requests a new one using the refresh token before making API calls. This refresh logic is critical — without it, your integration will break every hour and require users to re-authorize. The entire OAuth flow must happen from your deployed site since Bolt's WebContainer has no stable URL that GoToWebinar can redirect back to. During development, you can hardcode a test access token to test other API functionality without going through the OAuth flow.

Bolt.new Prompt

Create the OAuth flow for GoToWebinar. Build /api/gotowebinar/auth that redirects users to GoToWebinar's authorization URL with client_id from GOTOWEBINAR_CLIENT_ID, response_type=code, redirect_uri=GOTOWEBINAR_REDIRECT_URI, and scope='collab:webinar:create collab:webinar:read'. Create /api/gotowebinar/callback that receives the code parameter, exchanges it for tokens by POSTing to https://authentication.logmeininc.com/oauth/token with client credentials, and stores the access_token, refresh_token, and expires_at in the database. Create a getValidToken() helper that returns a fresh access token, refreshing if needed.

Paste this in Bolt.new chat

lib/gotowebinar-auth.ts
1// lib/gotowebinar-auth.ts
2const GOTOWEBINAR_TOKEN_URL = 'https://authentication.logmeininc.com/oauth/token';
3
4export async function exchangeCodeForTokens(code: string) {
5 const credentials = Buffer.from(
6 `${process.env.GOTOWEBINAR_CLIENT_ID}:${process.env.GOTOWEBINAR_CLIENT_SECRET}`
7 ).toString('base64');
8
9 const response = await fetch(GOTOWEBINAR_TOKEN_URL, {
10 method: 'POST',
11 headers: {
12 Authorization: `Basic ${credentials}`,
13 'Content-Type': 'application/x-www-form-urlencoded',
14 },
15 body: new URLSearchParams({
16 grant_type: 'authorization_code',
17 code,
18 redirect_uri: process.env.GOTOWEBINAR_REDIRECT_URI!,
19 }),
20 });
21
22 if (!response.ok) {
23 throw new Error(`Token exchange failed: ${await response.text()}`);
24 }
25
26 const tokens = await response.json();
27 return {
28 accessToken: tokens.access_token as string,
29 refreshToken: tokens.refresh_token as string,
30 expiresAt: Date.now() + tokens.expires_in * 1000,
31 organizerKey: tokens.organizer_key as string,
32 accountKey: tokens.account_key as string,
33 };
34}
35
36export async function refreshAccessToken(refreshToken: string) {
37 const credentials = Buffer.from(
38 `${process.env.GOTOWEBINAR_CLIENT_ID}:${process.env.GOTOWEBINAR_CLIENT_SECRET}`
39 ).toString('base64');
40
41 const response = await fetch(GOTOWEBINAR_TOKEN_URL, {
42 method: 'POST',
43 headers: {
44 Authorization: `Basic ${credentials}`,
45 'Content-Type': 'application/x-www-form-urlencoded',
46 },
47 body: new URLSearchParams({
48 grant_type: 'refresh_token',
49 refresh_token: refreshToken,
50 }),
51 });
52
53 const tokens = await response.json();
54 return {
55 accessToken: tokens.access_token as string,
56 expiresAt: Date.now() + tokens.expires_in * 1000,
57 };
58}

Pro tip: GoToWebinar refresh tokens do not expire as long as they are used at least once every 90 days. Build a background job or cron to refresh tokens proactively before they expire.

Expected result: Visiting /api/gotowebinar/auth redirects to GoToWebinar's authorization page. After approving, the user is redirected to /api/gotowebinar/callback where tokens are exchanged and stored. Subsequent API calls use the stored access token.

3

Create Webinars and Manage Registrants

With valid OAuth tokens, you can call GoToWebinar's REST API to create webinars, list upcoming sessions, and manage registrants. GoToWebinar's API base URL is https://api.getgo.com/G2W/rest/v2/organizers/{organizerKey}/. All requests require the Authorization: Bearer {accessToken} header. Creating a webinar requires specifying the subject (title), description, times (startTime and endTime in ISO 8601 format), and whether it's a single session or series. GoToWebinar returns a webinarKey that uniquely identifies the webinar — save this key for subsequent operations like adding registrants or fetching attendees. Registration management uses the webinarKey to list registrants, add new registrants with their contact details, and retrieve individual join links. GoToWebinar automatically generates confirmation emails with join links when you create a registrant via the API. Rate limit of 100 requests per minute applies per access token — cache registrant lists that change infrequently to stay under the limit.

Bolt.new Prompt

Create API routes for GoToWebinar management. Build /api/gotowebinar/webinars (GET) that fetches upcoming webinars for the organizer. Build /api/gotowebinar/webinars/create (POST) that accepts title, description, startTime, endTime, and creates a new webinar. Build /api/gotowebinar/webinars/[webinarKey]/registrants (GET and POST) for listing and creating registrants. All routes should use the stored OAuth access token and the organizer key from GOTOWEBINAR_ORGANIZER_KEY.

Paste this in Bolt.new chat

app/api/gotowebinar/webinars/route.ts
1// app/api/gotowebinar/webinars/route.ts
2import { NextResponse } from 'next/server';
3
4const G2W_BASE = 'https://api.getgo.com/G2W/rest/v2';
5
6export async function GET() {
7 const accessToken = process.env.GOTOWEBINAR_ACCESS_TOKEN; // Replace with DB lookup
8 const organizerKey = process.env.GOTOWEBINAR_ORGANIZER_KEY;
9
10 const fromDate = new Date().toISOString();
11 const toDate = new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString();
12
13 try {
14 const response = await fetch(
15 `${G2W_BASE}/organizers/${organizerKey}/webinars?fromTime=${fromDate}&toTime=${toDate}`,
16 {
17 headers: {
18 Authorization: `Bearer ${accessToken}`,
19 Accept: 'application/json',
20 },
21 }
22 );
23
24 const data = await response.json();
25 return NextResponse.json(data);
26 } catch (error: unknown) {
27 const e = error as { message: string };
28 return NextResponse.json({ error: e.message }, { status: 500 });
29 }
30}
31
32export async function POST(request: Request) {
33 const accessToken = process.env.GOTOWEBINAR_ACCESS_TOKEN;
34 const organizerKey = process.env.GOTOWEBINAR_ORGANIZER_KEY;
35 const { subject, description, startTime, endTime } = await request.json();
36
37 const response = await fetch(
38 `${G2W_BASE}/organizers/${organizerKey}/webinars`,
39 {
40 method: 'POST',
41 headers: {
42 Authorization: `Bearer ${accessToken}`,
43 'Content-Type': 'application/json',
44 },
45 body: JSON.stringify({
46 subject,
47 description,
48 times: [{ startTime, endTime }],
49 type: 'single_session',
50 isOnDemand: false,
51 }),
52 }
53 );
54
55 const data = await response.json();
56 return NextResponse.json(data, { status: response.ok ? 201 : 400 });
57}

Pro tip: GoToWebinar requires times in ISO 8601 format with timezone. Use new Date().toISOString() for UTC times. If organizers work in a specific timezone, convert appropriately before sending to the API.

Expected result: GET to /api/gotowebinar/webinars returns a list of upcoming webinars. POST to the same route with valid webinar data creates a new webinar and returns its webinarKey.

4

Build the Webinar Management Dashboard

With the API routes in place, build a management dashboard that gives your team full visibility into upcoming webinars and registrant data. A well-designed webinar dashboard shows three views: upcoming webinars (list of scheduled sessions with registration counts and quick actions), registrant management (expandable view of who has registered for each webinar with their name, email, and registration date), and past webinar analytics (attendance rate, poll results, and recording links). The dashboard is primarily read-only with create and cancel as the main write operations. Use React's useEffect to fetch data when the dashboard mounts. For the registrant view, only fetch registrant details on demand (when the user clicks 'View Registrants') to avoid hitting GoToWebinar's rate limit by loading all registrant data upfront. Show registrant counts on the webinar cards but load full lists lazily. GoToWebinar returns rich metadata about each webinar including description, estimated attendance, and whether it's a series — use this data to make the dashboard informative without additional API calls.

Bolt.new Prompt

Build a webinar management dashboard at /admin/webinars. At the top, show three metric cards: Total Upcoming Webinars, Total Registrants Across All Upcoming Webinars, and Most Recent Past Webinar Attendance Rate. Below that, show upcoming webinars as cards with title, date/time, registration count, and two buttons: 'View Registrants' (opens a slide-over showing the registrant list) and 'Copy Join Link'. Add a 'Create Webinar' button that opens a modal with a form for title, description, start date/time, and end date/time. Show a separate section for past webinars from the last 90 days with attendance rate percentages.

Paste this in Bolt.new chat

Pro tip: GoToWebinar's API paginates responses with a 'nextPage' cursor in the response body. Build pagination into your API routes from the start to avoid missing webinars or registrants once you have more than 100 records.

Expected result: The /admin/webinars dashboard shows real webinar data. Metric cards display accurate counts. Clicking 'View Registrants' loads the registrant list for that webinar. The create webinar form successfully creates a new session via the API.

Common use cases

Webinar Registration and Confirmation Flow

Build a custom registration page in your Bolt app that creates a GoToWebinar registrant via the REST API and sends a confirmation with the join link. This lets you collect additional custom fields beyond GoToWebinar's default form while still using GoToWebinar for the actual webinar infrastructure.

Bolt.new Prompt

Create a webinar registration page at /webinar/register that shows an upcoming webinar title, date, and description. The form collects first name, last name, email, and company name. On submit, call /api/gotowebinar/register which creates a registrant in GoToWebinar using the webinar key from GOTOWEBINAR_WEBINAR_KEY. Return the join link and confirmation number from GoToWebinar's API. Display a confirmation page with the join link and add to calendar buttons.

Copy this prompt to try it in Bolt.new

Webinar Management Dashboard

Build an internal admin dashboard showing all upcoming GoToWebinar sessions with registrant counts, attendance rates for past webinars, and quick links to create new webinars. The dashboard gives your marketing team visibility into webinar performance without logging into GoToWebinar's interface.

Bolt.new Prompt

Create an admin dashboard at /admin/webinars that fetches upcoming and past webinars from /api/gotowebinar/webinars. Show upcoming webinars as cards with title, date/time, registration count, and a 'View Registrants' button. Show past webinars in a table with attendance rate (attended / registered), average attendance duration, and a link to the recording. Add a 'Create Webinar' button that opens a form to create a new webinar through the GoToWebinar API.

Copy this prompt to try it in Bolt.new

Post-Webinar Recording Library

Create a gated recording library where registered attendees can access webinar recordings. After each webinar, fetch the recording asset URLs from GoToWebinar's API and store them in your database. Users log in with the email they registered with to access the recordings.

Bolt.new Prompt

Build a recordings library page at /resources/recordings that shows a list of past webinar recordings. Fetch recording assets from /api/gotowebinar/recordings which calls GoToWebinar's recordings endpoint. Display each recording with its title, date, duration, and a play button. Gate access behind an email verification step: user enters their registration email, check if that email is in the registrant list for that webinar via the GoToWebinar API, and only show the video player if they were registered.

Copy this prompt to try it in Bolt.new

Troubleshooting

OAuth callback never fires — browser stays on authorization page or shows an error

Cause: The redirect URI in your GoTo developer app settings doesn't match the URL your API route is deployed to. GoToWebinar enforces exact URI matching including trailing slashes and HTTPS vs HTTP.

Solution: Log into developer.goto.com, select your app, and verify the registered redirect URI matches your deployed API route exactly (e.g., https://your-app.netlify.app/api/gotowebinar/callback). The URI must use HTTPS. Remember that this OAuth flow cannot work from Bolt's WebContainer preview — deploy first, then test OAuth.

API returns 401 after the access token was working, suddenly stops authenticating

Cause: GoToWebinar access tokens expire after 3,600 seconds (1 hour). Requests made after expiry return 401 until the token is refreshed.

Solution: Implement automatic token refresh before making API calls. Check if the stored access token's expiry timestamp is within the next 5 minutes — if so, use the refresh token to get a new access token before making the API request. Update the stored token and expiry in your database after refreshing.

typescript
1// Token refresh check before API calls:
2async function getValidAccessToken() {
3 const stored = await getTokenFromDatabase(); // Your DB query
4 const fiveMinutesFromNow = Date.now() + 5 * 60 * 1000;
5 if (stored.expiresAt < fiveMinutesFromNow) {
6 const refreshed = await refreshAccessToken(stored.refreshToken);
7 await updateTokenInDatabase(refreshed); // Your DB update
8 return refreshed.accessToken;
9 }
10 return stored.accessToken;
11}

GoToWebinar API returns 429 Too Many Requests

Cause: GoToWebinar's rate limit is 100 requests per minute per access token. Dashboards that fetch webinars, registrant counts for each webinar, and recordings simultaneously can hit this limit quickly.

Solution: Add caching to your API routes using in-memory cache or a Redis store. Cache webinar lists for 5 minutes and registrant counts for 2 minutes — these change infrequently and don't need real-time accuracy. Fetch registrant details only on demand rather than loading all registrant lists upfront when the dashboard loads.

typescript
1// Simple in-memory cache for API responses:
2const cache = new Map<string, { data: unknown; expiry: number }>();
3
4function getCached(key: string) {
5 const entry = cache.get(key);
6 if (entry && entry.expiry > Date.now()) return entry.data;
7 return null;
8}
9
10function setCached(key: string, data: unknown, ttlMs: number) {
11 cache.set(key, { data, expiry: Date.now() + ttlMs });
12}

Best practices

  • Store GOTOWEBINAR_CLIENT_SECRET and OAuth tokens as server-side environment variables only — these control access to all your webinar data and registrant information
  • Implement automatic token refresh logic that checks token expiry before every API call — access tokens expire in 1 hour and must be refreshed without user interaction
  • Cache GoToWebinar API responses (webinar lists, registrant counts) for 2-5 minutes to stay within the 100 requests/minute rate limit on busier dashboards
  • Register multiple redirect URIs in your GoTo developer app upfront (Netlify URL, Bolt Cloud URL, any custom domain) to avoid reconfiguration when switching deployment targets
  • Complete the initial OAuth authorization from your deployed site — the WebContainer has no stable URL that GoToWebinar can redirect back to during development
  • Store the organizerKey returned with OAuth tokens in your database alongside the access and refresh tokens — it's required for all GoToWebinar API requests
  • Use GoToWebinar's webinarKey (not title or date) as the stable identifier for webinars in your database — keys never change while titles might be edited
  • Implement a loading state while fetching registrant data — large webinars can have hundreds of registrants and the API call may take a moment to complete

Alternatives

Frequently asked questions

Can I test GoToWebinar API calls in Bolt's WebContainer preview?

Partially. You can test the actual GoToWebinar REST API calls (creating webinars, fetching registrants) in the Bolt preview once you have an access token — these are outbound HTTPS calls that work in WebContainers. What doesn't work is the OAuth authorization flow: GoToWebinar needs to redirect back to your callback URL after authorization, and the WebContainer has no stable public URL for this. The practical approach is to hardcode a test access token from the GoToWebinar developer console while building and testing API routes in Bolt, then implement the full OAuth flow after deploying.

How long do GoToWebinar OAuth tokens last?

Access tokens expire after 3,600 seconds (1 hour). Refresh tokens do not expire unless unused for 90 days. Build automatic token refresh into your API routes: before making any GoToWebinar API call, check if the access token expires within the next 5 minutes — if so, use the refresh token to get a new access token from GoToWebinar's token endpoint.

Do I need a GoToWebinar Pro plan for API access?

Yes. GoToWebinar's REST API requires a paid GoTo plan (GoTo Pro or higher). The API is not available on the free plan or basic plans. GoToWebinar offers a 7-day free trial of paid plans where you can test API access before committing to a subscription. Check developer.goto.com for current API access requirements as plan names and inclusions change.

Can GoToWebinar handle 1,000+ attendees?

Yes. GoToWebinar Standard supports up to 500 attendees, Enterprise supports up to 3,000, and GoToWebinar Enterprise Plus goes up to 5,000. The API has the same capabilities regardless of your plan's attendee limit. Registrant counts and attendee lists scale accordingly — for large events, implement pagination in your registrant-fetching API routes.

How do I get registrant join links for a specific webinar?

When you create a registrant via the API (POST to /organizers/{organizerKey}/webinars/{webinarKey}/registrants), GoToWebinar returns a joinUrl in the response. This URL is unique per registrant and pre-authenticates them for the webinar. Store this URL in your database when creating registrants. For existing registrants, you can also fetch the join URL by retrieving registrant details from the API.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.