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

  1. Log into Canvas as an admin

  2. Go to Account > Settings

  3. Click “New Access Token”

  4. 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:

  1. AfterSave hook triggers

  2. Check if need_canvas_sync = true

  3. Create/update Canvas user via API

  4. Store lms_id in student record

  5. Set need_canvas_sync = false

Student → Canvas User Mapping:

SIS Field

Canvas Field

email

login_id, email

first_name

name (part)

last_name

sortable_name (part)

code

sis_user_id

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:

  1. Create Canvas course in the configured account

  2. Store canvas_id in SIS course

  3. Apply blueprint association if course template specified

Course → Canvas Course Mapping:

SIS Field

Canvas Field

name

name

code

course_code, sis_course_id

status

workflow_state

Blueprint Courses

Course templates sync from Canvas blueprints:

  1. Blueprint courses in Canvas are tagged

  2. Sync job imports blueprints as CourseTemplate records

  3. New courses can be associated with templates

  4. 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:

  1. StudentEnrollCourse created in SIS

  2. Hook triggers Canvas enrollment creation

  3. Store canvas_enrollment_id in SIS

Enrollment States:

SIS Status

Canvas State

active

active

invited

invited

completed

completed

inactive

inactive

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

id

canvas_assignment_id

name

name

due_at

due_date

points_possible

max_score

submission_types

type

Import Grades

Canvas submission grades import to SIS:

Sync Job: CanvasSyncGradesJob

Imports:

  • scoreAssessmentResult.score

  • gradeAssessmentResult.grade

  • submitted_atAssessmentResult.submitted_at

  • graded_atAssessmentResult.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 /api/course_templates/blueprint

Get blueprint courses

GET /api/course_templates/sync-status

Get sync status

GET /api/course_templates/failed-syncs

Get failed syncs

POST /api/course_templates/sync-canvas

Trigger sync

Canvas Data Endpoints

Endpoint

Description

GET /api/canvas_assignments/list

List imported assignments

GET /api/canvas_modules/list

List imported modules

GET /api/canvas_module_items/list

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

user already exists

Duplicate email

Update existing user

course not found

Invalid canvas_id

Re-sync course

enrollment exists

Duplicate enrollment

Skip or update

rate limit exceeded

Too many API calls

Reduce batch size

Password Synchronization

Optional feature to sync passwords:

  1. Enable in settings

  2. When student password changes in SIS

  3. Update Canvas login credentials

  4. 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

  1. Test in Sandbox: Use Canvas sandbox for testing

  2. Batch Operations: Use batch APIs for large syncs

  3. Monitor Logs: Check job logs regularly

  4. Handle Failures: Implement retry logic for transient failures

  5. Unique Identifiers: Use SIS IDs for reliable matching

  6. Rate Limits: Respect Canvas API rate limits (700 req/10 min)