@JustineHampton
You can use the course-version of the list content migrations endpoint to get IDs and timestamps for each of the imports.
If my destination course ID was 896851, then I would use GET /api/v1/courses/896851/content_migrations. You might want to add ?per_page=100 after that if there were more than 10 content migrations.
If you don't have access to a REST client, you can put this into your browser's location bar. It would be your main Canvas instance (basically, the dashboard page), and then add the part after GET. With Chrome, check the box that says to pretty print the results.
This gives you information about each migration, including which course it came from and what time it was started and finished.
Here's how mine starts out.
[
{
"id": 31246011,
"workflow_state": "completed",
"started_at": "2025-09-09T01:27:32Z",
"finished_at": "2025-09-09T01:27:45Z",
"migration_type": "course_copy_importer",
"created_at": "2025-09-09T01:27:32Z",
"migration_issues_url": "<instance>/api/v1/courses/896851/content_migrations/31246011/migration_issues",
"settings": {
"source_course_id": 7723704,
"source_course_name": "CHEM 100 (Y3) - Concepts of Chemistry (FA25)",
"source_course_html_url": "<instance>/courses/7723704"
},
"progress_url": "<instance>/api/v1/progress/81570989",
"migration_type_title": "Course Copy"
},
... many more
]
The important things here are
- The content migration ID, labeled id. For me, that's 31246011. We may be able to use this to get specifics about the migration.
- The started_at and finished_at timestamps can be used to compare against assignments to see when they were created. If the migrations don't overlap each other, this may be enough information.
- The course ID or name of the course this came from. In this case, it's course 7723704 or the Chem 100 course.
Now we're going to try the get asset id mapping. I will admit that I did not know about this until your message and basically wrote someone else earlier tonight that trying to match up IDs was nearly impossible.
I tried GET /api/v1/courses/896851/content_migrations/31246011/asset_id_mapping.
This response started off like this.
"assignments": {
"52063284": "52607059",
"i5feaea207e5d53db0abba8d51b941d53": {
"source": {},
"destination": {
"id": "8497279"
}
},
...
"verifiers": {
"75099867": "<obscured>",
"76813183": "<obscured>",
"76813184": "<obscured>",
...
"files": { ... },
"module_items": { ... },
"modules": { ... }
...
The first line there is a simple 52063284 : 52607059. When I go to the original course (7723704), I find assignment with id 52063284. I do not find assignment id 52607059. That ID is in my destination course. That is the key (52063284) is the original assignment ID in the course the content was migrated from and the value (52607059) is the assignment ID in the destination course.
That seemed fairly easy.
The next one has an unique identifier rather than a sequential numeric ID. The destination is 8497279 is the assignment ID in my destination course. But what is the "i5feaea207e5d53db0abba8d51b941d53" ? It's an assignment (since we're in the assignment category) migration_id. That particular ID was used five times because I imported that same assignment five times into my sandbox course (I was testing something).
The migration identifier isn't helpful here, but we know the destination ID was 8497279, and we can pull up that assignment, get a title, and then go find that title in the 7723704 course.
Skip the verifiers section. That contains the keys needed to access the files, but the files section contains the same information.
Basically, most sections are filled with migration_ids that give the destination ID of whatever that section is for. For module_items, a destination would be the ID in the destination course of the module_item. You could go look up that ID (in many cases /api/v1/courses/:destination_course_id/<section>/id will get it for you).
Then you go to the course that was copied from (7723704 in my case) and you find the whatever (the section type) with the same name.
That will probably work unless the instructor renamed things.
Another way to do things is to get a list of all assignments and look at the date they were created. For example: GET /api/v1/courses/:destination_course_id/assignments?per_page=100 will give the first 100 assignments in the course. Then you can search for anything that has a created_at date between the migrations started_at and finished_at timestamps. You would need to repeat that for each type of thing (assignment, quiz, discussion, page, etc) to be removed.
Another possibility, assuming the course isn't published and active with students who have completed assignments, is to start over. Reset the course and recopy just the needed content. It's a bit extreme, but you can hopefully see that the issue isn't trivial.
Thank you for helping me find the migration content section. I can give hope to people wanting to track information across multiple courses now.