Canvas LMS Integration
The B12 SIS integrates with Instructure Canvas LMS for course management, assignments, grades, and user synchronization.
Overview
The Canvas integration supports:
User Sync: Students and teachers sync to Canvas users
Course Sync: SIS courses create/update Canvas courses
Enrollment Sync: Student/teacher enrollments sync to Canvas
Assignment Sync: Canvas assignments import to SIS assessments
Grade Sync: Assessment results sync from Canvas gradebook
Blueprint Courses: Course templates from Canvas blueprints
Configuration
Environment Variables
# Canvas API Configuration
CANVAS_API_URL=https://canvas.yourschool.edu
CANVAS_API_TOKEN=your-api-token
CANVAS_ACCOUNT_ID=1
CANVAS_SYNC_ENABLED=true
# Sync Options
CANVAS_SYNC_BATCH_SIZE=100
CANVAS_SYNC_DRY_RUN=false
Getting an API Token
Log into Canvas as an admin
Go to Account > Settings
Click “New Access Token”
Set expiration and save the token
!!! warning “Token Security” Store the API token securely. Never commit it to version control.
Sync Architecture
┌─────────────────────────────────────────────────────────────┐
│ B12 SIS │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │
│ │ Student │ │ Course │ │ Enroll │ │ Assessment │ │
│ │ Model │ │ Model │ │ Model │ │ Result Model │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────────┬────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▲ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ Canvas Hooks ││
│ │ AfterSave → SyncIfNeeded → Canvas API Client ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────┬───────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Canvas LMS │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │
│ │ Users │ │ Courses │ │ Enroll │ │ Assignments │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────┘
User Synchronization
Student Sync
When a student is created/updated in SIS:
AfterSavehook triggersCheck if
need_canvas_sync = trueCreate/update Canvas user via API
Store
lms_idin student recordSet
need_canvas_sync = false
Student → Canvas User Mapping:
SIS Field |
Canvas Field |
|---|---|
|
|
|
|
|
|
|
|
Teacher Sync
Similar to student sync, teachers sync to Canvas users with appropriate roles.
Manual Sync Trigger
Force sync a student:
curl -X POST http://localhost:8080/api/students/:id/force-sync-canvas \
-H "Authorization: Bearer $TOKEN" \
-H "X-Team-ID: $TEAM_ID"
Course Synchronization
Course Creation
When a course is created in SIS:
Create Canvas course in the configured account
Store
canvas_idin SIS courseApply blueprint association if course template specified
Course → Canvas Course Mapping:
SIS Field |
Canvas Field |
|---|---|
|
|
|
|
|
|
Blueprint Courses
Course templates sync from Canvas blueprints:
Blueprint courses in Canvas are tagged
Sync job imports blueprints as
CourseTemplaterecordsNew courses can be associated with templates
Template changes push to associated courses
Sync Blueprint Courses:
curl -X POST http://localhost:8080/api/course_templates/sync-canvas \
-H "Authorization: Bearer $TOKEN" \
-H "X-Team-ID: $TEAM_ID"
Enrollment Synchronization
Student Enrollment
When a student enrolls in a course:
StudentEnrollCoursecreated in SISHook triggers Canvas enrollment creation
Store
canvas_enrollment_idin SIS
Enrollment States:
SIS Status |
Canvas State |
|---|---|
|
|
|
|
|
|
|
|
Teacher Enrollment
Primary teachers enroll as TeacherEnrollment:
// Course model tracks teacher enrollment
PrimaryTeacherEnrollCanvasId string
NeedPrimaryTeacherEnrollCanvasSync bool
Assignment & Grade Sync
Import Assignments
Canvas assignments import to SIS assessments:
Sync Job: CanvasSyncAssignmentsJob
make run-job JOB=CanvasSyncAssignmentsJob
Assignment → Assessment Mapping:
Canvas Field |
SIS Field |
|---|---|
|
|
|
|
|
|
|
|
|
|
Import Grades
Canvas submission grades import to SIS:
Sync Job: CanvasSyncGradesJob
Imports:
score→AssessmentResult.scoregrade→AssessmentResult.gradesubmitted_at→AssessmentResult.submitted_atgraded_at→AssessmentResult.graded_at
Force Sync Student Assessments
Trigger grade sync for a specific student:
curl -X POST http://localhost:8080/api/students/:id/force-sync-canvas-assessments \
-H "Authorization: Bearer $TOKEN" \
-H "X-Team-ID: $TEAM_ID"
Background Jobs
CanvasSyncJob
Master sync job that coordinates all sync operations:
Schedule: Every hour
Operations: Users, courses, enrollments
CanvasSyncCourseEnrollmentsJob
Syncs course enrollments:
Schedule: Every 30 minutes
Handles: New enrollments, updates, deletions
CanvasBlueprintSyncJob
Syncs blueprint/template courses:
Schedule: Daily at 2 AM
Handles: Blueprint imports, associations
Running Jobs Manually
# Run specific job
make run-job JOB=CanvasSyncJob
# List all jobs
make list-jobs
API Endpoints
Course Template Endpoints
Endpoint |
Description |
|---|---|
|
Get blueprint courses |
|
Get sync status |
|
Get failed syncs |
|
Trigger sync |
Canvas Data Endpoints
Endpoint |
Description |
|---|---|
|
List imported assignments |
|
List imported modules |
|
List module items |
Error Handling
Sync Errors
Failed syncs are logged and can be retried:
{
"id": "sync-error-uuid",
"entity_type": "Student",
"entity_id": "student-uuid",
"operation": "create_user",
"error": "Canvas API error: email already exists",
"retry_count": 3,
"last_attempt": "2024-01-15T10:30:00Z"
}
Viewing Sync Errors
curl http://localhost:8080/api/course_templates/failed-syncs \
-H "Authorization: Bearer $TOKEN" \
-H "X-Team-ID: $TEAM_ID"
Common Errors
Error |
Cause |
Solution |
|---|---|---|
|
Duplicate email |
Update existing user |
|
Invalid canvas_id |
Re-sync course |
|
Duplicate enrollment |
Skip or update |
|
Too many API calls |
Reduce batch size |
Password Synchronization
Optional feature to sync passwords:
Enable in settings
When student password changes in SIS
Update Canvas login credentials
Notify student of change
!!! warning “Security” Password sync should only be enabled for managed accounts. External SSO accounts should not sync passwords.
Monitoring
Sync Status Dashboard
Monitor sync health:
curl http://localhost:8080/api/course_templates/sync-status \
-H "Authorization: Bearer $TOKEN"
Response:
{
"success": true,
"data": {
"last_sync": "2024-01-15T10:00:00Z",
"status": "completed",
"stats": {
"users_synced": 150,
"courses_synced": 25,
"enrollments_synced": 500,
"errors": 3
}
}
}
Job Logs
curl -X POST http://localhost:8080/api/job_logs/list \
-H "Authorization: Bearer $TOKEN" \
-H "X-Team-ID: $TEAM_ID" \
-H "Content-Type: application/json" \
-d '{
"filter": {
"conditions": [
{"field": "job_name", "operator": "contains", "value": "Canvas"}
]
}
}'
Best Practices
Test in Sandbox: Use Canvas sandbox for testing
Batch Operations: Use batch APIs for large syncs
Monitor Logs: Check job logs regularly
Handle Failures: Implement retry logic for transient failures
Unique Identifiers: Use SIS IDs for reliable matching
Rate Limits: Respect Canvas API rate limits (700 req/10 min)