Connect Retool to Schoology by creating a REST API Resource configured with Schoology's API base URL and OAuth 1.0a authentication using your consumer key and secret. Use Schoology's REST API to build K-12 administration dashboards that manage courses, track student grades, monitor assignment completion, and view cross-classroom performance — giving school administrators and teachers direct access to LMS data in a configurable internal tool.
| Fact | Value |
|---|---|
| Tool | Schoology |
| Category | Other |
| Method | REST API Resource |
| Difficulty | Intermediate |
| Time required | 30 minutes |
| Last updated | April 2026 |
Build a Schoology K-12 Administration Dashboard in Retool
Schoology is widely adopted in K-12 districts as a learning management system, but administrators and curriculum coordinators often find that Schoology's built-in reporting is limited when it comes to cross-classroom analysis. Viewing grade distributions across all sections of the same course, identifying students at risk across multiple classes, or generating district-level completion reports requires exporting data and working with spreadsheets — a time-consuming process.
Retool solves this by giving administrators direct, queryable access to Schoology's REST API. You can build dashboards that show course enrollment counts, grade distributions per assignment, student performance trends over a semester, and attendance patterns — all in a single configurable panel. Teachers can look up student progress across all their sections without navigating Schoology's per-section views, and curriculum directors can compare course performance across multiple schools in a district.
Schoolygy's API uses OAuth 1.0a authentication with a consumer key and secret obtained from your Schoology system administrator or district API settings. While OAuth 1.0a requires careful header construction, Retool's REST API Resource handles the authentication layer so queries are straightforward. The most valuable Schoology data — courses, enrollments, grades, assignments, and users — is all accessible through the v1 REST API.
Integration method
Schoology connects to Retool through a REST API Resource using OAuth 1.0a authentication with your Schoology API consumer key and secret. Retool's server-side proxy handles all requests, keeping credentials secure. You configure the base URL and authentication headers once at the resource level, then build individual queries to retrieve courses, users, grades, and assignment data from Schoology's REST API.
Prerequisites
- A Schoology account with API access enabled (typically requires a district-level administrator or system admin account)
- A Schoology API consumer key and secret (obtained via Schoology's API management settings or your district's Schoology administrator)
- A Retool account with permission to create Resources
- Knowledge of which Schoology building IDs or school IDs you need to query (for district-level access)
- Familiarity with Retool's query editor, Table component, and basic event handler configuration
Step-by-step guide
Obtain Schoology API credentials and create the REST API Resource
Before creating the Retool resource, obtain your Schoology API credentials. In Schoology, navigate to your Account Settings → API and click Generate API Credentials. This gives you a consumer key and consumer secret. If you do not see an API section, contact your Schoology district administrator to enable API access for your account. In Retool, go to the Resources tab and click Add Resource. Select REST API from the resource type list. Name the resource 'Schoology API'. In the Base URL field, enter https://api.schoology.com. All Schoology API v1 endpoints follow the pattern /v1/{resource} which will be appended to this base URL. Schoolygy uses OAuth 1.0a authentication, which signs each request with your consumer key and secret. In Retool's REST API resource, set the Authentication type to Basic Auth as a starting point, then switch to Custom Headers to properly implement OAuth 1.0a. Add the following header: - Authorization: OAuth realm='Schoology API', oauth_consumer_key='{{ retoolContext.configVars.SCHOOLOGY_CONSUMER_KEY }}', oauth_signature_method='HMAC-SHA1', oauth_timestamp='', oauth_nonce='', oauth_version='1.0', oauth_signature='' For production use, implement the full OAuth 1.0a signature via a Retool Workflow or JavaScript query that generates the Authorization header dynamically. Store your consumer key in Settings → Configuration Variables as SCHOOLOGY_CONSUMER_KEY and the consumer secret as SCHOOLOGY_CONSUMER_SECRET (both marked as Secret). Save the resource configuration.
1// JavaScript query — generate OAuth 1.0a Authorization header for Schoology2// Run this query before your API calls to get a fresh signed header3const consumerKey = retoolContext.configVars.SCHOOLOGY_CONSUMER_KEY;4const consumerSecret = retoolContext.configVars.SCHOOLOGY_CONSUMER_SECRET;5const method = 'GET';6const url = 'https://api.schoology.com/v1/users';78// Generate OAuth parameters9const timestamp = Math.floor(Date.now() / 1000).toString();10const nonce = Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2);1112// For simple read-only operations, Schoology also accepts two-legged OAuth13// where the Authorization header is built with consumer key only (no token)14const authHeader = `OAuth realm="Schoology API",` +15 `oauth_consumer_key="${consumerKey}",` +16 `oauth_signature_method="PLAINTEXT",` +17 `oauth_timestamp="${timestamp}",` +18 `oauth_nonce="${nonce}",` +19 `oauth_version="1.0",` +20 `oauth_signature="${consumerSecret}%26"`;2122return { authorization: authHeader };Pro tip: Schoology supports two-legged OAuth (no user token required) for system-level API access with a consumer key and secret. This is simpler than full OAuth 1.0a with user tokens and is appropriate for administrative dashboards that access data across all users.
Expected result: The Schoology API resource is saved in Retool with the base URL configured. The OAuth header generator query returns a valid Authorization header that can be referenced in subsequent API queries.
Query users, courses, and enrollments
Create queries to retrieve the core Schoology data your dashboard needs. Start with courses and users, which are the foundation of most administrative reports. Create a query named getCourses: - Method: GET - Path: /v1/courses - Headers: Authorization = {{ generateOAuthHeader.data.authorization }} This returns courses across your Schoology account. Each course object includes an id, title, course_code, description, and building_id (school identifier). Add a URL parameter school_id to filter by a specific school if your district has multiple buildings. Create a query named getCourseEnrollments: - Method: GET - Path: /v1/courses/{{ dropdown_course.value }}/sections - Headers: Authorization = {{ generateOAuthHeader.data.authorization }} This retrieves all sections of a selected course, including enrollment counts. To get the actual list of enrolled users in a section, create getEnrolledStudents: - Method: GET - Path: /v1/sections/{{ table_sections.selectedRow.id }}/enrollments - Headers: Authorization = {{ generateOAuthHeader.data.authorization }} Bind getCourses results to a Select component named dropdown_course. When a course is selected, getCourseEnrollments runs to populate a sections table. Selecting a section row triggers getEnrolledStudents to show the student roster. Schoolygy enrollment responses include role (admin, teacher, student) and status (active, inactive) fields — filter to status=1 (active) and role=student to see only currently enrolled students.
1// JavaScript transformer — format enrollment list for student roster table2const enrollments = (data.enrollment || []);3return enrollments4 .filter(e => e.status === 1 && e.admin === 0) // active students only5 .map(enrollment => ({6 uid: enrollment.uid,7 name: `${enrollment.name_first || ''} ${enrollment.name_last || ''}`.trim(),8 email: enrollment.primary_email || 'N/A',9 grade_level: enrollment.grad_year || 'N/A',10 enrollment_status: enrollment.status === 1 ? 'Active' : 'Inactive',11 enrollment_date: enrollment.created12 ? new Date(enrollment.created * 1000).toLocaleDateString()13 : 'N/A'14 }))15 .sort((a, b) => a.name.localeCompare(b.name));Pro tip: Schoology timestamps are Unix epoch integers, not ISO 8601 strings. Convert them using new Date(timestamp * 1000) when formatting dates in your transformers — note the multiplication by 1000 to convert seconds to milliseconds.
Expected result: The courses dropdown populates with available courses. Selecting a course loads the sections table with enrollment counts. Selecting a section populates the student roster with active enrolled students.
Query grades and assignment completion data
Create queries to retrieve grade data for students in a selected course section. Schoology's grades API provides both overall course grades and individual assignment scores. Create a query named getSectionGrades: - Method: GET - Path: /v1/sections/{{ table_sections.selectedRow.id }}/grades - Headers: Authorization = {{ generateOAuthHeader.data.authorization }} This returns grade data for all students in the section. The response includes an array of student grade objects with uid, grade, comment, and a grades array of individual assignment scores. Create a query named getSectionAssignments: - Method: GET - Path: /v1/sections/{{ table_sections.selectedRow.id }}/assignments - Headers: Authorization = {{ generateOAuthHeader.data.authorization }} This retrieves all assignments in the section with due dates, point values, and categories. Combine getSectionGrades and getSectionAssignments in a JavaScript query to calculate completion rates: Bind the merged data to a Table component with columns for student name, current grade (formatted as a letter grade), assignments completed, assignments missing, and completion rate. Apply conditional row formatting to highlight students below 70% grade in red and students with more than 3 missing assignments in orange. For individual student drilldown, create getStudentGradeDetail: - Method: GET - Path: /v1/users/{{ table_students.selectedRow.uid }}/grades - URL parameter: section_id = {{ table_sections.selectedRow.id }} This shows the complete grade breakdown for a single student across all assignments in the section.
1// JavaScript query — merge grades with assignment data to calculate completion2const grades = (getSectionGrades.data?.grades?.grade || []);3const assignments = (getSectionAssignments.data?.assignment || []);4const totalAssignments = assignments.length;56return grades.map(studentGrade => {7 const assignmentScores = studentGrade.grades?.grade || [];8 const completed = assignmentScores.filter(9 g => g.grade !== null && g.grade !== undefined && g.grade !== ''10 ).length;11 const missing = totalAssignments - completed;12 const overallGrade = parseFloat(studentGrade.grade);1314 return {15 uid: studentGrade.uid,16 overall_grade: isNaN(overallGrade) ? 'N/A' : `${overallGrade.toFixed(1)}%`,17 letter_grade: overallGrade >= 90 ? 'A'18 : overallGrade >= 80 ? 'B'19 : overallGrade >= 70 ? 'C'20 : overallGrade >= 60 ? 'D' : 'F',21 assignments_completed: completed,22 assignments_missing: missing,23 completion_rate: totalAssignments > 024 ? `${((completed / totalAssignments) * 100).toFixed(0)}%`25 : 'N/A',26 at_risk: overallGrade < 70 || missing > 327 };28});Pro tip: Schoology's grades endpoint requires the section to have grade periods configured. If grades come back empty, verify that the section has an active grading period in Schoology's course settings. Administrators can check this in the Schoology admin interface.
Expected result: The grades table populates with all students in the selected section, showing their current grade percentage, letter grade, and assignment completion statistics. At-risk students are visually highlighted based on the conditional formatting rules.
Build a cross-section performance comparison view
Create a performance comparison view that lets curriculum directors compare grade distributions across multiple sections of the same course. This is one of the most valuable uses of Retool for K-12 administrators because Schoology's built-in UI shows one section at a time. Create a JavaScript query named aggregateSectionPerformance that runs after fetching grades for multiple sections: In your Retool app layout, add a Multi-Select component named multiSelect_sections to let users choose which sections to compare. Set its options bound to {{ getCourseEnrollments.data.section.map(s => ({ label: s.section_title, value: s.id })) }}. Add a Chart component configured as a grouped bar chart with sections on the x-axis and average grade on the y-axis. Below the chart, add a Table showing the summary statistics per section: section name, teacher name, enrolled count, average grade, passing rate (students above 70%), and A-rate (students above 90%). For the teacher performance view, add a text component that calculates which section has the highest average grade and displays it as a highlighted best practice: 'Section {{ bestPerformingSection.name }} led by {{ bestPerformingSection.teacher }} has the highest average grade of {{ bestPerformingSection.avg }}%'. This cross-section view is the core value proposition of the Retool-Schoology integration for district administrators and curriculum directors who need to make data-driven decisions about instructional support.
1// JavaScript query — aggregate performance statistics across multiple sections2// Assumes sectionGradesData is an array of { sectionId, sectionTitle, teacher, grades[] }3const sectionData = sectionGradesData || [];45return sectionData.map(section => {6 const grades = (section.grades || []).map(g => parseFloat(g.grade)).filter(g => !isNaN(g));7 const avg = grades.length > 08 ? grades.reduce((sum, g) => sum + g, 0) / grades.length9 : 0;10 const passing = grades.filter(g => g >= 70).length;11 const aGrade = grades.filter(g => g >= 90).length;1213 return {14 section_id: section.sectionId,15 section_title: section.sectionTitle || 'Unknown Section',16 teacher: section.teacher || 'Unknown',17 enrolled: grades.length,18 average_grade: avg.toFixed(1),19 passing_count: passing,20 passing_rate: grades.length > 021 ? `${((passing / grades.length) * 100).toFixed(0)}%`22 : 'N/A',23 a_rate: grades.length > 024 ? `${((aGrade / grades.length) * 100).toFixed(0)}%`25 : 'N/A'26 };27}).sort((a, b) => parseFloat(b.average_grade) - parseFloat(a.average_grade));Pro tip: When loading grades for multiple sections simultaneously, use Promise.all() in a JavaScript query to trigger all section grade queries in parallel rather than sequentially. This significantly reduces total load time for a cross-section comparison view.
Expected result: The performance comparison table shows all selected sections ranked by average grade, with passing rates and A-rates calculated. The bar chart visually displays grade distribution differences between sections.
Add student search and at-risk identification panel
Build a student search panel that gives counselors and administrators the ability to look up any student across all courses and identify at-risk indicators. This requires combining user lookup with cross-course grade queries. Create a query named searchUsers: - Method: GET - Path: /v1/users - URL parameter: school_uid = {{ textInput_studentSearch.value }} (for searching by student ID) - Headers: Authorization = {{ generateOAuthHeader.data.authorization }} For name-based search, Schoology supports a name_first and name_last parameter. Add these as conditional URL parameters. Once a student is selected from the search results, create getStudentCourses: - Method: GET - Path: /v1/users/{{ selectedStudent.uid }}/sections - Headers: Authorization = {{ generateOAuthHeader.data.authorization }} This retrieves all course sections the student is currently enrolled in. For each section, fetch their grade using the grades endpoint. Combine the results in a JavaScript query that flags: - Any course where grade is below 70% - Any course where grade has dropped more than 10 points in the last two weeks - Any section with more than 3 overdue assignments Display the at-risk summary at the top of the student profile panel using Callout or Alert components, then show the full course list below. For complex multi-school district implementations with thousands of students, RapidDev's team can help architect a caching layer using Retool Database that pre-computes at-risk indicators nightly so the student lookup panel loads instantly.
1// JavaScript query — identify at-risk indicators across student's enrolled courses2const enrolledCourses = (getStudentCourses.data?.section || []);3const gradeData = studentGradesByCourse || {}; // Object keyed by section ID45const coursesSummary = enrolledCourses.map(section => {6 const grades = gradeData[section.id] || {};7 const currentGrade = parseFloat(grades.grade) || null;8 const missingCount = parseInt(grades.missing_assignments) || 0;910 return {11 section_id: section.id,12 course_title: section.course_title || 'Unknown Course',13 section_title: section.section_title || '',14 teacher: section.teacher_name || 'Unknown',15 current_grade: currentGrade !== null ? `${currentGrade.toFixed(1)}%` : 'No grades',16 letter_grade: currentGrade >= 90 ? 'A' : currentGrade >= 80 ? 'B'17 : currentGrade >= 70 ? 'C' : currentGrade >= 60 ? 'D' : 'F',18 missing_assignments: missingCount,19 at_risk_grade: currentGrade !== null && currentGrade < 70,20 at_risk_missing: missingCount > 3,21 risk_level: (currentGrade < 70 && missingCount > 3) ? 'HIGH'22 : (currentGrade < 70 || missingCount > 3) ? 'MEDIUM' : 'LOW'23 };24});2526return {27 courses: coursesSummary,28 high_risk_count: coursesSummary.filter(c => c.risk_level === 'HIGH').length,29 medium_risk_count: coursesSummary.filter(c => c.risk_level === 'MEDIUM').length30};Pro tip: For counselor-facing tools, display the at-risk course count prominently at the top of the student profile using a Stat component. This allows counselors to immediately see the severity without reading through the full course table.
Expected result: The student search returns matching users from Schoology. Selecting a student populates their full course list with grades and at-risk indicators. The risk level summary at the top clearly shows how many courses need immediate counselor attention.
Common use cases
Build a student performance tracker across all courses
Create a Retool panel where teachers or counselors can look up a student by ID or name and see their enrollment status, current grade, and assignment completion rate across all active courses. Display a summary showing which courses they are struggling in, flagging any course with a grade below 70% or more than 3 missing assignments.
Build a student lookup dashboard with a search input for student name or ID, a Table showing all enrolled courses with current grade and missing assignment count, and a color-coded risk indicator that flags courses where the student is below passing threshold so counselors can intervene quickly.
Copy this prompt to try it in Retool
Course grade distribution dashboard for curriculum directors
Build a Retool dashboard for curriculum directors that aggregates grade distributions across all sections of the same course — for example, all sections of Algebra I across a district. Display average grades, standard deviations, and assignment completion rates per section, enabling directors to identify sections or teachers where student outcomes differ significantly from the norm.
Create a curriculum analysis panel that lists all sections of a selected course with their average grade, grade distribution as a histogram, and assignment completion rate, sorted by performance so directors can quickly identify which sections need support or represent best practices to share.
Copy this prompt to try it in Retool
District-level enrollment and course management panel
Build an administrative panel that gives district operations teams a real-time view of enrollment numbers across all schools and courses. Show total enrollment per course, seat capacity utilization, and waitlist counts. Include the ability to view course details and enrolled student lists with contact information for parent communication workflows.
Build a district enrollment dashboard that fetches all courses and their enrollment counts, displays capacity utilization by school in a bar chart, and provides a drilldown table showing enrolled students for any selected course with their name, grade level, and parent contact information.
Copy this prompt to try it in Retool
Troubleshooting
All API calls return 401 Unauthorized despite entering the correct consumer key
Cause: Schoology OAuth 1.0a requires a properly formatted Authorization header with specific parameters. An incorrectly structured header or missing parameters will result in authentication failure.
Solution: Verify that your Authorization header follows the exact OAuth 1.0a format with all required fields: realm, oauth_consumer_key, oauth_signature_method, oauth_timestamp, oauth_nonce, oauth_version, and oauth_signature. For PLAINTEXT signature method, the signature is your consumer secret followed by %26 (the URL-encoded ampersand). Test with a direct API call in Retool's query preview panel and inspect the Authorization header value.
1// Minimal OAuth 1.0a header for Schoology two-legged auth2// oauth_signature for PLAINTEXT = consumerSecret + '%26' (no token)3Authorization: OAuth realm="Schoology API",oauth_consumer_key="YOUR_KEY",oauth_signature_method="PLAINTEXT",oauth_timestamp="1234567890",oauth_nonce="abc123",oauth_version="1.0",oauth_signature="YOUR_SECRET%26"Grades endpoint returns empty array even though grades are entered in Schoology
Cause: The section may not have an active grading period configured, or you may be querying a section from a previous semester that has been archived.
Solution: Verify in Schoology that the course section has an active grading period enabled in Course Settings → Gradebook. Check that the section is in the current active term. If querying historical data, some districts restrict API access to previous terms — verify with your Schoology administrator that historical section access is enabled.
User search by name returns no results even for existing students
Cause: Schoology's user search endpoint may not support partial name matching — it often requires exact name fields or the internal Schoology user ID (uid) for direct lookup.
Solution: Try querying with the exact first name in the name_first parameter and exact last name in name_last, or use the school_uid parameter with the student's district-assigned ID number. If your district assigns unique school UIDs, searching by school_uid is more reliable than name-based search. Alternatively, preload all users into a searchable Retool Table using the /v1/users endpoint with pagination.
API returns 403 Forbidden for certain resources like grades or user data
Cause: Your Schoology API credentials may be associated with a teacher account rather than an administrator account, restricting access to student data outside your own courses.
Solution: Schoology API permissions are tied to the role of the account that generated the credentials. System administrator or district administrator accounts have access to all users, grades, and courses across the district. Request administrator-level API credentials from your Schoology district admin for full dashboard access. Teacher accounts can only access their own sections and students.
Best practices
- Store your Schoology consumer key and consumer secret as Secret configuration variables in Retool — never hard-code them in query headers or body fields.
- Use a system administrator Schoology account to generate API credentials for your Retool integration, as teacher accounts have restricted access that limits the usefulness of administrative dashboards.
- Convert Schoology's Unix epoch timestamps (seconds) to readable dates using new Date(timestamp * 1000).toLocaleDateString() in your JavaScript transformers — note the multiplication by 1000.
- Pre-load courses and sections into dropdown components on page load, then trigger grade queries only when a specific section is selected to avoid making unnecessary API calls for all sections at once.
- Add caching for cross-section performance reports by storing computed metrics in Retool Database via a nightly Workflow, so directors can load the comparison view instantly without waiting for multiple grade API calls.
- Filter enrollment queries to active students only (status=1) to avoid including withdrawn or transferred students in your performance reports.
- When building counselor-facing at-risk dashboards, prioritize visual at-risk indicators (colored badges, alert callouts) over raw numbers — counselors need to act quickly on the most at-risk students.
Alternatives
Canvas is widely used in higher education with a modern REST API and OAuth 2.0, while Schoology targets K-12 with OAuth 1.0a and is designed around classroom and district administration.
Blackboard is an enterprise LMS used in higher education and large institutions with complex OAuth 2.0 authentication, while Schoology is purpose-built for K-12 districts with simpler grade management workflows.
Moodle is an open-source LMS deployable on your own infrastructure with token-based Web Services, while Schoology is a hosted K-12 platform with district-level administration features.
Frequently asked questions
Does Schoology have a native connector in Retool?
No, Schoology does not have a native connector in Retool. You connect it via a REST API Resource using OAuth 1.0a authentication with your Schoology consumer key and secret. The key distinction from most REST APIs is that Schoology requires OAuth 1.0a signing rather than simple API key or Bearer token authentication, which adds some configuration complexity.
What level of Schoology account do I need to build a district-wide dashboard?
You need a system administrator or district administrator account to generate API credentials that have access to all users, courses, and grades across the district. Teacher-level accounts can only access their own courses and sections. Request administrator-level API credentials from your Schoology district system administrator before building cross-school or cross-course dashboards.
Can I write grade data back to Schoology from Retool?
Yes, Schoology's API supports grade submission via PUT requests to the /v1/sections/{section_id}/grades endpoint. You can build Retool forms that allow administrators to update grades programmatically. However, this should be done carefully — always add confirmation modals and audit logging before allowing grade writes from Retool, as incorrect grade changes have immediate consequences for students.
How do I handle large districts with thousands of students in Retool?
Schoology's API uses pagination for large result sets. Use the start and limit URL parameters to page through results (e.g., start=0&limit=200 for the first page, start=200 for the next). For district-wide dashboards with thousands of students, use a Retool Workflow to sync student and grade data into Retool Database nightly, then query the cached data in your live dashboard for much faster load times.
Can I send messages to students or parents through the Schoology API from Retool?
Yes, Schoology's API includes a messaging endpoint at /v1/messages that allows you to send private messages to users within the Schoology platform. You can build a Retool panel that lets counselors or administrators send direct messages to students or their associated parent accounts. Messages appear in the recipient's Schoology inbox. Ensure your message content complies with your district's communication policies.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation