Google Docs to Forms - Formswrite.com logo
BlogPricing

Canvas API: Create Users, Courses, and Enroll Students (Code Examples)

FO

Formswrite Team

Feb 15, 2026

Canvas API: Create Users, Courses, and Enroll Students (Code Examples)

Canvas API: Create Users, Courses, and Enroll Students

This guide covers the most common Canvas API operations with complete code examples: creating users, building courses, enrolling students, and managing grades.

Prerequisites

  1. A Canvas LMS instance (institutional or free teacher account)
  2. An Access Token (Account → Settings → Approved Integrations → New Access Token)
  3. Admin permissions for user creation (or use the free teacher account for course management)

Create Users

POST /api/v1/accounts/:account_id/users

Requires admin permissions.
bashcurl -X POST "https://yourschool.instructure.com/api/v1/accounts/1/users" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "user": {
      "name": "Jane Smith",
      "short_name": "Jane",
      "sortable_name": "Smith, Jane",
      "terms_of_use": true,
      "skip_registration": true
    },
    "pseudonym": {
      "unique_id": "[email protected]",
      "password": "SecurePass123!",
      "sis_user_id": "STU-2026-001",
      "send_confirmation": false
    }
  }'

Response

json{
  "id": 142,
  "name": "Jane Smith",
  "short_name": "Jane",
  "sortable_name": "Smith, Jane",
  "email": "[email protected]",
  "login_id": "[email protected]",
  "created_at": "2026-02-15T10:30:00Z"
}

Python: Create Multiple Users

pythonimport requests

CANVAS_URL = "https://yourschool.instructure.com"
TOKEN = "your_access_token"
ACCOUNT_ID = 1

headers = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json"
}

students = [
    {"name": "Alice Johnson", "email": "[email protected]", "sis_id": "STU-001"},
    {"name": "Bob Williams", "email": "[email protected]", "sis_id": "STU-002"},
    {"name": "Carol Davis", "email": "[email protected]", "sis_id": "STU-003"},
]

created_users = []
for student in students:
    response = requests.post(
        f"{CANVAS_URL}/api/v1/accounts/{ACCOUNT_ID}/users",
        headers=headers,
        json={
            "user": {
                "name": student["name"],
                "terms_of_use": True,
                "skip_registration": True
            },
            "pseudonym": {
                "unique_id": student["email"],
                "password": "Welcome2026!",
                "sis_user_id": student["sis_id"],
                "send_confirmation": False
            }
        }
    )
    user = response.json()
    created_users.append(user)
    print(f"Created: {user['name']} (ID: {user['id']})")

Get All Users

GET /api/v1/accounts/:account_id/users

bashcurl "https://yourschool.instructure.com/api/v1/accounts/1/users?per_page=100" \
  -H "Authorization: Bearer YOUR_TOKEN"

Python: Search Users

python# Search by email
response = requests.get(
    f"{CANVAS_URL}/api/v1/accounts/{ACCOUNT_ID}/users",
    headers=headers,
    params={
        "search_term": "[email protected]",
        "per_page": 10
    }
)
users = response.json()

# List all users with pagination
def get_all_users():
    url = f"{CANVAS_URL}/api/v1/accounts/{ACCOUNT_ID}/users?per_page=100"
    all_users = []
    while url:
        response = requests.get(url, headers=headers)
        all_users.extend(response.json())
        links = response.headers.get("Link", "")
        url = None
        for link in links.split(","):
            if 'rel="next"' in link:
                url = link.split(";")[0].strip("<> ")
    return all_users

Create Courses

POST /api/v1/accounts/:account_id/courses

bashcurl -X POST "https://yourschool.instructure.com/api/v1/accounts/1/courses" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "course": {
      "name": "Biology 101 - Spring 2026",
      "course_code": "BIO101-SP26",
      "start_at": "2026-01-15T00:00:00Z",
      "end_at": "2026-05-15T00:00:00Z",
      "license": "private",
      "is_public": false,
      "default_view": "modules"
    }
  }'

Python: Create Multiple Courses

pythoncourses = [
    {"name": "Biology 101", "code": "BIO101"},
    {"name": "Chemistry 201", "code": "CHEM201"},
    {"name": "Physics 301", "code": "PHYS301"},
]

for c in courses:
    response = requests.post(
        f"{CANVAS_URL}/api/v1/accounts/{ACCOUNT_ID}/courses",
        headers=headers,
        json={
            "course": {
                "name": c["name"],
                "course_code": c["code"],
                "default_view": "modules"
            },
            "offer": True  # Publish immediately
        }
    )
    course = response.json()
    print(f"Created course: {course['name']} (ID: {course['id']})")

Get All Courses

pythonresponse = requests.get(
    f"{CANVAS_URL}/api/v1/courses",
    headers=headers,
    params={"per_page": 100}
)

for course in response.json():
    print(f"{course['id']}: {course['name']} ({course.get('course_code', 'N/A')})")

Enroll Students

POST /api/v1/courses/:course_id/enrollments

Enrollment Types

TypeRole
StudentEnrollmentStudent
TeacherEnrollmentTeacher
TaEnrollmentTeaching Assistant
ObserverEnrollmentObserver
DesignerEnrollmentDesigner

cURL: Enroll a Student

bashcurl -X POST "https://yourschool.instructure.com/api/v1/courses/5/enrollments" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enrollment": {
      "user_id": 142,
      "type": "StudentEnrollment",
      "enrollment_state": "active",
      "notify": false
    }
  }'

Python: Bulk Enroll Students

pythoncourse_id = 5
student_ids = [142, 143, 144, 145, 146]

for uid in student_ids:
    response = requests.post(
        f"{CANVAS_URL}/api/v1/courses/{course_id}/enrollments",
        headers=headers,
        json={
            "enrollment": {
                "user_id": uid,
                "type": "StudentEnrollment",
                "enrollment_state": "active",
                "notify": False
            }
        }
    )
    enrollment = response.json()
    print(f"Enrolled user {uid}: {enrollment.get('id', 'error')}")

Enroll by SIS ID

bashcurl -X POST "https://yourschool.instructure.com/api/v1/courses/5/enrollments" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enrollment": {
      "user_id": "sis_user_id:STU-001",
      "type": "StudentEnrollment",
      "enrollment_state": "active"
    }
  }'

Complete Workflow: Course Setup

pythonimport requests

CANVAS_URL = "https://yourschool.instructure.com"
TOKEN = "your_token"
ACCOUNT_ID = 1
headers = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json"
}

# Step 1: Create the course
course = requests.post(
    f"{CANVAS_URL}/api/v1/accounts/{ACCOUNT_ID}/courses",
    headers=headers,
    json={
        "course": {
            "name": "Biology 101 - Spring 2026",
            "course_code": "BIO101",
            "default_view": "modules"
        },
        "offer": True
    }
).json()
course_id = course["id"]
print(f"Course created: {course_id}")

# Step 2: Create students
students = [
    {"name": "Alice", "email": "[email protected]"},
    {"name": "Bob", "email": "[email protected]"},
]

user_ids = []
for s in students:
    user = requests.post(
        f"{CANVAS_URL}/api/v1/accounts/{ACCOUNT_ID}/users",
        headers=headers,
        json={
            "user": {"name": s["name"], "skip_registration": True},
            "pseudonym": {"unique_id": s["email"], "password": "Welcome2026!"}
        }
    ).json()
    user_ids.append(user["id"])
    print(f"User created: {user['name']} ({user['id']})")

# Step 3: Enroll students
for uid in user_ids:
    requests.post(
        f"{CANVAS_URL}/api/v1/courses/{course_id}/enrollments",
        headers=headers,
        json={
            "enrollment": {
                "user_id": uid,
                "type": "StudentEnrollment",
                "enrollment_state": "active"
            }
        }
    )
print(f"Enrolled {len(user_ids)} students in course {course_id}")

# Step 4: Create a module
module = requests.post(
    f"{CANVAS_URL}/api/v1/courses/{course_id}/modules",
    headers=headers,
    json={"module": {"name": "Week 1: Introduction", "position": 1}}
).json()
print(f"Module created: {module['id']}")

Adding Quizzes to Your Courses

Once your course structure is set up, you'll want to add assessments. Creating quizzes through the Canvas API requires building each question individually with complex JSON - for a 50-question quiz, that's 50+ API calls.
A faster approach: use Formswrite to convert a Google Doc into a Canvas QTI package, then import it.
bash# 1. Convert Google Doc to Canvas QTI via Formswrite
curl -X POST https://api.formswrite.com/api/v1/convert \
  -H "Authorization: Bearer FORMSWRITE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"documentId": "DOC_ID", "format": "canvas"}'

# 2. Download the QTI .zip file from the response URL

# 3. Import into Canvas via Settings → Import Course Content → QTI .zip file
This approach: write questions naturally in a Google Doc, let AI handle the conversion, and import into Canvas in seconds.

FAQ

How do I get a Canvas API access token?

Account → Settings → Approved Integrations → New Access Token. Copy it immediately - it won't be shown again.

Can I create users without admin permissions?

No. User creation requires account-level admin access. Individual teachers can manage enrollments in their own courses.

What enrollment types are available?

StudentEnrollment, TeacherEnrollment, TaEnrollment, ObserverEnrollment, and DesignerEnrollment.

Can I enroll users by email instead of user ID?

Not directly. You need the user's Canvas ID or SIS ID. Search for the user first with the users API, then enroll by ID.

Summary

The Canvas API makes it straightforward to automate user creation, course setup, and enrollments. For quiz content, pair it with Formswrite to convert Google Docs into Canvas QTI packages - significantly faster than building quizzes through the API.

Turn your document into an LMS quiz

Convert a PDF, Word, or Google Doc into a Moodle, Canvas, or Blackboard quiz import.

Convert for your LMS

Or go straight to a converter: Google Docs to Forms, PDF to Google Form, Word to Google Form, Google Forms Quiz Generator


Share this post with your network

Back to Blog
Formswrite

Ask AI to compare Formswrite for you:

ChatGPTClaudeGeminiPerplexityGrok

Company

About usPricingContact usTerms of ServicePrivacy PolicyRefund PolicyAffiliate Program

Formswrite is the AI-powered form builder for educators, training centers, and businesses that need to convert documents into Google Forms, quizzes, and assessments without rebuilding from scratch. Upload a Google Doc, Word, PDF, image, or spreadsheet - Formswrite extracts the questions, structure, and grading rules, then exports to Google Forms, Canvas, Moodle, Kahoot, Quizizz, and more.

Trusted by educators, training teams, and HR departments worldwide. Formswrite's AI tools - quiz generator, worksheet generator, lesson-plan generator, rubric generator, and flashcard builder - are centralized in one platform.

Our brands

Docswrite logo

Docswrite

Zoral logo

Zoral

JobsPipe logo

JobsPipe

Parsley logo

Parsley

© 2026 Formswrite. All rights reserved.

Terms
Privacy
llms.txt
llms-full.txt