Community Member

Assignments buckets broken? Finding unsubmtted?

I'll start with a very specific question with an example:

How exactly are the buckets computed?  What are the actual values being used to choose something for the unsubmitted bucket?  I can't find info on this...look at my reference section below for all I've found.

As an example to reinforce my question,  Why is the following assignment not showing up when I request unsubmitted bucket when it appears to be a valid unsubmitted assignment.  (Coincidentally, it does show up on Dashboard List view on the due date, but doesn't show anywhere on the calendar...related?):


    "id": 691750,
    "description": "",
    "due_at": "2020-09-28T04:59:59Z",
    "unlock_at": "2020-09-16T05:00:00Z",
    "lock_at": "2020-09-28T04:59:59Z",
    "points_possible": 100,
    "grading_type": "points",
    "assignment_group_id": 72079,
    "grading_standard_id": null,
    "created_at": "2020-09-16T18:16:39Z",
    "updated_at": "2020-09-16T20:56:30Z",
    "peer_reviews": false,
    "automatic_peer_reviews": false,
    "position": 20,
    "grade_group_students_individually": false,
    "anonymous_peer_reviews": false,
    "group_category_id": null,
    "post_to_sis": true,
    "moderated_grading": false,
    "omit_from_final_grade": false,
    "intra_group_peer_reviews": false,
    "anonymous_instructor_annotations": false,
    "anonymous_grading": false,
    "graders_anonymous_to_graders": false,
    "grader_count": 0,
    "grader_comments_visible_to_graders": true,
    "final_grader_id": null,
    "grader_names_visible_to_final_grader": true,
    "allowed_attempts": -1,
    "secure_params": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..tto7HMlkxBn0LE0NjBeGlEopongCj9zPHlv0DL2BgCk",
    "course_id": 41166,
    "name": "ckla 23.2 Adjectives 9/21",
    "submission_types": [
    "has_submitted_submissions": false,
    "due_date_required": true,
    "max_name_length": 30,
    "in_closed_grading_period": false,
    "is_quiz_assignment": false,
    "can_duplicate": false,
    "original_course_id": null,
    "original_assignment_id": null,
    "original_assignment_name": null,
    "original_quiz_id": null,
    "workflow_state": "published",
    "external_tool_tag_attributes": {
        "url": "",
        "new_tab": false,
        "resource_link_id": "e4ccdc12f13a78d8ebb1b27f45237e7e5f695445",
        "external_data": "",
        "content_type": "ContextExternalTool",
        "content_id": 58
    "muted": true,
    "html_url": "",
    "url": "",
    "published": true,
    "only_visible_to_overrides": false,
    "locked_for_user": false,
    "submissions_download_url": "",
    "post_manually": false,
    "anonymize_students": false,
    "require_lockdown_browser": false




I'm trying to write a script for myself and other parents at my school because it is simply too difficult for our elementary grade children to find all their assignment, especially unsubmitted ones.  Idiosyncrasies like the above make me question that the APIs are returning the true number of assignments the kids need to do as I see things in their dashboards that contradict what the API returns like the above.

When I query for:






it returns an empty list:






even though there is a published assignment showing in their dashboard a week away they have not submitted. 



According to the docs, the assignments API call(s):


GET /api/v1/courses/:course_id/assignments


is supposed to support the following buckets:

If included, only return certain assignments depending on due date and submission status.

Allowed values:past, overdue, undated, ungraded, unsubmitted, upcoming, future


However there is no description of how these are computed.  I found this page which describes some of them:

  • Overdue Assignments: assignments and discussions that are past the due date, are still available, have not been submitted, and have not been graded.
  • Upcoming Assignments: assignments, discussions, and quizzes that have an upcoming due date.
  • Undated Assignments: assignments, discussions, and quizzes that do not have a due date.
  • Past Assignments: assignments and discussions that are past the due date and either are not available, have been submitted, or have received a grade; quizzes that are past the due date.

But many are not discussed, including unsubmitted.  

So, How exactly are these buckets computed?

Labels (2)
0 Kudos
5 Replies
Community Champion

I've done some work that relies on missing assignments and going through the Assignments endpoint has proved tricky. I think the submission field is looking at whether or not there have been any submissions, not returning students who have not submitted.

It's much more reliable to go through the Submission endpoint to get that kind of information. Instead of looking at assignments and trying to figure out who hasn't submitted, query the Submission endpoint for all students (or individuals if you have a list of their IDs already) and filter by submission status.


GET /api/v1/courses/:course_id/students/submissions?workflow_state=unsubmitted&student_ids[]=all&grouped=true


Note that you have to specify 'all' in the student_ids[] param or else only your missing assignments are returned. The grouped param returns by User object rather than a flat list of missing assignments.

0 Kudos
Community Member

Thanks.  Not exactly what I was looking for, but hopefully you can be of some assistance.

First, it sounds like there is *no* published documentation as to how this really works?  We are both making some assumptions as to how/what that unsubmitted bucket it supposed to do, but no one from Canvas wants to actually tell us?

Next, to be clear I'm writing this script from the perspective of a single student.  So I am logged in with a token with just the authority to see assignments for one student - and that is what I want.  To me, the unsubmitted bucket for the currently authenticated token should show any published assignments without a submission.

What I have found myself having to do is something along these lines:

  • Enumerate all courses
  • For each course list all assignment.  Here I was already using the ?include=submission which was providing some more fields to look at
  • For each assignment I need to do a lot of hand-work.  There are tons of fields that seem to provide conflicting info.  Part of the issue is our teachers don't have a good grasp on managing canvas and necessarily keeping their house in order.  So not everything I get back will be a genuine assignment.  We need to check to make sure it is actually published, unlocked, has no submissions from my user, etc.  It seems there are 2 or 3 fields for each of these in different areas and I can't work out which one is which at this point.

In essence, what I am trying to accomplish is a view that combines a list of all assignments (like Grades does), but actually shows full submission and date details and does this in a single view for all course.

0 Kudos
Community Member

Here is another part of the problem I'm dealing with trying to find this out.  The API documentation seems to be incomplete/incorrect, so I'm not sure how we are supposed to reliably do *anything*

0 Kudos
Community Champion

I hear you on the manual processing.

Since the assignments endpoint isn't returning buckets correctly (I confirmed with a dummy class today signed in as a student) you can still do the same by gathering all submissions and then culling the list based on the submission workflow status and then submission history. 

This example is using Python to process because there's really good library I lean on to do the API calls.

from config import PROD_URL, PROD_KEY
from canvasapi import Canvas

def get_course(canvas, id):
    course = canvas.get_course(id)
    return course

def get_my_missing(submissions):
    # Take all submissions and interpolate a list of missing work
    missing = [item.assignment['name'] for item in submissions if
               item.workflow_state == "unsubmitted" and 
               item.excused is not True and 
               item.submitted_at is None

    return missing

def main():
    # set up the Canvas object
    canvas = Canvas(PROD_URL, PROD_KEY)

    # get the user's course
    course_id = input('What course are you looking for? ')

    course = get_course(canvas, course_id)

    # The endpoint looks for assignment IDs. If you don't supply any, it gets
    # submissions for every assignment in the class.
    # Include the "assignment" param to get the assignment name easily.
    # Include the "submission_history"
    submissions = course.get_multiple_submissions(include=["assignment"])

    missing = get_my_missing(submissions)

    # Display the assignment name
    for assignment in missing:

if __name__ == "__main__":


Community Member

Hello, I was wondering if you found a solution to this. I have the same problem where I want a bucket that only shows upcoming assignments, but some assignments which are upcoming show up while others don't.


0 Kudos