Skip to main content
RapidDev - Software Development Agency
replit-integrationsStandard API Integration

How to Integrate Replit with Google Classroom

To integrate Replit with Google Classroom, create a Google Cloud project, enable the Classroom API, and set up OAuth 2.0 credentials. Store your Client ID and Client Secret in Replit Secrets (lock icon 🔒 in sidebar), then use the Google Classroom REST API from your Node.js or Python backend to read courses, assignments, and submissions. A deployed Replit server is required to handle the OAuth redirect callback.

What you'll learn

  • How to create a Google Cloud project and enable the Google Classroom API
  • How to configure OAuth 2.0 credentials with the correct redirect URI for Replit
  • How to store Google OAuth credentials securely in Replit Secrets
  • How to implement the OAuth 2.0 authorization code flow in Node.js
  • How to list courses, assignments, and student submissions from the Classroom API
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate12 min read35 minutesOtherMarch 2026RapidDev Engineering Team
TL;DR

To integrate Replit with Google Classroom, create a Google Cloud project, enable the Classroom API, and set up OAuth 2.0 credentials. Store your Client ID and Client Secret in Replit Secrets (lock icon 🔒 in sidebar), then use the Google Classroom REST API from your Node.js or Python backend to read courses, assignments, and submissions. A deployed Replit server is required to handle the OAuth redirect callback.

Why Integrate Google Classroom with Replit?

Google Classroom is used by hundreds of millions of students and teachers worldwide. The Classroom API lets developers build tools that extend Classroom's functionality: automated assignment distribution, grade export scripts, custom dashboards that aggregate submission data across multiple classes, attendance tools, and parent notification systems. Replit is an ideal platform for hosting these tools because it provides a persistent web server with a public URL — something required for the OAuth 2.0 redirect flow that Classroom authentication depends on.

The Google Classroom API is a RESTful API with clear resource types: courses, coursework (assignments and materials), submissions, announcements, and roster (teachers and students). Once a user completes the OAuth flow, your Replit app can act on their behalf — reading their course list, fetching assignment details, checking which students submitted, and programmatically posting grades.

Common use cases for Replit and Google Classroom integration include: building a teacher dashboard that shows all pending grading across multiple courses in one view, creating automated quiz scoring tools that sync results back to Classroom gradebooks, generating submission reports for administrators, and building parent-facing portals that display assignment status for a student's courses.

Integration method

Standard API Integration

The Replit-Google Classroom integration uses Google's OAuth 2.0 Authorization Code flow. Your Replit app registers a redirect URI in the Google Cloud Console, sends users to Google's consent screen, receives an authorization code at the redirect endpoint, exchanges it for access and refresh tokens, and then calls the Classroom API on behalf of the authenticated user. Tokens are stored server-side in Replit; the frontend only sees session IDs.

Prerequisites

  • A Google account with access to Google Classroom courses (teacher or admin role for most write operations)
  • A Google Cloud project with billing enabled (free tier is sufficient for Classroom API)
  • Google Classroom API enabled in the Google Cloud Console
  • OAuth 2.0 credentials (Client ID and Client Secret) configured with your Replit app's URL as the redirect URI
  • A deployed Replit app with a public URL (required for OAuth redirect)

Step-by-step guide

1

Create a Google Cloud Project and Enable the Classroom API

Go to console.cloud.google.com and sign in. Click 'Select a project' at the top, then 'New Project'. Give it a name like 'Classroom Replit Integration' and click 'Create'. Once the project is created, navigate to 'APIs & Services' → 'Library'. Search for 'Google Classroom API'. Click on it and click 'Enable'. Next, configure the OAuth consent screen. Go to 'APIs & Services' → 'OAuth consent screen'. Choose 'External' (for Google accounts outside your organization) or 'Internal' (for Google Workspace accounts in your domain). Fill in the required fields: - App name: your application name - User support email: your email - Developer contact: your email Under 'Scopes', add the Classroom API scopes your app needs: - https://www.googleapis.com/auth/classroom.courses.readonly — read course list - https://www.googleapis.com/auth/classroom.coursework.me.readonly — read your assignments - https://www.googleapis.com/auth/classroom.rosters.readonly — read class roster - https://www.googleapis.com/auth/classroom.student-submissions.me.readonly — read submissions For write operations (posting grades, creating announcements), add the corresponding write scopes. Click 'Save and Continue' through all steps. Your app will be in 'Testing' mode, which allows up to 100 test users. Add your own Google account as a test user.

Pro tip: During development, add your own Google account as a test user in the OAuth consent screen. Without this, the OAuth flow will fail with 'Access blocked: This app's request is invalid'.

Expected result: The Google Classroom API is enabled in your project and the OAuth consent screen is configured with the required scopes.

2

Create OAuth 2.0 Credentials

In the Google Cloud Console, go to 'APIs & Services' → 'Credentials'. Click '+ Create Credentials' → 'OAuth client ID'. Choose 'Web application' as the application type. Give it a name (e.g., 'Replit Web Client'). Under 'Authorized redirect URIs', add your Replit app's callback URL. The format is: https://your-repl-name.your-username.repl.co/auth/google/callback To find your Replit app URL before deploying: open your Repl, click the web preview panel, and copy the URL shown. Your callback path must match exactly what you will configure in your Express/Flask server. Click 'Create'. Google shows your Client ID and Client Secret — copy both immediately. The Client Secret is shown once in this screen; you can retrieve it later from the credentials list but it is easier to copy now. Store these in Replit Secrets in the next step. Do not paste them into your code files.

Pro tip: If your Replit app URL changes (e.g., after forking the Repl), you must update the authorized redirect URI in Google Cloud Console. OAuth will fail with 'redirect_uri_mismatch' if the URLs do not match exactly.

Expected result: You have a Google OAuth Client ID (ends in .apps.googleusercontent.com) and Client Secret ready to store in Replit Secrets.

3

Store Credentials in Replit Secrets

Click the lock icon (🔒) in the Replit sidebar. Add the following secrets: GOOGLE_CLIENT_ID — your OAuth Client ID GOOGLE_CLIENT_SECRET — your OAuth Client Secret GOOGLE_REDIRECT_URI — your full callback URL (e.g., https://your-repl.your-user.repl.co/auth/google/callback) SESSION_SECRET — a random string used to sign session cookies (generate with: require('crypto').randomBytes(32).toString('hex')) These values must never appear in your code. The CLIENT_SECRET in particular authenticates your application to Google — if exposed, anyone could impersonate your app in the OAuth flow.

Pro tip: Generate a secure SESSION_SECRET by running this in the Replit Shell: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" and storing the output as the secret.

Expected result: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REDIRECT_URI, and SESSION_SECRET all appear in the Replit Secrets panel.

4

Implement OAuth 2.0 Flow and Call the Classroom API (Node.js)

Install the required packages: npm install express express-session googleapis The googleapis package provides the official Google API client for Node.js, which handles OAuth token exchange and API calls. The flow is: 1. User visits /auth/login → redirected to Google's consent screen 2. User grants permission → Google redirects to /auth/google/callback with an authorization code 3. Server exchanges the code for tokens → stores tokens in session 4. Server uses tokens to call Classroom API Tokens expire after 1 hour but include a refresh token for automatic renewal.

server.js
1// server.js — Google Classroom OAuth + API server
2const express = require('express');
3const session = require('express-session');
4const { google } = require('googleapis');
5
6const app = express();
7app.use(express.json());
8app.use(session({
9 secret: process.env.SESSION_SECRET,
10 resave: false,
11 saveUninitialized: false
12}));
13
14function getOAuthClient() {
15 return new google.auth.OAuth2(
16 process.env.GOOGLE_CLIENT_ID,
17 process.env.GOOGLE_CLIENT_SECRET,
18 process.env.GOOGLE_REDIRECT_URI
19 );
20}
21
22const SCOPES = [
23 'https://www.googleapis.com/auth/classroom.courses.readonly',
24 'https://www.googleapis.com/auth/classroom.coursework.me.readonly',
25 'https://www.googleapis.com/auth/classroom.rosters.readonly'
26];
27
28// Step 1: redirect to Google consent screen
29app.get('/auth/login', (req, res) => {
30 const oauth2Client = getOAuthClient();
31 const authUrl = oauth2Client.generateAuthUrl({
32 access_type: 'offline', // Get refresh token
33 scope: SCOPES,
34 prompt: 'consent'
35 });
36 res.redirect(authUrl);
37});
38
39// Step 2: handle the callback from Google
40app.get('/auth/google/callback', async (req, res) => {
41 const { code } = req.query;
42 if (!code) return res.status(400).send('Missing authorization code');
43
44 try {
45 const oauth2Client = getOAuthClient();
46 const { tokens } = await oauth2Client.getToken(code);
47 req.session.tokens = tokens;
48 res.redirect('/courses'); // Redirect to app after login
49 } catch (err) {
50 console.error('OAuth callback error:', err.message);
51 res.status(500).send('Authentication failed');
52 }
53});
54
55// Middleware: check authentication
56function requireAuth(req, res, next) {
57 if (!req.session.tokens) return res.redirect('/auth/login');
58 next();
59}
60
61// Step 3: use the token to call Google Classroom API
62app.get('/courses', requireAuth, async (req, res) => {
63 try {
64 const oauth2Client = getOAuthClient();
65 oauth2Client.setCredentials(req.session.tokens);
66
67 const classroom = google.classroom({ version: 'v1', auth: oauth2Client });
68 const response = await classroom.courses.list({
69 pageSize: 20,
70 courseStates: ['ACTIVE']
71 });
72
73 const courses = (response.data.courses || []).map(c => ({
74 id: c.id,
75 name: c.name,
76 section: c.section,
77 enrollmentCode: c.enrollmentCode,
78 courseState: c.courseState
79 }));
80
81 res.json({ courses });
82 } catch (err) {
83 console.error('Classroom API error:', err.message);
84 res.status(500).json({ error: err.message });
85 }
86});
87
88// Fetch assignments for a course
89app.get('/courses/:courseId/assignments', requireAuth, async (req, res) => {
90 const { courseId } = req.params;
91 try {
92 const oauth2Client = getOAuthClient();
93 oauth2Client.setCredentials(req.session.tokens);
94
95 const classroom = google.classroom({ version: 'v1', auth: oauth2Client });
96 const response = await classroom.courses.courseWork.list({
97 courseId,
98 pageSize: 50,
99 orderBy: 'dueDate asc'
100 });
101
102 res.json({ assignments: response.data.courseWork || [] });
103 } catch (err) {
104 res.status(500).json({ error: err.message });
105 }
106});
107
108const PORT = process.env.PORT || 3000;
109app.listen(PORT, '0.0.0.0', () => {
110 console.log(`Google Classroom server running on port ${PORT}`);
111});

Pro tip: Set access_type: 'offline' and prompt: 'consent' in the auth URL generation to always receive a refresh token. Without a refresh token, your server will fail after the access token expires (1 hour).

Expected result: Visiting /auth/login redirects to Google's consent screen. After authorization, visiting /courses returns a list of active Google Classroom courses as JSON.

5

Python Implementation with Flask

For Python Replit projects, the google-auth-oauthlib and google-api-python-client libraries provide the same OAuth and Classroom API functionality. Install: pip install flask google-auth-oauthlib google-api-python-client The Python implementation follows the same OAuth flow as the Node.js version but uses Flask's session for token storage.

app.py
1# app.py Google Classroom OAuth server in Python
2import os
3import json
4from flask import Flask, session, redirect, url_for, request, jsonify
5from google_auth_oauthlib.flow import Flow
6from googleapiclient.discovery import build
7from google.oauth2.credentials import Credentials
8
9app = Flask(__name__)
10app.secret_key = os.environ['SESSION_SECRET']
11os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '0' # Enforce HTTPS in production
12
13SCOPES = [
14 'https://www.googleapis.com/auth/classroom.courses.readonly',
15 'https://www.googleapis.com/auth/classroom.coursework.me.readonly'
16]
17
18def make_flow():
19 return Flow.from_client_config(
20 {
21 'web': {
22 'client_id': os.environ['GOOGLE_CLIENT_ID'],
23 'client_secret': os.environ['GOOGLE_CLIENT_SECRET'],
24 'redirect_uris': [os.environ['GOOGLE_REDIRECT_URI']],
25 'auth_uri': 'https://accounts.google.com/o/oauth2/auth',
26 'token_uri': 'https://oauth2.googleapis.com/token'
27 }
28 },
29 scopes=SCOPES,
30 redirect_uri=os.environ['GOOGLE_REDIRECT_URI']
31 )
32
33@app.route('/auth/login')
34def login():
35 flow = make_flow()
36 auth_url, state = flow.authorization_url(access_type='offline', prompt='consent')
37 session['oauth_state'] = state
38 return redirect(auth_url)
39
40@app.route('/auth/google/callback')
41def callback():
42 flow = make_flow()
43 flow.fetch_token(authorization_response=request.url)
44 creds = flow.credentials
45 session['tokens'] = {
46 'token': creds.token,
47 'refresh_token': creds.refresh_token,
48 'token_uri': creds.token_uri,
49 'client_id': creds.client_id,
50 'client_secret': creds.client_secret,
51 'scopes': list(creds.scopes)
52 }
53 return redirect('/courses')
54
55@app.route('/courses')
56def courses():
57 if 'tokens' not in session:
58 return redirect('/auth/login')
59 creds = Credentials(**session['tokens'])
60 service = build('classroom', 'v1', credentials=creds)
61 result = service.courses().list(pageSize=20, courseStates=['ACTIVE']).execute()
62 return jsonify({'courses': result.get('courses', [])})
63
64if __name__ == '__main__':
65 app.run(host='0.0.0.0', port=3000)

Pro tip: Set OAUTHLIB_INSECURE_TRANSPORT='0' in production. During local dev on Replit you may set it to '1' temporarily if testing over HTTP, but the deployed Replit URL uses HTTPS so this should not be needed.

Expected result: Visiting /auth/login in the browser triggers Google OAuth. After consent, /courses returns the authenticated user's active Google Classroom courses.

Common use cases

Multi-Course Assignment Dashboard

Build a teacher tool that lists all courses, then shows all pending assignments across every course in a single view, sorted by due date. Teachers currently have to click into each course separately in Classroom — this dashboard saves significant time.

Replit Prompt

Build a Node.js Express server with Google OAuth 2.0 login. After login, fetch all the teacher's courses from the Classroom API, then for each course fetch all coursework with a due date. Display them sorted by due date ascending. Store GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in environment variables.

Copy this prompt to try it in Replit

Assignment Submission Status Exporter

Create a tool that takes a course ID and assignment ID, fetches all student submissions, and exports a CSV with each student's name, submission status (turned in / not turned in), and grade if assigned. Export it to a file or return it via HTTP.

Replit Prompt

Write a Python Flask server with Google OAuth that provides a GET /export?courseId=X&assignmentId=Y endpoint. After authentication, fetch all student submissions for that assignment and return a CSV file with student name, email, submission status, and grade. Store OAuth credentials in environment variables.

Copy this prompt to try it in Replit

Automated Course Announcement Sender

Build an internal tool that sends the same announcement to multiple Google Classroom courses at once. Useful for school administrators who need to broadcast a message to all classes, or teachers who manage several sections of the same course.

Replit Prompt

Create a Node.js server with an endpoint POST /announce that accepts a message and list of course IDs, authenticates via Google OAuth, and posts the message as an announcement to each specified course using the Classroom API. Store credentials in environment variables.

Copy this prompt to try it in Replit

Troubleshooting

redirect_uri_mismatch — OAuth callback returns this error from Google

Cause: The redirect URI your server sends to Google does not exactly match the URI registered in Google Cloud Console. Even a trailing slash difference or http vs https mismatch causes this error.

Solution: In the Google Cloud Console, go to Credentials → your OAuth client → Authorized redirect URIs. Ensure the URI listed exactly matches process.env.GOOGLE_REDIRECT_URI in your Replit Secrets, including protocol, hostname, path, and no trailing slash.

typescript
1// Log the exact redirect URI your server is using
2console.log('Using redirect URI:', process.env.GOOGLE_REDIRECT_URI);

Access blocked: This app's request is invalid — OAuth consent screen error

Cause: Your Google account is not added as a test user in the OAuth consent screen configuration, and the app is still in 'Testing' mode.

Solution: Go to Google Cloud Console → APIs & Services → OAuth consent screen → Test users. Add your Google account email address as a test user. Only test users can authorize apps in Testing mode.

insufficient_scope — Classroom API returns 403 for specific operations

Cause: The OAuth token was granted without including the scope needed for the operation you are trying to perform.

Solution: Add the required scope to the SCOPES array in your authorization URL generation, then re-authorize the user (they will see a new consent screen). Write operations (creating announcements, posting grades) require separate write scopes.

typescript
1const SCOPES = [
2 'https://www.googleapis.com/auth/classroom.courses.readonly',
3 'https://www.googleapis.com/auth/classroom.announcements', // Add write scope
4];

Token expired — API calls fail after 1 hour with 401 Unauthorized

Cause: Google OAuth access tokens expire after 3600 seconds. Without automatic refresh, API calls fail after expiry.

Solution: The googleapis client for Node.js handles token refresh automatically when you provide a refresh token. Ensure you set access_type: 'offline' when generating the auth URL. For Python, use google.auth.transport.requests.Request() to refresh expired credentials.

typescript
1// Node.js: googleapis refreshes automatically if refresh_token is in session
2// Ensure you stored the full tokens object including refresh_token
3console.log('Has refresh token:', !!req.session.tokens?.refresh_token);

Best practices

  • Store GOOGLE_CLIENT_SECRET in Replit Secrets and never log it or include it in HTTP responses or error messages
  • Request only the OAuth scopes your application actually uses — requesting broader scopes than necessary reduces user trust and may cause the OAuth consent to be rejected
  • Store OAuth tokens server-side in the session, never in the browser's localStorage or as cookies accessible to JavaScript
  • Set access_type: 'offline' in your auth URL to receive a refresh token — without it, users must re-authorize every hour
  • Add your own Google account as a test user while the OAuth app is in Testing mode to avoid 'access blocked' errors
  • Deploy as an Autoscale Replit deployment with a stable URL, since the redirect URI must be registered in Google Cloud Console and must not change
  • Handle token refresh errors gracefully — when the refresh token is revoked (user revoked app access), redirect to re-authorization rather than showing an error
  • Use pagination (nextPageToken) when fetching large course or submission lists to avoid incomplete data

Alternatives

Frequently asked questions

How do I connect Replit to Google Classroom?

Create a Google Cloud project, enable the Classroom API, and generate OAuth 2.0 credentials with your Replit app's URL as the redirect URI. Store the Client ID and Client Secret in Replit Secrets, then implement the OAuth 2.0 Authorization Code flow in your Node.js or Python server. After a user authorizes your app, you can call the Classroom API on their behalf.

Does Replit work with the Google Classroom API?

Yes. The Google Classroom API accepts standard HTTPS requests and works with Replit's Node.js and Python environments. Replit is well-suited for Classroom integrations because it provides a persistent public URL needed for the OAuth redirect callback.

Can I use the Google Classroom API for free?

Yes. The Google Classroom API is free to use within Google Cloud's quotas (500 queries per 100 seconds by default). Creating a Google Cloud project and enabling the API costs nothing. The API is available to any Google Workspace or personal Google account with Classroom access.

Do I need a teacher account to use the Classroom API?

It depends on what you want to do. Reading course data, assignments, and submissions requires the account to be enrolled in or teaching those courses. Creating assignments and posting grades requires teacher or co-teacher role. Student accounts can read their own submissions and assignment details.

Why does my OAuth redirect fail in the Replit preview?

The Replit preview window uses an embedded iframe URL that differs from the public Replit URL. Google OAuth requires exact redirect URI matching — it will fail in the in-app preview. Test the OAuth flow by opening your Replit app URL in a full browser tab, not the built-in preview panel.

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.