Obtaining a list of Admin Users with their Roles

Community Champion
13 9 6,552

On September 16, 2017, Canvas added an Admin CSV option to the Provisioning Report. It provides most of the information here and is built-into Canvas rather than being an external solution. It does require that you combine information from multiple tables to get human-friendly information for some of the values, so some people may still find this document useful. I've added a Method 0 to the document to include Canvas' report.

One request that has surfaced multiple times in the Community is how to quickly get a list of admin users and the roles those users have. On March 3, 2017,  @liuz21  asked it in Is there a quick way to get the user list for each admin role?. There,  @abunag  provided the standard answer of "I manually maintain this list" and that he did it for over 200 sub-accounts. Our institution is small and we know who our admins are, so I didn't realize the problem was that large. Anthony's solution is typical of what admins are forced to do, but neither encouraging nor a good use of his time. Obtaining the list automatically via a script sounded like something that could be done without too much hassle. My original mental estimate of an hour turned into a weekend and then that turned into about five days. The moral of the story is that you should never use the words "easy" when it comes to adding functionality to Canvas.

There's another moral to the story. After spending several days writing the script to do this, completing the documentation, and getting ready to publish the tool, I went looking for places in the Community that mentioned it and found that I had already written a Google Sheet script to do this back in December 2015. It showed me that I really need to do a better job of organizing my scripts because I'm forgetting which ones I've already written. It also points out the problem of finding things in the Community -- items buried within a question or feature request are harder for people to find than a document. Sometimes, even the person who wrote it forgets that he wrote something. But it also may have been why I thought this wouldn't be too bad in the first place -- I had already done it once.

Method 0: Use the Admin CSV option from the Provisioning Report

When I wrote this script, there was nothing built into Canvas that would provide the information. The September 16, 2017, production release of Canvas added the ability to download the Admin CSV file for an account or a sub-account. This mostly obsoleted the information that I have in this document.

The provisioning reports are designed to provide the information necessary so that you could recreate the accounts. We often take the information and reassemble it into a more useful form. This means looking up Canvas IDs from one table and tying them to a value in another table.

For example, if you want the name of the (sub)account, you have to take the canvas_account_id in the Admins CSV file and link it to the canvas_account_id in the Accounts CSV and then you can get the human-friendly name from the name field of the Accounts CSV report.

But the good news is that it's now built into Canvas! For those who want a report that brings in that extra information automatically, then the information from the original document may be helpful.

Method 1: Download link inside Canvas

This method adds a button that will generate a CSV file that you can open in Excel that will contain a list of the admin accounts and the roles that they have. By default, the CSV file contains (in this order): the account name, the user name, user role within that account, login ID, sortable name, Canvas account ID, Canvas user ID, Canvas role ID, SIS user ID, SIS login ID, SIS account ID, and Canvas parent account ID.

CSV File


Here are the quick install steps for those who don't want to read the full instructions.

  1. Install the Tampermonkey browser extension.
  2. Install the List Admin Roles user script.

How to Use

The script adds a button to the main Admin People page for your account and sub-account. These are the pages that you get to by going to Admin and choosing People or by clicking on Sub-Accounts from the Admin page and choosing People.

Location of item on menu

When you see the "List Account Admins", you click it and wait. How long you wait depends on how many sub-accounts and admin users you have.

It attempts to gather information for all sub-accounts of whichever account page you are viewing when you click the button. This means that you can get the admin list for all of your sub-accounts or you can go to a specific account and then get all of the admin users for just that sub-account.

Grouping and Sorting

The information is grouped based off the account hierarchy that you have specified. The primary sorting and grouping of the information in the report matches what you get when you click on the Sub-Accounts link from the account admin page.

It starts with the root account, where root in this case means whichever account or sub-account you were viewing when you clicked the button. All of the admins for that (sub)account are listed first and then any sub-accounts for that account come next in alphabetical order.

Within each account or sub-account, the users are listed alphabetically by the sortable name (if available) or their name. 

If an account does not have any admins in it, then it is not listed in the report. In other words, this is not a list of your sub-accounts, this is a list of users and what roles they have.

Custom URLs

If you do not use a custom URL, then you should not have to change anything to make the script work. By default, it is is setup to recognized *.instructure.com sites, including test and beta instances. However, if you are using a custom URL then you will need to modify line 5 of the code.

// @include     /^https://.*\.instructure\.com/accounts/[0-9]+$/‍‍‍‍‍‍‍‍

This is a regular expression that tells it which pages to run on. To make sure that it doesn't run on sub-pages within your admin pages, I make sure that it has just an account number at the end. This means that I need to match based on a regular expression instead of the wildcard * that other scripts use. In regular expressions, dots have special meanings, so if you want use a dot, you need to escape it with a backslash. If you want canvas.site.edu, you need to enter it as canvas\.site\.edu.

The following include line would match canvas.site.edu, canvas.test.site.edu, and canvas.beta.site.edu:

// @include     /^https://canvas(\.test|\.beta)?\.site\.edu/accounts/[0-9]+$/‍‍‍‍‍‍‍‍

Deciding what to include

By default, the report includes the account name, user name, user role, login ID, sortable name, Canvas account ID, Canvas user ID, Canvas role ID, SIS user ID, SIS login ID, SIS account ID, and Canvas parent account ID. However, all of this is configurable using the variable reportFields at the top of the code.

Here's an abbreviated section of code.

var reportFields = [ {
'name' : 'Account',
'src' : 'a.name'
}, {
'name' : 'Name',
'src' : 'u.name'
}, {
'name' : 'Role',
'src' : 'r.role'

The order that the information is listed in the CSV export is the order that they are listed in the reportFields array.

Each entry in the array is an object that contains a name and a source (src). The name is the heading that will appear in the report and the defaults have no spaces to assist with other software like R that doesn't like a space in the heading. The source for the information is made up of two parts, separated by dot. The first part is an abbreviation for the object that contains it and could be the a for account, r for role, or u for user. The part after the dot is the field that is returned via the API field.

Here is a list of the available information.

  • User: id, integration_id, login_id, name, short_name, sis_import_id, sis_login_id, sis_user_id, sortable_name
  • Role: id, role
  • Account: default_group_storage_quote_mb, default_storage_quota_mb, default_time_zone, default_user_storage_quota_mb, id, name, parent_account_id, root_account_id, workflow_state

Here are some notes on the available information.


  • The email is not available through those requests, it would need a separate API call for each user that was an admin and that could take a while.
  • For us, there's not much difference between short name and name, so I just went with name. The sortable_name is "Last, First" so it becomes sortable by last name.


  • There is actually more information available about the roles than what is provided. However, that was going to require an additional API call for each role or multiple calls to fetch all the roles for an account and then repeating that for different accounts. The List roles API had a query parameter to fetch information about roles that were created in a parent account, but not one to fetch role information for all sub-accounts, which is what would have made this really nice.


  • There's a lot of stuff regarding storage quotas here. I didn't see how that was germane to this report.
  • The parent_account_id and root_account_id could be used to establish some kind of hierarchy of sub accounts, but I figured that most people knew what their hierarchy is and indenting in the spreadsheet to reflect that isn't really a viable option.
  • The workflow_state is used as a filter on 'active', so displaying it doesn't accomplish anything.

Behind the Scenes

You do not need to understand this section to use it. This is for those who want to take it and go further with it.

When I first started this, I though there were basically three API calls that needed made. When it was finished, there were still three, although some of them were different than what I had originally thought. The process is simpler and faster, but provides less information than was possible. The only noticeable change was "Account Admin" became "AccountAdmin" in the report.

API Calls

  • Get a single account from the Accounts API. This returns the account information for the account that the admin is viewing when they click the button
  • Get the sub-accounts of an account from the Accounts API. This returns all of the sub-accounts, but it does not return information on the account itself, which is why the call to get a single account was needed as well. Be sure to specify recursive=1 in the query parameters to get all of the sub-...-sub-accounts.
  • List account admins from the Admins API. This call needs made for every account and sub-account that you have. It includes basic role information for each user, which saves having to make additional calls for the role information.

Method 2: Google Sheet

This is the documentation for the December 9, 2015, version of a Google Sheet that I wrote.

It doesn't provide as much information and it doesn't allow you to specify which sub-accounts to get the list for. It doesn't do any sorting, although it still probably groups by sub-account. It was something quick I threw together one morning.

Google Sheet CSV File


  1. Open up the Google Spreadsheet: List Canvas Admins
  2. This will open the spreadsheet in view-only mode, you need to make your own copy. Go to File > Make a Copy.
  3. There will be new Menu item called "Canvas". It contains the menu. The first thing to do is choose "Configure API Settings". It will ask for authorization. Then put in the hostname of your Canvas instance and an API access token - How do I obtain an API access token for an account?
  4. After you configure that, go to the Canvas menu again and choose either "List All Admins" or "List Only Sub-Account Admins"
  5. Watch the magic occur on a new sheet called "Admins"

Course-level roles are not included

The code here uses API calls that return list of admins for an account. That means that if you have a course-level role it will not show up in this report. Those roles are based on enrollments so you would need to look at every enrollment for every user in every course to see which ones have special roles.

You can obtain course role enrollment data through Canvas Data or through the Provisioning Report from the Admin > Settings > Reports screen. The Canvas Data approach requires extra setup and the information is not live. The Provisioning Report is live when the report was generated, but it runs and then emails you once it's ready.

Neither of these approaches is suitable for invocation through a button in a web browser, were people expect immediate results, or a Google sheet, where there is a script timeout of 5 minutes.

Community Champion

I moved the button to the People page instead of the Courses page. Canvas moved things around with the December 9, 2017, release and the script stopped working. Yesterday, the FileSaver.js changed and broke compatibility with Tampermonkey and someone let me know. While I was fixing the FileSaver issue, I noticed the other and fixed them both at the same time.

Community Champion

Just for the sake of clarification - does this return the same results as the Admin CSV that was added to Provisioning reports in September?

Community Champion


They're mostly the same and I'm good with people using Canvas' report and I am not trying to compete or duplicate.

I wrote this before Canvas had their thing, so there was a need at the time, and I kind of thought it was abandoned after Canvas added the Admin CSV portion, but someone sent me an email this morning saying the script no longer worked. So I updated it to work and since I moved the location, I thought I should update the instructions to match. I should probably update the document to make mention that Canvas now has this built in.

In case someone is wondering whether or not to keep my script around, here are the differences in the reports:

  • Mine lists the name of the (sub)account while Canvas only provides the account ID.
  • Mine lists the name (James Jones) and sortable name (Jones, James) of the user while Canvas only lists the name.
  • Mine provides the Login while Canvas does not.
  • Mine lists the parent account ID for sub-accounts while Canvas does not.
  • Canvas lists the status of all of the admins, including deleted ones, while mine only lists the active ones
  • Canvas includes whether or not it was created by SIS. We both give the SIS IDs although the naming scheme is different.

Canvas makes most (if not all) of the information that I provide available in other provisioning reports, mine just attempts to pull it all into one place to save having to do lookups across multiple tables.

Mine is relatively immediate assuming you've got the script already loaded while you have to wait for the report to be generated and the link emailed by Canvas. On the other hand, Canvas' approach is built in and mine is something the user has to install.

Community Champion

This is a very helpful comparison. Your solution definitely has added value (subaccount name, in particular).

Community Champion

 @James  another great post, thank you.

I have recently been asked to buid a hierarchy of "Department Chairs", and came across this article while looking to see what others have done.

The Admin report almost works, but it does not show the hierarchy between sub-accounts.

For example, the primary "Admin" role in the root account is applied to all sub-accounts below it.  It will be up to you to keep track of that inheritance and handle it in your lookup table.  This is simple for the root account, but as you get into nested sub-accounts it isn't as clear regarding which admin's have access to additional nested sub-accounts.  In other words when you make the API call for a sub-account it does not return admins for the account above the sub-account, which doesn't give you a full picture of who has admin access to that sub-account.  Who else has access based on inheritance? 

It is possible to use recursion to traverse all accounts and sub-accounts to get all admins for each department (sub-account).  Reults do include custom account roles that you have created.  Create a lookup table to keep a record of each sub-account and associated admins, and fill in that lookup table as you traverse the sub-account tree.  Doing this I was able to record an admin for a sub-account, then relate that admin to all associated sub-accounts, giving me a more complete picture of who had admin access to which sub-accounts.

In most cases I think the report is sufficient, but it is possible to get more detail with the API.  Granted, this was a special case, but maybe it will help someone.

Community Champion

Hi  @garth ,

I can't remember if I considered inheritance when I wrote it or not. I don't think we would want it at our school, but we're small enough that all of the admins are known and we wouldn't want the top level admins to filter down and be displayed for every sub-account that we had. I can certainly see where some people would want that, though. 

Thanks for sharing the information for those who want it that way.

Community Participant

I am correct that this script no longer works since Canvas updated their UI, or am I doing something wrong?

Community Champion

Are you talking about the script in method 1 or the google sheet script in method 2? When Canvas came out with their own thing (Method 0), I kind of stopped paying attention to either of my solutions to know if they still work or not.

The Google Sheet solution shouldn't depend on the UI. The Userscript definitely could break because of UI changes.

Community Participant

@James Thanks for your reply.

I was referring to the Tampermonkey script.  I like the idea that the subaccount names would be included without any additional effort.  But I do see that Canvas's built-in Provisioning Report is a viable option also.

Thank you.