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!
We are migrating course data into Canvas from a different vendor and need the ability to import existing grades in bulk via API (not thru the UI).
We've identified the following bulk_update API but are running into trouble executing successfully.
Submissions - Canvas LMS REST API Documentation
Our courses have a number of assignments and we need to send grades for each student for each assignment. Based on API docs, it seems that this endpoint does what we need.
From the documentation, we specify the posted_grade and assignment_id which has the student id included in they key name.
When we execute this POST, we get the following error which we think is related to the assignment_id kvp.
{
"errors": [
{
"message": "The specified resource does not exist."
}
],
"error_report_id": 4065
}
Has anyone used this API endpoint before who can offer some guidance? Or, is there some other API that we can use to bulk import the grades?
TIA
@clforwork can you post your syntax?
I got the same sort of error as you, but with the same data it worked fine if I used the assignment-specific endpoint instead:
/api/v1/courses/course_id/assignments/23456/submissions/update_grades
grade_data[13576][posted_grade]=92
Can you use that instead?
Thank you both for replying!
Peter, we need to import hundreds of thousands of grades so I am trying to avoid making one to one calls for each grade.
Garth, I am not able to get this to work with curl or Postman so have not tried implementing in code yet. Below is my curl cmd and the resulting output. Any suggestions?
curl -v
'https://**REDACTED**-sandbox.instructure.com/api/v1/courses/218/submissions/update_grades'
-X POST
-F 'grade_data[447][posted_grade]=88&grade_data[447][assignment_id]=23046'
-H "Authorization: Bearer **REDACTED**"
* Trying **REDACTED**...
* Connected to **REDACTED**-sandbox.instructure.com (**REDACTED**) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.canvaslms.com
* Server certificate: DigiCert SHA2 Secure Server CA
* Server certificate: DigiCert Global Root CA
> POST /api/v1/courses/218/submissions/update_grades HTTP/1.1
> Host: **REDACTED**-sandbox.instructure.com
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: Bearer **REDACTED**
> Content-Length: 203
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------2760f598125e718f
>
< HTTP/1.1 100 Continue
< HTTP/1.1 404 Not Found
< Cache-Control: no-cache
< Content-Type: application/json; charset=utf-8
< Date: Mon, 28 Aug 2017 16:59:42 GMT
< P3P: CP="None, see http://www.instructure.com/privacy-policy"
< Server: Apache
< Set-Cookie: _csrf_token=**REDACTED**; path=/; secure
< Set-Cookie: log_session_id=**REDACTED**; path=/
< Set-Cookie: canvas_session=**REDACTED**; path=/; secure; HttpOnly
< Status: 404 Not Found
< X-Canvas-Meta: q=41113;at=102050000000000016;dk=170000000000016;a=1;g=mxbSmo0d4UfMNmJSHa7fKPtXEdkupUUi4QyOqShn;s=10205;c=cluster28;z=us-east-1c;b=1314160;m=1314160;u=0.05;y=0.00;d=0.07;
< X-Canvas-User-Id: **REDACTED**
< X-Content-Type-Options: nosniff
< X-Rate-Limit-Remaining: 700.0
< X-Request-Context-Id: **REDACTED**
< X-Request-Cost: 0.12316718199995452
< X-Request-Processor: 0c1436a00de381f1c
< X-Runtime: 0.189197
< X-Session-Id: **REDACTED**
< X-UA-Compatible: IE=Edge,chrome=1
< X-XSS-Protection: 1; mode=block
< Content-Length: 88
< Connection: keep-alive
* HTTP error before end of send, stop sending
<
* Closing connection 0
{"errors":[{"message":"The specified resource does not exist."}],"error_report_id":4079}%
Got it figured out. Despite not being documented on the page that I linked to in my original post, it is possible to send a JSON payload which allows specification of the assignment Id. This is the payload that I used where 329 is the assignment Id and 60,62 are student Ids.
Thanks again for your replies.
{ "grade_data": { "329": { "60": { "posted_grade": "18" }, "62": { "posted_grade": "75" } } } }
@clforwork awesome! Glad you got it working. Thanks for sharing.
Thanks for posting this.
So, the documentation could have:
grade_data[<assignment_id>][<student_id>][posted_grade]
An example for curl data would be:
-F "grade_data[576][13576][posted_grade]=1.5" \
-F "grade_data[576][77249][posted_grade]=2.5"
BTW, the other endpoint I had above would not need one call per grade, but it would be one call per grade column.
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