Skip to main content

How LTI® Grade Passback Works

The short answer

Grade passback is Assignment and Grade Services, one of the LTI® Advantage services. Your tool posts a score against a line item — a column in the LMS gradebook — and the LMS records it against that user. Three concepts do all the work: line items, scores and results.

It is specified as Assignment and Grade Services 2.0 by 1EdTech Consortium, Inc.

The three concepts

A line item is a gradebook column. In most integrations one already exists: the LMS created it when the activity was added to the course. You can also create your own, which is what you want if a single activity produces several marks.

A score is a submission for one user. Posting one does not replace the column; it records a result within it.

A result is what the gradebook currently holds. Read-only, and the honest answer to "did that actually land".

Getting permission

Service calls are not authorised by the launch. Verifying a launch proves who the user is; it grants nothing.

To call a service, your tool signs an assertion with its own private key, exchanges it at the platform's token endpoint for an access token scoped to specific permissions, and calls the service with that. Four scopes matter here:

ScopeAllows
.../lti-ags/scope/lineitemCreate, update and delete columns
.../lti-ags/scope/lineitem.readonlyList and read columns
.../lti-ags/scope/scorePost scores
.../lti-ags/scope/result.readonlyRead what the gradebook holds

Scopes are granted per registration and per course, so a tool can have grade access in one course and not another. Treat a missing service as normal rather than as an error — the launch tells you which services are available for that context, and branching on that is more reliable than assuming.

Posting a score

{
"userId": "9a8b7c6d",
"scoreGiven": 95,
"scoreMaximum": 100,
"activityProgress": "Completed",
"gradingProgress": "FullyGraded",
"timestamp": "2026-08-11T10:04:00Z"
}

The two progress fields are more important than they look, because the LMS decides what to display based on them, not on the score.

activityProgress describes what the learner did — Initialized, Started, InProgress, Submitted, Completed.

gradingProgress describes whether the mark is final — NotReady, Failed, Pending, PendingManual, FullyGraded.

Only FullyGraded means "show this". A score sent with Pending is accepted, stored, and not displayed — which is the single most common reason for "the API returned success and the teacher sees nothing".

scoreGiven is optional. Omitting it while sending progress fields is how you record that someone started or submitted without assigning a mark.

Why a score does not appear

In the order worth checking:

gradingProgress is not FullyGraded. Above.

You posted to a different line item than the one on screen. If your tool created a column, that is not the column the LMS created for the activity. Read the line items back and look at what exists.

The column is read-only. Some platforms lock columns under certain configurations, and the LMS rejects the write with its own error. A good client surfaces that error rather than flattening it into a 500.

The user identifier is wrong. userId is the sub from the launch for that platform, not your internal ID and not an email address.

A 401 with insufficient scope. The registration was not granted the score scope. That is an administrator change, not a code change.

Grading after the launch

Most real grading is asynchronous — a human marks an essay on Thursday, a job runs overnight. By then the browser session is long gone.

This needs credentials that outlive the launch. With LTIAAS that is the service key, issued alongside the launch data when grade services are available. It does not expire with the session and it carries the service endpoints for that context, so a background job can post a score days later without a live launch.

The asynchronous grading guide covers the pattern.

What LTIAAS handles

The token exchange, the assertion signing and the endpoint discovery, so a score post is one authenticated request:

await axios.post(
`https://your.ltiaas.com/api/lineitems/${lineItemId}/scores`,
{ userId, scoreGiven: 95, scoreMaximum: 100,
activityProgress: 'Completed', gradingProgress: 'FullyGraded' },
{ headers: { Authorization: `LTIK-AUTH-V2 ${API_KEY}:${ltik}` } }
)

Some conveniences worth knowing about, because they remove failures rather than just typing. scoreMaximum is filled in from the line item if you send only scoreGiven. The timestamp is stamped for you. Both progress fields are validated against the permitted vocabularies before the call leaves, so a typo fails immediately with a clear message rather than being rejected by the LMS. And where a platform sends only a single line item endpoint rather than a container, LTIAAS falls back to it instead of failing.

When the LMS does reject something, its status code, the URL called and both bodies are surfaced — which is the difference between "the column is read-only" and "500".

Common questions

What is LTI® grade passback?

Sending a score from your tool back into the LMS gradebook, using Assignment and Grade Services. Your tool posts a score against a line item — a gradebook column — and the LMS records it for that user.

What is a line item?

A column in the gradebook. It usually already exists, created by the LMS when the activity was added to the course. Your tool can also create its own if it needs more than one column per activity.

Why does my score return success but not appear in the gradebook?

Usually the column. The score was accepted against a line item that is not the one on screen, or gradingProgress was not FullyGraded so the LMS is holding it as pending. Read the results back to see what the gradebook actually holds.

Can I send a grade after the launch has ended?

Yes, and it is the normal case for anything graded asynchronously. It needs credentials that outlive the launch — with LTIAAS that is the service key, which does not expire with the session.

Next

All trademarks, logos, and service marks displayed on this website are the property of their respective owners. LTIAAS is a trademark of GatherAct, LLC, doing business as LTIAAS. Learning Tools Interoperability (LTI)® and LTI® are trademarks of 1EdTech Consortium, Inc. LTIAAS is not affiliated with, endorsed or sponsored by 1EdTech Consortium, Inc. or by any other owners of third-party trademarks used on this website. LTIAAS is not responsible for the content, quality, or accuracy of any websites linked to or from this website that are not owned by LTIAAS. If you have any questions or concerns about the use of any trademarks or content on this website, please contact us.