To integrate Schoology with Bolt.new, create Next.js API routes that use OAuth 1.0a authentication with your Schoology consumer key and secret. The Schoology REST API provides access to courses, sections, assignments, and grades. API access requires school administrator approval — you cannot use the Schoology API without a valid API key from your institution's Schoology account.
Building a K-12 Learning Dashboard with the Schoology API
Schoology is one of the most widely used learning management systems in K-12 education, deployed across thousands of US school districts and internationally. Part of the PowerSchool family since 2019, Schoology provides a REST API that lets authorized developers read and write course data, enrollment information, assignments, grades, and more. If you are building a parent portal, student progress tracker, tutoring platform, or any tool that needs to pull data from a school's Schoology account, this is the integration to use.
The most important fact about the Schoology API: access is institution-controlled. Unlike consumer APIs where you sign up and get a key, Schoology API credentials are issued by school administrators through the Schoology platform. You need a school's Schoology administrator to create an API application for you and provide a consumer key and consumer secret. Individual teachers or students cannot generate API keys — it requires district-level or school-level admin access. If you are building for your own school, request this through your IT department. If you are building a product for schools, you will need each school to authorize your app.
The Schoology API uses OAuth 1.0a for authentication, an older but robust standard that signs each request cryptographically. Unlike OAuth 2.0 (which uses bearer tokens), OAuth 1.0a creates a signature for every API call using a combination of the request URL, HTTP method, timestamp, nonce, and your consumer secret. This signature must be recomputed for each request. There are npm packages that handle this — the oauth-signature package or the oauth package both work well and are pure JavaScript compatible with Bolt's WebContainer.
Integration method
Schoology uses OAuth 1.0a for API authentication, requiring a consumer key and secret from your school's Schoology admin. All Schoology REST API calls are outbound HTTPS requests handled through Next.js API routes that generate OAuth 1.0a signatures server-side. API access must be requested from your school's Schoology administrator and approved through the Schoology developer program. All data fetching works in Bolt's WebContainer preview once credentials are obtained.
Prerequisites
- A Schoology account at a school or institution that uses Schoology (PowerSchool LMS)
- Schoology API credentials (consumer key and consumer secret) approved by your school's Schoology administrator
- Understanding of OAuth 1.0a authentication (different from the more common OAuth 2.0)
- A Bolt.new project using Next.js for server-side API routes
- For multi-user apps: your school admin must configure your app with the appropriate user-level or system-level API access
Step-by-step guide
Request Schoology API Credentials
Request Schoology API Credentials
Schoology API credentials are not self-service — they must be issued by a Schoology administrator at your school or district. There are two types of API access in Schoology: System credentials (school-admin level): A single consumer key and secret that can access data for all users in the school. Created by a Schoology admin going to System Settings → API → Register New App. This is what you need for building dashboards that aggregate data across students or courses. The admin gives your app a name, description, and callback URL, then provides you with the consumer key and secret. User credentials (individual level): Each user can generate their own OAuth credentials in My Resources → Apps & External Tools. These only provide access to that user's data. Useful for personal tools but not for multi-student or teacher dashboards. To request system credentials: contact your school's Schoology administrator (usually the district IT department or LMS coordinator). Explain what data you need to access (courses, assignments, grades) and what you're building. They will create an API application in Schoology's admin settings and share the consumer key and consumer secret with you. For developers building commercial products for schools: the Schoology Partners program allows you to list your app in Schoology's App Center, which simplifies the authorization process for each school that wants to connect. Contact developers@schoology.com for partnership information.
1# Schoology API base URL:2# https://api.schoology.com/v1/34# Key endpoints:5# GET /users/{userId}/sections — courses/sections a user is enrolled in6# GET /sections/{sectionId} — single course section details7# GET /sections/{sectionId}/assignments — assignments in a section8# GET /sections/{sectionId}/grades — grade data for a section9# GET /sections/{sectionId}/enrollments — enrolled students10# GET /users/me — current user info1112# Authentication: OAuth 1.0a13# Header format: OAuth realm="Schoology API", oauth_consumer_key="...", oauth_signature="...", ...Pro tip: Ask your Schoology admin for 'system-level' API credentials, not user-level. System credentials are required to build dashboards that show data for multiple users. User credentials only work for the individual user who created them.
Expected result: You have a Schoology consumer key and consumer secret from your school's administrator, ready to configure in your .env file.
Implement OAuth 1.0a Request Signing
Implement OAuth 1.0a Request Signing
OAuth 1.0a is more complex to implement than OAuth 2.0 because every API request must be individually signed. The signature is a HMAC-SHA1 hash of the request parameters combined with your consumer secret. This prevents request tampering and authenticates each API call. The signing process: (1) collect all OAuth parameters (consumer_key, nonce, signature_method, timestamp, version) plus any query parameters; (2) percent-encode and sort them alphabetically; (3) build the signature base string: HTTP_METHOD + '&' + encoded_URL + '&' + encoded_params; (4) sign the base string using HMAC-SHA1 with the consumer_secret as the key; (5) add the signature to the Authorization header. The oauth package (npm) and oauth-1.0a package both handle this for you. The oauth-1.0a package is lighter and easier to use for REST API calls — it's pure JavaScript, works in Bolt's WebContainer, and handles all the encoding and signing. Install it with the crypto module from Node.js for the HMAC implementation. All signing happens server-side in your API routes, keeping the consumer secret out of client code.
Set up Schoology API authentication in my Next.js project. Install the oauth-1.0a package. Create a lib/schoology.ts utility that: (1) exports a getOAuthHeader(method, url, params?) function that generates an OAuth 1.0a Authorization header using HMAC-SHA1 signing with SCHOOLOGY_CONSUMER_KEY and SCHOOLOGY_CONSUMER_SECRET from environment variables. (2) exports a schoologyFetch<T>(path, method, body?) function that calls the Schoology API with the OAuth header. Base URL: https://api.schoology.com/v1. Create a .env with SCHOOLOGY_CONSUMER_KEY and SCHOOLOGY_CONSUMER_SECRET placeholders.
Paste this in Bolt.new chat
1// lib/schoology.ts2import OAuth from 'oauth-1.0a';3import crypto from 'crypto';45const BASE_URL = 'https://api.schoology.com/v1';67const oauth = new OAuth({8 consumer: {9 key: process.env.SCHOOLOGY_CONSUMER_KEY!,10 secret: process.env.SCHOOLOGY_CONSUMER_SECRET!,11 },12 signature_method: 'HMAC-SHA1',13 hash_function(base_string, key) {14 return crypto.createHmac('sha1', key).update(base_string).digest('base64');15 },16});1718export async function schoologyFetch<T>(19 path: string,20 method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET',21 body?: object22): Promise<T> {23 const url = `${BASE_URL}${path}`;24 const requestData = { url, method };2526 const authHeader = oauth.toHeader(oauth.authorize(requestData));2728 const response = await fetch(url, {29 method,30 headers: {31 ...authHeader,32 'Content-Type': 'application/json',33 },34 body: body ? JSON.stringify(body) : undefined,35 });3637 if (!response.ok) {38 const text = await response.text();39 throw new Error(`Schoology API ${response.status}: ${text}`);40 }4142 return response.json() as Promise<T>;43}Pro tip: OAuth 1.0a uses a timestamp in the signature. If your server clock is more than a few minutes off from UTC, Schoology will reject requests with 'Invalid timestamp' errors. Ensure your server time is synchronized via NTP.
Expected result: lib/schoology.ts exports an authenticated Schoology API client. The OAuth 1.0a signing is handled automatically for every request.
Build Course and Assignment API Routes
Build Course and Assignment API Routes
With the authenticated Schoology client, create the API routes for fetching educational data. The most commonly needed endpoints are: the current user's enrolled sections (courses), assignments within a section, and grade data. Schoolgy's API returns paginated results with a total, next, and links structure. Most list endpoints default to 20 items per page. Use the start and limit query parameters to control pagination — start is the offset (0-indexed) and limit is how many records to return (max 200 for most endpoints). For building dashboards, fetch all records by looping until you get an empty next link. The /users/me endpoint returns the authenticated user's details including their uid. Use this uid to fetch their enrollments: /users/{uid}/sections returns all course sections the user is enrolled in. Each section has a section_id, course_title, section_title, access, and grading_period. Then use section_ids to fetch assignments and grades from /sections/{section_id}/assignments and /sections/{section_id}/grades.
Create Schoology API routes in my Next.js project. First, /api/schoology/me (GET): call schoologyFetch('/users/me') to get the current user and return their uid, name, and email. Second, /api/schoology/sections (GET): call /users/{uid}/sections to get all enrolled course sections. Third, /api/schoology/sections/[sectionId]/assignments (GET): fetch assignments for a section, returning id, title, due_date, max_points, type. Fourth, /api/schoology/sections/[sectionId]/grades (GET): fetch grade data for the section. Use TypeScript interfaces for SchoologySection, SchoologyAssignment, SchoologyGrade.
Paste this in Bolt.new chat
1// app/api/schoology/sections/route.ts2import { NextResponse } from 'next/server';3import { schoologyFetch } from '@/lib/schoology';45interface SchoologyUser { uid: string; name_display: string; }6interface SchoologySection {7 id: string;8 course_title: string;9 section_title: string;10 section_code: string;11 grading_period: string;12 access: string;13}1415export async function GET() {16 try {17 const user = await schoologyFetch<SchoologyUser>('/users/me');18 const data = await schoologyFetch<{ section: SchoologySection[] }>(19 `/users/${user.uid}/sections?limit=100`20 );21 return NextResponse.json(data.section || []);22 } catch (error: unknown) {23 const e = error as { message: string };24 return NextResponse.json({ error: e.message }, { status: 500 });25 }26}Pro tip: Schoology section IDs are different from course IDs. A course may have multiple sections (different class periods). Most grade and assignment data is accessed via section ID, not course ID. Always fetch sections (not courses) as your primary data model.
Expected result: GET /api/schoology/sections returns the user's enrolled course sections. GET /api/schoology/sections/{id}/assignments returns assignments for that section. Both work in the Bolt preview with valid credentials.
Build the Student/Parent Dashboard UI
Build the Student/Parent Dashboard UI
The Schoology dashboard brings together course grades, upcoming assignments, and recent activity into a unified view. Design for two primary audiences: students checking their own progress and parents monitoring their child's performance. For the course overview, display each section as a card with the course name, current grade (letter grade and percentage), and a grade trend indicator. Schoology's grade data comes back as a flat list of grade items — you need to calculate the overall course grade by aggregating the graded items based on their grading category weights if applicable. For the assignments view, sort by due date and group by urgency: overdue (past due date, not submitted), due soon (next 3 days), and upcoming (rest of the week and beyond). Use red/yellow/green color coding. Assignments from Schoology include: title, due date, maximum points, assignment type, and section ID. Link each assignment card back to the Schoology web URL (constructable from section_id and assignment_id) so students can click through to submit work. Authentication context: for parent dashboards, the API credentials are the student's, and the parent sees the student's data. If building for parents, you need either the student to authorize the app (user-level credentials) or a system-level credential that allows the app to query on behalf of specific users.
Build a Schoology student dashboard at /dashboard/school. Fetch sections from /api/schoology/sections on load. Show course cards with name, section title, and grade (formatted as letter grade). Add an 'Upcoming Assignments' panel that fetches assignments for all sections due in the next 14 days. Sort assignments by due date with urgency badges: overdue (red), due today (orange), due this week (yellow), later (green). Show assignment title, course name, due date, and max points. Add a loading state and error handling for missing credentials.
Paste this in Bolt.new chat
Pro tip: Schoology returns dates in Unix timestamp format (seconds since epoch), not ISO strings. Convert them with new Date(timestamp * 1000).toLocaleDateString() in your frontend code before displaying.
Expected result: The dashboard shows course sections with grades and a sorted assignment list with urgency color coding. Data loads from the Schoology API through your Next.js API routes.
Common use cases
Student Progress Dashboard for Parents
Build a parent-facing dashboard that shows their child's current grades, upcoming assignments, and recent activity across all courses. Parents can see at a glance which assignments are due, which courses need attention, and their child's grade trend over time. Pulls data from Schoology's enrollments, courses, and grades APIs.
Build a student progress dashboard. Create API routes that: (1) GET /api/schoology/courses returns all courses the student is enrolled in with current grade, (2) GET /api/schoology/assignments returns upcoming assignments due in the next 14 days across all courses, sorted by due date. Display a dashboard with course grade cards (showing letter grade and percentage), and an upcoming assignments timeline sorted by due date. Use SCHOOLOGY_CONSUMER_KEY and SCHOOLOGY_CONSUMER_SECRET for OAuth 1.0a signing.
Copy this prompt to try it in Bolt.new
Assignment Tracker with Reminder Notifications
Create an assignment tracking app that polls Schoology for new assignments and can send SMS or email reminders before due dates. Pull assignments from Schoology, store them in Supabase, and send reminder notifications via Plivo or SendGrid when due dates approach. Supplements Schoology's built-in notifications for students who miss them.
Build an assignment reminder system. Create a cron job API route at /api/schoology/sync-assignments that fetches all courses for enrolled students, gets assignments due in the next 7 days from each course's /section/{id}/assignments endpoint, and stores them in a Supabase assignments table. A separate /api/notifications/send-reminders route checks for assignments due in 24 hours and sends SMS reminders via Plivo. Show a calendar view of upcoming assignments sorted by due date. Use SCHOOLOGY_CONSUMER_KEY and SCHOOLOGY_CONSUMER_SECRET.
Copy this prompt to try it in Bolt.new
Teacher Grade Entry Dashboard
Build a streamlined grade entry interface for teachers who find Schoology's built-in grade entry slow. The dashboard loads a course's student roster and assignment list, shows current grades in an editable spreadsheet view, and syncs changes back to Schoology via the API. Faster for bulk grade entry than the standard Schoology interface.
Create a teacher grade entry tool. Build an API route GET /api/schoology/sections/{sectionId}/gradebook that fetches all students enrolled in a section and their grades for all graded items. Display an editable spreadsheet/table where teachers can update grades inline. Create a PUT route /api/schoology/grades that submits updated grades back to Schoology's /sections/{id}/grades endpoint. Show a save status indicator and handle partial saves gracefully. Use SCHOOLOGY_CONSUMER_KEY and SCHOOLOGY_CONSUMER_SECRET.
Copy this prompt to try it in Bolt.new
Troubleshooting
API returns 401 Unauthorized or 'Invalid Consumer Key'
Cause: SCHOOLOGY_CONSUMER_KEY or SCHOOLOGY_CONSUMER_SECRET is incorrect, or the API application has been disabled by the school administrator.
Solution: Verify the consumer key and secret with your school's Schoology administrator. Consumer keys are case-sensitive. Confirm the API application is still active in the school's Schoology admin settings (System Settings → API). If the school has refreshed credentials or disabled the app, request new credentials.
OAuth signature verification failed or 'Timestamp out of range'
Cause: The OAuth timestamp in the signature is too far from Schoology's server time. OAuth 1.0a requires the timestamp to be within a small window (typically 5 minutes) of the server's current time.
Solution: Ensure your development machine and server clock are synchronized with NTP. In the Bolt WebContainer, the system time should be accurate since it runs in the browser. If you're seeing timestamp errors consistently, check if your system timezone is misconfigured — use Date.now() for timestamps, not manual timezone calculations.
1// The oauth-1.0a package uses Date.now() / 1000 by default.2// If you need to debug the timestamp:3console.log('Current UTC timestamp:', Math.floor(Date.now() / 1000));API returns 200 but sections or assignments array is empty
Cause: The user authenticated has no enrollments (sections), or the API application only has access to certain sections based on how the admin configured it, or the current grading period has ended.
Solution: Verify the API application has 'Read' access to the 'Courses' resource in Schoology's admin API configuration. Check that the user has active section enrollments in the current grading period. Add ?grading_period_id=all or check Schoology's documentation for the correct parameter to include historical enrollments.
1// Include all grading periods to see past courses:2const data = await schoologyFetch(`/users/${uid}/sections?include_past=1&limit=100`);Schoology API access denied — cannot get credentials from school
Cause: School IT departments may be reluctant to issue API credentials to external developers due to FERPA (Family Educational Rights and Privacy Act) concerns about student data access.
Solution: Prepare a data access request document explaining exactly what data you access, how it's stored, your security practices, and FERPA compliance. Schools are more likely to approve access with documented data handling procedures. Consider building on behalf of an internal school IT team rather than as an external third party.
Best practices
- Store SCHOOLOGY_CONSUMER_KEY and SCHOOLOGY_CONSUMER_SECRET as server-side environment variables only — these credentials control access to student data protected by FERPA
- Never expose student grades, assignment data, or personally identifiable information to non-authorized users — implement proper authentication and authorization in your app before connecting to Schoology
- Cache Schoology API responses for 15-30 minutes since educational data changes infrequently — new assignments don't appear every second, and caching reduces API load and improves response times
- Handle the Schoology API's paginated responses correctly by checking for next links and fetching additional pages when total exceeds the limit parameter
- Convert Schoology Unix timestamps to local dates using the user's timezone, not the server timezone — due dates displayed in the wrong timezone cause missed assignment submissions
- Document all student data you collect for FERPA compliance — keep a clear data inventory of what Schoology data you store and for how long
Alternatives
Canvas has a more developer-friendly REST API with OAuth 2.0 (easier than Schoology's OAuth 1.0a) and is widely used in higher education alongside K-12 settings.
Google Classroom has a well-documented REST API with standard OAuth 2.0, is free for Google Workspace for Education schools, and is widely used in schools that have adopted Google's ecosystem.
Moodle is open-source and self-hosted with a REST API that schools control entirely — useful when you need custom integration with a school running their own LMS.
Edmodo provides a simpler LMS focused on K-12 classrooms with an API similar to Schoology's, suitable for lower-tech-requirement school integrations.
Frequently asked questions
Can I use the Schoology API without school admin approval?
No. Schoology API credentials require administrator approval. Individual teachers can generate user-level API credentials for their own data only, but system-level credentials that let your app access data for multiple users require a school or district administrator to create an API application in Schoology's system settings. This is by design — student data is protected by FERPA and school districts need control over who accesses it.
Why does Schoology use OAuth 1.0a instead of OAuth 2.0?
Schoology's API was built when OAuth 1.0a was the standard, and they have maintained backward compatibility since then. OAuth 1.0a is more complex to implement (every request requires a cryptographic signature) but does not require token refresh flows. For Bolt.new integration, the oauth-1.0a npm package handles all the signing complexity, so the practical implementation effort is similar to OAuth 2.0.
Does the Schoology API work in Bolt's WebContainer?
Yes. Schoology's API uses standard HTTPS REST calls. The oauth-1.0a npm package is pure JavaScript compatible with Bolt's WebContainer. All the OAuth 1.0a signing happens server-side in Next.js API routes using Node.js's built-in crypto module. Outbound API calls to Schoology's endpoints work in the Bolt preview. There are no webhook endpoints in Schoology's API (it's a pull-only API), so no deployment is required for basic data access.
Is Schoology the same as PowerSchool?
Schoology is a separate product from PowerSchool SIS (Student Information System), though both are now owned by PowerSchool Group. Schoology is the learning management system (courses, assignments, grades in context of teaching). PowerSchool SIS manages official student records, enrollment, and grade transcripts. They have separate APIs and different data domains. Your school may use one or both.
Can I build a parent app that shows multiple children's Schoology data?
This requires system-level API credentials configured to allow proxy access on behalf of specific users. With system-level credentials, your app can make API calls on behalf of any user in the school. The parent authenticates with your app, you look up their children's user IDs in Schoology, and use the system credentials to fetch data for each child. This requires explicit administrator configuration of proxy access permissions in Schoology.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation