{"id":23819859,"url":"https://github.com/kth/canvas-api","last_synced_at":"2025-09-07T02:30:56.163Z","repository":{"id":13220554,"uuid":"73919340","full_name":"KTH/canvas-api","owner":"KTH","description":"Node.js API client for Canvas LMS. Based on Got","archived":false,"fork":false,"pushed_at":"2024-03-13T08:01:43.000Z","size":1424,"stargazers_count":18,"open_issues_count":2,"forks_count":5,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-04-14T04:06:13.274Z","etag":null,"topics":["javascript","kth-e-larande","nodejs","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KTH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-11-16T12:45:02.000Z","updated_at":"2024-03-02T21:49:19.000Z","dependencies_parsed_at":"2024-03-13T09:25:25.276Z","dependency_job_id":"45372ec5-0382-44a8-87ef-39451b9ecc8a","html_url":"https://github.com/KTH/canvas-api","commit_stats":{"total_commits":344,"total_committers":13,"mean_commits":26.46153846153846,"dds":0.6773255813953488,"last_synced_commit":"81320e83a9074ef3701de24e383b8212d2f0e787"},"previous_names":[],"tags_count":67,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fcanvas-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fcanvas-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fcanvas-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTH%2Fcanvas-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KTH","download_url":"https://codeload.github.com/KTH/canvas-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232163085,"owners_count":18481581,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","kth-e-larande","nodejs","typescript"],"created_at":"2025-01-02T07:16:06.154Z","updated_at":"2025-01-02T07:16:06.977Z","avatar_url":"https://github.com/KTH.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Canvas API (for TypeScript and JavaScript)\n\n```shell\nnpm i @kth/canvas-api\n```\n\nNode.JS HTTP client (for both TypeScript and JavaScript) for the [Canvas LMS API](https://canvas.instructure.com/doc/api/)\n\n## Getting Started\n\nFirst, generate a token by going to `«YOUR CANVAS INSTANCE»/profile/settings`. For example https://canvas.kth.se/profile/settings. Then you can do something like:\n\n```js\nconst canvasApiUrl = process.env.CANVAS_API_URL;\nconst canvasApiToken = process.env.CANVAS_API_TOKEN;\nconst Canvas = require(\"@kth/canvas-api\").default;\n\nasync function start() {\n  console.log(\"Making a GET request to /accounts/1\");\n  const canvas = new Canvas(canvasApiUrl, canvasApiToken);\n\n  const { body } = await canvas.get(\"accounts/1\");\n  console.log(body);\n}\n\nstart();\n```\n\nIn TypeScript, use `import`:\n\n```ts\nimport Canvas from \"@kth/canvas-api\";\n\nconsole.log(\"Making a GET request to /accounts/1\");\nconst canvas = new Canvas(canvasApiUrl, canvasApiToken);\n\nconst { body } = await canvas.get(\"accounts/1\");\nconsole.log(body);\n```\n\n## Concepts\n\n### 🆕 New from v4. SIS Imports\n\nThis package implements one function to perform SIS Imports (i.e. call the [POST sis_imports] endpoint).\n\n\u003e Note: this is the only function that calls a **specific** endpoint. For other endpoints you should use `canvas.get`, `canvas.requestUrl`, `canvas.listItems` and `canvas.listPages`\n\n[post sis_imports]: https://canvas.instructure.com/doc/api/sis_imports.html#method.sis_imports_api.create\n\n### `listItems` and `listPages`\n\nThis package does have pagination support which is offered in two methods: `listItems` and `listPages`. Let's see an example by using the `[GET /accounts/1/courses]` endpoint.\n\nIf you want to get all **pages** you can use `listPages`:\n\n```js\nconst canvas = new Canvas(canvasApiUrl, canvasApiToken);\n\nconst pages = canvas.listPages(\"accounts/1/courses\");\n\n// Now `pages` is an iterator that goes through every page\nfor await (const coursesResponse of pages) {\n  // `courses` is the Response object that contains a list of courses\n  const courses = coursesResponse.body;\n\n  for (const course of courses) {\n    console.log(course.id, course.name);\n  }\n}\n```\n\nTo avoid writing two `for` loops like above, you can call `listItems`, that iterates elements instead of pages. The following code does exactly the same as before. Note that in this case, you will not have the `Response` object:\n\n```js\nconst canvas = new Canvas(canvasApiUrl, canvasApiToken);\n\nconst courses = canvas.listItems(\"accounts/1/courses\");\n\n// Now `courses` is an iterator that goes through every course\nfor await (const course of courses) {\n  console.log(course.id, course.name);\n}\n```\n\n[get /accounts/1/courses]: https://canvas.instructure.com/doc/api/accounts.html#method.accounts.courses_api\n\n### Typescript support\n\nThis package does not contain type definitions to the objects returned by Canvas. If you want such types, you must define them yourself and pass it as type parameter to the methods in this library.\n\nFor example, to get typed \"account\" objects:\n\n```ts\n// First you define the \"Account\" type (or interface)\n// following the Canvas API docs: https://canvas.instructure.com/doc/api/accounts.html\ninterface CanvasAccount {\n  id: number;\n  name: string;\n  workflow_state: string;\n}\n\n// Then, you can call our methods by passing your custom type as type parameter\nconst { body } = await canvas.get\u003cCanvasAccount\u003e(\"accounts/1\");\n\nconsole.log(body);\n```\n\n### Error handling\n\nBy default, this library throws `CanvasApiError` exceptions when it gets a non-200 HTTP response from the Canvas API. You can catch those exceptions with any of the methods:\n\n```ts\nconst canvas = new Canvas(canvasApiUrl, \"-------\");\nconst pages = canvas.listPages(\"accounts/1/courses\");\n\ntry {\n  for await (const coursesResponse of pages) {\n    const courses = coursesResponse.body;\n\n    for (const course of courses) {\n      console.log(course.id, course.name);\n    }\n  }\n} catch (err) {\n  if (err instanceof CanvasApiError) {\n    console.log(err.options.url);\n    console.log(err.response.statusCode);\n    console.log(err.message);\n  }\n}\n```\n\n#### Shorter error objects\n\nBy default, `CanvasApiError` thrown by this library contains a property `response` with a very big object. If you would like to have a smaller `response` in the error object, you can modify the `errorHandler` property:\n\n```ts\nimport CanvasApi, { minimalErrorHandler } from \"@kth/canvas-api\";\nconst canvas = new CanvasApi(\"...\");\ncanvas.errorHandler = minimalErrorHandler;\n```\n\n#### Custom error objects\n\nYou can also pass a custom function in the `.errorHandler` property: that function will be called with whatever is thrown by `got`. Read more about [errors in Got here](https://github.com/sindresorhus/got/blob/main/documentation/8-errors.md)\n\nNotes:\n\n- Argument `err` in the custom handler will be the error thrown by `got`, so it will never be `CanvasApiError`\n- Make sure the function you pass never returns something.\n\nYou can use this function to create your own error objects:\n\n```ts\nimport CanvasApi from \"@kth/canvas-api\";\n\nconst canvas = new CanvasApi(\"...\");\n\ncanvas.errorHandler = function customHandler(err: unknown): never {\n  if (err instanceof HTTPError) {\n    throw new CustomError(`Oh! An error! ${err.message}`);\n  }\n\n  throw err;\n};\n```\n\n## Design philosophy\n\n1. **Do not implement every endpoint**. This package does **not** implement every endpoint in Canvas API This package also does not implement type definitions for objects returned by any endpoint nor definition for parameters. That would make it unmaintainable.\n\n2. **Offer \"lower-level\" API** instead of trying to implement every possible feature, expose the \"internals\" to make it easy to extend.\n\n   Example: you can use `.client` to get the `Got` instance that is used internally. With such object, you have access to all options given by the library [got](https://github.com/sindresorhus/got)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkth%2Fcanvas-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkth%2Fcanvas-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkth%2Fcanvas-api/lists"}