Typed TypeScript wrapper for Canvas LMS REST API endpoints accessible with a student-scoped access token. Zero runtime dependencies — uses native fetch.
npm install canvas-student-apiRequires Node.js 18+ or a modern browser with native fetch support.
import { CanvasClient } from 'canvas-student-api';
const canvas = new CanvasClient({
baseUrl: 'https://myschool.instructure.com',
token: 'your-student-access-token',
});
// List your courses
for await (const course of canvas.courses.list()) {
console.log(course.name);
}
// Get a specific assignment
const assignment = await canvas.assignments.get(courseId, assignmentId);
console.log(assignment.name, assignment.due_at);
// Collect all planner items as an array
const items = await canvas.planner.listItems({
startDate: '2026-03-01',
endDate: '2026-03-31',
}).toArray();const canvas = new CanvasClient({
baseUrl: 'https://myschool.instructure.com', // required
token: 'your-access-token', // required
perPage: 50, // optional, default: 100
fetch: customFetchFn, // optional, for testing/custom transports
});All list methods return an AsyncIterable<T> with a .toArray() convenience method. Single-item methods return a Promise<T>.
| Domain | Property | Methods |
|---|---|---|
| Courses | canvas.courses |
list, get, listUsers, getActivityStream, getActivityStreamSummary, listTabs, listFavorites, getSettings |
| Assignments | canvas.assignments |
list, get, listForUser, listGroups, listPeerReviews |
| Submissions | canvas.submissions |
list, get, create, uploadFile, uploadCommentFile |
| Modules | canvas.modules |
list, get, listItems, getItem |
| Pages | canvas.pages |
list, get, listForGroup, getForGroup |
| Discussions | canvas.discussions |
list, listForGroup, listEntries, createEntry, createReply |
| Quizzes | canvas.quizzes |
list, get, listSubmissions, getSubmission, listQuestions |
| Files | canvas.files |
listForCourse, listForFolder, listForUser, get, listFolders, getFolder |
| Calendar | canvas.calendar |
listEvents, listUserEvents, get |
| Planner | canvas.planner |
listItems, listOverrides, getOverride, createOverride, updateOverride, deleteOverride, listNotes, getNote, createNote, updateNote, deleteNote |
| Conversations | canvas.conversations |
list, get, create, addMessage |
| Users | canvas.users |
getProfile, get, listTodoItems, listUpcomingEvents, getActivityStream, getActivityStreamSummary, listBookmarks, getBookmark, listCourseNicknames, listGradedSubmissions, listNotificationPreferences |
| Groups | canvas.groups |
list, get, getActivityStream, getActivityStreamSummary, listMembers |
| Enrollments | canvas.enrollments |
listForCourse, listForUser, get |
| Announcements | canvas.announcements |
list, listAccountNotifications, getAccountNotification, closeAccountNotification |
API errors throw a CanvasApiError with structured details:
import { CanvasApiError } from 'canvas-student-api';
try {
await canvas.courses.get(999);
} catch (err) {
if (err instanceof CanvasApiError) {
console.error(err.status); // 404
console.error(err.statusText); // "Not Found"
console.error(err.url); // request URL
console.error(err.body); // parsed JSON error body from Canvas
}
}All list endpoints use Canvas Link header pagination automatically:
// Iterate page by page (memory efficient)
for await (const course of canvas.courses.list()) {
process.stdout.write('.');
}
// Or collect everything at once
const allCourses = await canvas.courses.list().toArray();MIT