The Instructure Community will enter a read-only state on November 22, 2025 as we prepare to migrate to our new Community platform in early December.
Read our blog post for more info about this change.
Found this content helpful? Log in or sign up to leave a like!
I am building an external tool that helps teachers and TAs coordinate who is grading what in classes with hundreds of students. The way I've currently been getting ungraded submissions is by requesting all submissions for an assignment and then iterating through that list and looking for submissions without scores.
I've run into some trouble however, because since we have so many students in the course, each assignment has hundreds of submissions, and I'll have to use pagination in order to get all of the data I need to do it this way. This seems like an unreasonable amount of API requests to make over and over again, (roughly 40 each time my tool refreshes).
Is there a method in the API that returns only submissions that do not have scores?
Solved! Go to Solution.
howderek, following up on @garth 's post, there is no "one-stop-shop" for this. You can use the List assignments API with the bucket parameter set to "ungraded" to get a list of assignments with ungraded submissions. Then cycle through the results and pull the submissions for each of those assignments using the List assignment submissions API. Lastly, filter those results down to only those with a grade value of null.
A mock-up for the logic would be something like:
ungradedAssignments = GET /api/v1/courses/:course_id/assignments?bucket=upgraded
ungradedSubmissions = new Array
FOREACH ungradedAssignments AS ungradedAssignment
submissions = GET /api/v1/courses/:course_id/assignments/ && ungradedAssignment[id] && /submissions
FOREACH submissions AS submission
IF submission[grade] IS NULL
APPEND submission TO ARRAY ungradedSubmissions
END IF
END FOREACH
END FOREACH
Note: This is a rough-sketch pseudocode. The end result would be a single array, ungradedSubmissions, of all ungraded activity submissions for a course , regardless of the activity they belong to. Of course, each submission will contain the assignment_id, it should be easy to pair with the actual assignment, should you want to prettify the output.
Take a look at this API call:
Specifically the Request Parameters, look at the bucket parameter which accepts a value of ungraded:
| bucket | string | If included, only return certain assignments depending on due date and submission status. Allowed values: |
Let us know if this gets what you are after.
This does not solve the issue I have because this returns the assignments with ungraded submissions but does not return the ungraded submissions themselves, even if I add ?include=submission to the query string.
I appreciate the comment, however ![]()
Seeing as Canvas does not currently expose an API call to allow you to make a single request to download all submissions for a single assignment, along with necessary filters for graded vs. ungraded etc., you will likely end up looping and making multiple calls.
The approach I have taken in this scenario (not specifically for submission artifacts) is to use a workflow that I can throttle. In other words, have an asynchronous task that runs in the background where you can control how fast/slow it runs, control the frequency of API calls if you are concerned about exceeding the allowed threshold. Have the task send an email/text when complete and you can collect the results at that time.
In the meantime, you might consider starting an idea.
This one has been archived, but you may be able to get this group interested and voting on your idea:
It is not exactly the same, but I believe the goal is similar: one request to download bulk content instead of iterating and making multiple calls.
These ideas are very similar to what you are wanting, but is also archived:
There are other ideas that are in the same neighborhood as what you want. If you start a new idea, reach out to those following the other ideas and see if you can get them to support your idea. I definitely see value in what you are trying to accomplish, let me know if you create an idea and I'll definitely support it.
howderek, following up on @garth 's post, there is no "one-stop-shop" for this. You can use the List assignments API with the bucket parameter set to "ungraded" to get a list of assignments with ungraded submissions. Then cycle through the results and pull the submissions for each of those assignments using the List assignment submissions API. Lastly, filter those results down to only those with a grade value of null.
A mock-up for the logic would be something like:
ungradedAssignments = GET /api/v1/courses/:course_id/assignments?bucket=upgraded
ungradedSubmissions = new Array
FOREACH ungradedAssignments AS ungradedAssignment
submissions = GET /api/v1/courses/:course_id/assignments/ && ungradedAssignment[id] && /submissions
FOREACH submissions AS submission
IF submission[grade] IS NULL
APPEND submission TO ARRAY ungradedSubmissions
END IF
END FOREACH
END FOREACH
Note: This is a rough-sketch pseudocode. The end result would be a single array, ungradedSubmissions, of all ungraded activity submissions for a course , regardless of the activity they belong to. Of course, each submission will contain the assignment_id, it should be easy to pair with the actual assignment, should you want to prettify the output.
I'm not sure why I didn't think of this before, have you looked at the data portal?
It seems to me you could use the raw data to determine which submissions have been graded / not graded, as well as which ones had files associated with them, resulting in a list of file id's of interest.
Take a look at the Canvas Data Portal link in your Admin tool bar.
In the right menu, click on the Schema Docs to get details of each table.
Then you would only have to use the file API to execute the download for each file you wanted:
Canvas LMS REST API Documentation - Get File
This would produce a huge savings in the number of API calls you would have to make.
I have not gone through the steps to define the exact fields you should use, but if you start with the file_dim you should be able to work your way backwards to the submission and assignment to design the logic.
I considered using the data portal but I would prefer to work with real-time data because the purpose of my application is to coordinate who is grading what, so it's very important that I know what has been graded as it is graded, and I would prefer to save the trouble of managing a database between the Canvas data and the client application. Great suggestion though, thank you!
Totally understand the need for real time data, your point is very valid. The delay in data through the data portal is important to keep in mind.
Great point.
Community helpTo interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign inTo interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign in