For Developers

Resolving Duplicate Assignments

In order to preserve our general rostering abstraction, Edlink implements some rather unusual behavior when it comes to rostering from Canvas and Schoology. In these systems, course sections (what we call classes) may be joined together under a single "course". When syncing "courses" from these systems, Edlink splits them back up into their original sections.

There are numerous reasons for this, some of which are discussed in our Deprecating Sections document.

Unfortunately, with the good comes the bad, and this introduced some challenges for teachers who frequently merged sections together in their LMS.

The Problem

When a teacher assigns work to a single class via our API, Edlink creates the corresponding assignment in the LMS. However, when a teacher assigns work to multiple classes, Edlink creates a separate assignment for each class. What they expect to see (at least when creating work via their LMS UI) is a single assignment that is shared across all sections.

The user experience for students was typically unaffected as students cannot see coursework that was not explicitly assigned to them. However, teachers were often confused by the behavior and so we decided to make an improvement.

Assigning Coursework to Multiple Classes

There were a number of considerations that we had to take into account when designing this feature:

  • How will assignment IDs be handled?
  • Will we allow teachers to set different due dates for each class?
  • What exactly will happen if the assignment is updated or deleted?

These challenges proved pretty difficult to solve, but we eventually came up with a solution that we think will work for most users.

Assign to a Single Class First

When you assign work to a single class via our API, Edlink will create a single assignment in the LMS. This is the same behavior as before. You can accomplish this via either the User or Graph API.

Here's an example via the User API:

axios.post('https://ed.link/api/v2/my/classes/00000000-0000-0000-0000-000000000000/assignments', {
    headers: {
        authorization: `Bearer ${user_access_token}`
    },
    data: {
        assignee_mode: 'all',
        grading_type: 'points',
        max_attempts: 1,
        title: 'Week 12 Homework',
        submission_types: ['link'],
        state: 'open',
        due_date: '2025-02-28T18:00:24.573Z'
    }
});

Make sure you record the assignment ID that is returned in the response. You will need this ID to assign the work to additional classes.

Assigning to Subsequent Classes

In order to "attach" additional classes to the assignment, you will make subsequent call(s) to the same API endpoint, but with slightly different parameters. It is possible to determine which Edlink classes are linked together in Canvas or Schoology because they will all share the same course_id property.

  • You need to POST to the additional class ID, not the one from the first step.
  • You need to include the assignment_id from the first step in the request body as a property called parent_id.
  • You need to include a due_date property. This due date may be the same or different from the original assignment, but it is still subject to ordering requirements (e.g. the due date must be after the start date and before the end date, inclusive).
  • Optionally, you can include an assignee_mode property. This can be either all or individuals.
  • Optionally, you can include a start_date property. This will be the date that submissions will be accepted from this class.
  • Optionally, you can include a end_date property. This will be the date that submissions will no longer be accepted from this class.

All other properties are ignored and you should (optimally) not include them in the request body.

axios.post('https://ed.link/api/v2/my/classes/additional_class_id/assignments', {
    headers: {
        authorization: `Bearer ${user_access_token}`
    },
    data: {
        parent_id: 'assignment_id_from_first_request',
        due_date: '2025-02-28T18:00:24.573Z'
    }
});

This request will return the assignment, as usual. This assignment will have a different ID than the one from the first request, but it will be linked to the original assignment. You can repeat this process for as many classes as you need.

Potential Issues

  • If you attempt to attach a class that is not part of the same course, you will receive a 400 error.
  • If you send an invalid parent ID, you will receive an error.
  • The (now deprecated) assignee_mode = sections, is not supported. You must use all or individuals.
  • If the assignee_mode is set to all and the assignment already happens to be assigned to the request section in the LMS, you will receive a 400 error.
    • It is possible that this behavior may change in the future (i.e. to return the "existing" assignment), but for now, you should avoid this situation when possible.