# Canvas LMS Export & Backup (`plenteous_humidifier/canvas-complete-archive`) Actor

Export and back up authorized Canvas LMS courses through the official API. Archive modules, pages, files, assignments, discussions, quizzes, enrollments, and submissions with secure tokens and an audit manifest.

- **URL**: https://apify.com/plenteous\_humidifier/canvas-complete-archive.md
- **Developed by:** [Luigy Gabriel](https://apify.com/plenteous_humidifier) (community)
- **Categories:** Automation, Developer tools, Integrations
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 archived canvas resources

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Canvas LMS Export & Backup

Back up the Canvas LMS content you are authorized to access through the official, read-only Canvas REST API. This Actor exports structured records to an Apify dataset, writes a detailed audit manifest to the private key-value store, and can optionally download course files.

Use it to preserve coursework before account closure, back up teaching material, audit a migration, or build an authorized Canvas data pipeline without maintaining your own integration.

### What you can export

- Course metadata, term information, and syllabus
- Modules and module items
- Pages and page bodies
- File metadata and optional file bodies
- Assignments, descriptions, and rubrics
- Discussion topics and visible entries or replies
- Announcements
- Classic quizzes and visible questions
- Enrollments
- Submissions, grades, comments, rubric assessments, and submission history

Canvas always applies the permissions of the supplied token. The Actor does not bypass authentication, availability dates, course permissions, or institutional controls.

### Quick start

1. In Canvas, open **Account → Settings → Approved Integrations → New Access Token**.
2. Create a short-lived token with the minimum permissions needed for your archive.
3. Enter your institution's Canvas URL without `/api/v1`.
4. Add one or more course IDs, or leave the list empty to discover visible courses.
5. Select the resources and run the Actor.

Example:

```json
{
  "canvasBaseUrl": "https://school.instructure.com",
  "apiToken": "YOUR_SCOPED_CANVAS_TOKEN",
  "courseIds": ["12345"],
  "resources": [
    "modules",
    "pages",
    "files",
    "assignments",
    "discussions",
    "announcements",
    "quizzes"
  ],
  "downloadFiles": false,
  "maxCourses": 10
}
```

For instructor- or administrator-authorized personal data:

```json
{
  "canvasBaseUrl": "https://school.instructure.com",
  "apiToken": "YOUR_SCOPED_CANVAS_TOKEN",
  "courseIds": ["12345"],
  "resources": ["assignments", "enrollments", "submissions"],
  "submissionScope": "all",
  "acknowledgeSensitiveData": true
}
```

Selecting `submissionScope: "all"` never grants additional Canvas permissions. It only requests records already visible to the authenticated user.

### Results

The default dataset contains:

- one `course` record per archived course;
- one record per visible module, page, file, assignment, discussion, announcement, quiz, enrollment, or submission;
- one final `run-summary` record.

The private key-value store contains:

- `ARCHIVE_MANIFEST`: totals and completion status for every course/resource pair;
- `FILE_*`: optional binary file bodies when `downloadFiles` is enabled.

The run can succeed with partial resource errors. For example, a student token may be allowed to read assignments but receive `403` for the course file index. Check `ARCHIVE_MANIFEST` to distinguish completed, empty, and permission-restricted resources.

### Security and privacy

- `apiToken` is a secret input encrypted by Apify.
- The token is sent only to the configured Canvas origin.
- The token is never written to datasets, manifests, or logs.
- Cross-origin file downloads never receive the Canvas authorization header.
- Signed URL query parameters are removed from structured output by default.
- Literal localhost and private-network targets are rejected.
- File size, course count, record count, concurrency, timeout, and retry limits are configurable.
- Enrollments and submissions require explicit sensitive-data acknowledgment.

Use short-lived, scoped tokens and revoke them after one-off archives. Keep datasets and key-value stores private, use appropriate retention settings, and follow your institution's policy plus applicable privacy law such as LGPD, GDPR, or FERPA.

### File downloads

By default, the Actor exports file metadata only. Enable `downloadFiles` to save authorized file bodies to the run's private key-value store. `maxFileSizeMb` limits each download and oversized files are reported as skipped in the manifest.

For large institutional archives, prefer customer-owned object storage and short Apify retention periods.

### Common questions

#### Why did a resource return 403 or 404?

Canvas permissions differ by role, course, institution, and resource type. A partial failure normally means that the supplied account cannot access that endpoint. Other authorized resources continue exporting unless `failOnResourceError` is enabled.

#### Does this create an `.imscc` Common Cartridge?

Not yet. Canvas creates Common Cartridge exports through a write operation and an asynchronous export job. This Actor intentionally remains API read-only.

#### Are New Quizzes included?

Classic quiz questions are exported when visible. New Quizzes use a separate API and are not included in this release.

#### Can it restore a course?

This release exports and audits data; it does not write back to Canvas.

### Current limitations

- LTI tools, externally hosted videos, publisher content, and data hidden from the token cannot be archived.
- File bodies are separate key-value records rather than one ZIP file.
- Runs do not yet checkpoint and resume across platform migrations.
- Institutional Canvas administrators can restrict personal access tokens entirely.

### Authorization

Use this Actor only with accounts and data you are authorized to access. You are responsible for institutional approval, retention, sharing, and regulatory compliance.

# Actor input Schema

## `canvasBaseUrl` (type: `string`):

Your institution's HTTPS Canvas URL, for example https://school.instructure.com. Do not include /api/v1.

## `apiToken` (type: `string`):

A scoped Canvas access token. Apify stores this input encrypted.

## `courseIds` (type: `array`):

Optional Canvas course IDs. Leave empty to archive visible courses up to the course limit.

## `includeConcludedCourses` (type: `boolean`):

When course IDs are empty, include both active and completed courses.

## `maxCourses` (type: `integer`):

Safety limit when selecting courses automatically.

## `resources` (type: `array`):

Course resources to collect. Enrollments and submissions contain personal data and require explicit acknowledgment.

## `submissionScope` (type: `string`):

Export only the authenticated student's submissions or all visible submissions. The all option requires instructor/admin permissions.

## `acknowledgeSensitiveData` (type: `boolean`):

Required when exporting enrollments or submissions. You are responsible for institutional approval and applicable privacy law.

## `downloadFiles` (type: `boolean`):

Save authorized Canvas files to the run's private key-value store. Otherwise, only file metadata is exported.

## `maxFileSizeMb` (type: `integer`):

Skip individual files larger than this limit.

## `maxRecordsPerResource` (type: `integer`):

Per-course cap for each resource type.

## `requestConcurrency` (type: `integer`):

Number of resource groups fetched in parallel per course.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each Canvas API request.

## `maxRequestRetries` (type: `integer`):

Retry count for rate limits, server errors, and temporary network failures.

## `failOnResourceError` (type: `boolean`):

Stop the run when one resource is unavailable instead of recording the failure in the manifest.

## `preserveUrlQueryParameters` (type: `boolean`):

Disabled by default so signed download parameters are not persisted in datasets.

## Actor input object example

```json
{
  "courseIds": [],
  "includeConcludedCourses": true,
  "maxCourses": 10,
  "resources": [
    "modules",
    "pages",
    "files",
    "assignments",
    "discussions",
    "announcements",
    "quizzes"
  ],
  "submissionScope": "self",
  "acknowledgeSensitiveData": false,
  "downloadFiles": false,
  "maxFileSizeMb": 50,
  "maxRecordsPerResource": 5000,
  "requestConcurrency": 4,
  "requestTimeoutSecs": 60,
  "maxRequestRetries": 3,
  "failOnResourceError": false,
  "preserveUrlQueryParameters": false
}
```

# Actor output Schema

## `results` (type: `string`):

One dataset item per Canvas resource plus a final run summary.

## `manifest` (type: `string`):

Counts, failures, downloaded file totals, and security flags.

## `files` (type: `string`):

Private key-value store records whose keys begin with FILE\_.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("plenteous_humidifier/canvas-complete-archive").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("plenteous_humidifier/canvas-complete-archive").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call plenteous_humidifier/canvas-complete-archive --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=plenteous_humidifier/canvas-complete-archive",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/ys2PK7K2RewsLeJcX/builds/Lj1yP6bdlrTgdm0Uv/openapi.json
