Changelog
This page records partner-visible changes: operations in the published API Reference, documented behaviour in the published guides, and insight-type semantics. Internal changes with no external effect are not listed here.
2026.10.27.1
- Signals actions (
listSessionActionsGET /signals/1.0/sessions/{sessionId}/actions): each action now carriesresolvedAt, with the same meaning as onlistUserActions. For a proctoring action such asBlockTest, it is when the action happened, including actions recorded throughPUT /signals/1.0/actions/{actionId}, which leavestartedAtnull. See Signals Feedback. Non-breaking.
2026.10.26.3
- Signals insights (
listSessionInsightsGET /signals/1.0/sessions/{sessionId}/insights): insights still under internal evaluation are no longer listed or counted intotal.upsertInsightFeedbackPUT /signals/1.0/insights/{insightId}/feedbackreturns 404 for such an insight, andlistSessionFeedbackGET /signals/1.0/sessions/{sessionId}/feedbackleaves out feedback on it. Every insight you can list remains one you can rate. See Signals Feedback. Non-breaking.
2026.10.26.2
- Signals actions (
listSessionActionsGET /signals/1.0/sessions/{sessionId}/actions): each action now carriestype(for exampleBlockTestorWarn),initiatorUserId(the person who started the action, such as a guide, ornullwhen no person did), anddateCreated(when the platform received the action), with the same meaning as onlistUserActions. Keep only the action types you handle by readingtype. See Signals Feedback. Non-breaking.
2026.10.26.1
- Webhooks: subscribe to
action.createdto receive every Signals action created for a student, whatever its type, with{ actionId, type, userId, caliperSessionId, occurredAt }. Filter ondata.type(PascalCase, e.g.BlockTest,PreventTestStart).caliperSessionIdis null when the action has no session. Every subscription that listsproctoring_enforcement.recordednow also listsaction.created;proctoring_enforcement.recordedkeeps firing unchanged. See Webhooks. Non-breaking. - Analytics schema:
proctoring_enforcement_actionsnow serves the Signals actionsPreventTestStart,BlockTest,UnblockTest, andEndTest.action_typecarries those names instead ofprevented_start,blocked_mid_test,unblocked_mid_test, andexited_mid_test; the warning,forced_end, andlocked_out_restartkinds are no longer served.session_idis now nullable and is null on everyPreventTestStart. Thereason_category,insight_type,insight_group, andrule_visibilitycolumns are removed. Breaking for queries that filter on the oldaction_typevalues or read the removed columns.
2026.10.23.1
getOrgSessionsGET /insights/1.0/sessions: sessions no longer carryenforcementSummary(autoStopped,warningCount,notificationCount). Stop reading it. Theenforcementfilter is unchanged. Breaking for callers that readenforcementSummary.
2026.10.22.1
- Content ingestion (packages uploaded via
getIngestUploadUrlPOST /content/1.0/ingest/upload-url): new optionalpackageBuiltAtrequest field (ISO 8601 date-time). Importing a package no longer restores an item deleted withDELETE /content/1.0/items/{itemId}, unlesspackageBuiltAtis later than the deletion: send the time you built the package, and a package built before the delete cannot revive the item. WithoutpackageBuiltAt, a deleted item stays deleted. See Content Ingestion. Non-breaking for callers that never re-import a deleted item; callers that relied on a re-import restoring a deleted item must now sendpackageBuiltAt. upsertIssuedActionPUT /signals/1.0/actions/{actionId}:statealso acceptsCOMPLETED, for an action type issued already completed (RedirectOnLaunchis not; sendingCOMPLETEDfor it returns 400). A new optionaloccurredAtsetsresolvedAtwhen thePUTsetsstate, so a cancel through thePUTcan say when it happened, as the state endpoint already allows; it defaults to the server time, and sending it withoutstatereturns 400. See Signals Actions. Non-breaking.
2026.10.21.1
- Session integrity reports: use
storeSessionIntegrityReportPOST /session/1.0/sessions/{sessionId}/integrity-report,readSessionIntegrityReportGET /session/1.0/sessions/{sessionId}/integrity-report, andlistIntegrityReportsGET /session/1.0/integrity-reports. They take the same requests, return the same responses, and require the sameevents.write/events.readonlyscopes asupsertSessionIntegrityReportPOST /insights/1.0/sessions/{sessionId}/integrity-report,getSessionIntegrityReportGET /insights/1.0/sessions/{sessionId}/integrity-report, andgetIntegrityReportRollupGET /insights/1.0/integrity-reports. Switch your calls to the/session/1.0paths. The/insights/1.0paths are deprecated, now returnDeprecationandSunset: Fri, 23 Oct 2026 23:59:59 GMTresponse headers, and will be removed after 2026-10-23 23:59 UTC. Reports already stored read the same on both paths, and theinsights_session_integrity_report.readywebhook event is unchanged. See Session Integrity Reports. Non-breaking.
2026.10.20.5
listUserOpenActionsis renamedlistUserActions, andGET /signals/1.0/users/{userId}/actionsnow returns every action for the student by default, in any state and window, each with itsexpiredflag. New optional filters:state(comma-separatedOPEN,SEEN,COMPLETED,SKIPPED,CANCELLED),inWindow=true(only actions inside their delivery window), and inclusivecreatedAfter/createdBefore. Call withstate=OPEN,SEEN&inWindow=trueto get the previous default. See Signals Actions. Breaking for callers relying on the previous default.
2026.10.20.4
- Issued Signals actions are now in the published API Reference:
upsertIssuedActionPUT /signals/1.0/actions/{actionId},getIssuedActionGET /signals/1.0/actions/{actionId},listIssuedActionsGET /signals/1.0/actions,listUserOpenActionsGET /signals/1.0/users/{userId}/actions, andupdateActionStatePUT /signals/1.0/actions/{actionId}/state. A client with thehttps://timeback-platform.trilogy.com/signals/scope/actions.writescope and the type's permission on its tenant (forRedirectOnLaunch,signals:issue_action:redirect_on_launch) can issue an action for a student under an id it generates, cancel it, and read back its state,seenAt,resolvedAtand derivedexpiredflag. Issuer calls take the client's own token; a person's token, or one delegated to a person, is refused with 403. See Signals Actions. Non-breaking.
2026.10.20.3
- Share links:
POST /insights/1.0/sessions/{sessionId}/sharesis removed. UsePOST /external-access/1.0/sessions/{sessionId}/shareswith theshare.managescope. Share URLs you already delivered keep working until they expire. Breaking for callers of the old path.
2026.10.20.2
- Signals actions (
listSessionActionsGET /signals/1.0/sessions/{sessionId}/actions): the student an action targets is nowtargetUserId;userIdis no longer returned.statecan also beCOMPLETED,SKIPPEDorCANCELLED, andmessage,startedAtandendedAtcan benullfor an action no insight raised. See Signals Feedback. Breaking: readtargetUserIdinstead ofuserId.
2026.10.20.1
- Signals actions (
listSessionActionsGET /signals/1.0/sessions/{sessionId}/actions): each action now carriesuserId, the student it targets, andtbSessionId, the session it was raised in.tbSessionIdcan benullfor an action raised outside a session; read the student fromuserIdrather than through the session. See Signals Feedback. Non-breaking.
2026.10.19.2
- Share links: use
POST /external-access/1.0/sessions/{sessionId}/sharesto mint a parent-facing session share. It takes the same request and returns the same response (id,url,expiresAt), with the same organization-grant rules. It requires thehttps://timeback-platform.trilogy.com/external-access/scope/share.managescope instead ofevents.readonly: request that scope on your client credentials token.POST /insights/1.0/sessions/{sessionId}/sharesis deprecated and will be removed. Share URLs you already delivered keep working until they expire. Non-breaking.
2026.10.19.1
- Signals feedback is now in the published API Reference:
listSessionInsightsGET /signals/1.0/sessions/{sessionId}/insights,upsertInsightFeedbackPUT /signals/1.0/insights/{insightId}/feedback,listSessionFeedbackGET /signals/1.0/sessions/{sessionId}/feedback,listSessionActionsGET /signals/1.0/sessions/{sessionId}/actions,upsertActionFeedbackPUT /signals/1.0/actions/{actionId}/feedback, andgetActionFeedbackGET /signals/1.0/actions/{actionId}/feedback. A school credential with the Signals scopes can rate a session's insights and respond to its actions on behalf of a staff member, then read those ratings and responses back. See Signals Feedback. Non-breaking.
2026.10.14.1
- Sessions (
POST /caliper/v1p2, and the session times returned byGET /insights/1.0/sessions/{sessionId}): a session'sstartedAtTimeandendedAtTimeno longer move past the time the platform processed the event that set them. An event whoseeventTimeruns ahead of the platform clock is still stored with thateventTime, and aLoggedOutstamped ahead still completes the session, but the session's times stop at the processing time. An event naming a completed session is now not stored only when it is stamped after both the session'sendedAtTimeand its ownLoggedOutorTimedOuteventTime. See Session Management. Non-breaking.
2026.10.13.5
- Outbound webhooks (
createWebhookSubscriptionPOST /webhooks/1.0/{sourcedApplicationId}/subscriptionsandupdateWebhookSubscriptionPUTon/webhooks/1.0/{sourcedApplicationId}/subscriptions/{subscriptionId}): a subscription can listinsight.created,insight.updated, andinsight.deletedagain. An unrecognized event type is still rejected with 400. Non-breaking.
2026.10.13.4
- Rostering, applications, gradebook, and CLR credentials list operations:
sort=sourcedIdsorts by the primary key instead of returning a database error. On those and the CASE list operations, asortorfilteridentifier that names no field of the resource, or that namespassword, returns HTTP 400 instead of a database error or a silent match; asorterror reportsinvalid_sort_fieldonsort. A database column name such asdate_created, or a field name in another letter case such asroles.ROLE, used in place of the field name also returns 400. Every field and relation path that resolved before, such asfilter=roles.org.sourcedIdorfilter=class.school.sourcedId, is unchanged. Whitespace other than a space outside a quoted filter value, or text after a complete filter condition, returns 400. Breaking for callers that send any of these identifiers or filter shapes.
2026.10.13.3
- Getting access: the request section no longer carries the approver-facing approval-queue link. Requesters still start at the request page. Non-breaking.
2026.10.13.2
- Student config (
GETandPUT /rostering/1.0/students/{sourcedId}/config): the body now includessecondCameraRecordLearningAppIdsandsecondCameraEnforceLearningAppIds, lists of learning-app ids where that student's second camera records, or where the test does not start until the second camera passes its check. Ids in a list must be unique and non-empty, and each must be a learning app with proctoring mode on. Omitted lists read as empty. Non-breaking.
2026.10.13.1
- Getting access: requesters start at the access console request page. Campus reader and an automation key are approved right away when the roster already lists you as teacher, principal, administrator, or admission coordinator at every school you pick, or at a parent organization above it. Otherwise someone reviews the request. Network reader and write or family-contact access are reviewed by the platform team. An approved automation key or write key is collected from a one-time claim link that requires the requester's Google sign-in. Third-party app registration stays on Level 0. Work that page does not cover still goes to Alpha EDU Support. Reporting MCP connect for Claude and ChatGPT, including the URL the request page prints after approval, uses
https://platform.timeback.com/mcps/analytics(OAuth). The analytics introduction no longer asks readers to email timeback@trilogy.com. The published API credential text points at Getting access. Non-breaking.
2026.10.12.1
- Org config (
GETandPUT /rostering/1.0/orgs/{sourcedId}/config):signalsActionRulesno longer acceptsabsent-during-assessment-daily,device-visible-during-assessment, orleft-test-seeking.academic-integrity-full-screen-requiredis unchanged. Breaking for callers that write the removed keys. - Org config (
GETandPUT /rostering/1.0/orgs/{sourcedId}/config):signalsSanctionedDestinationsis removed. Stored lists are deleted. Breaking for callers that read or write that key. - Caliper ingest (
POST /caliper/v1p2):AbsentFromSeat,AnotherWindowVisible,TestFocusLost,FullScreenExited,Conversation, andDeviceVisibleare no longer registered. The event rejects with the existing unregistered-type error.WindowStateSnapshot,MediaStateSnapshot, andInputEventstay accepted. Breaking for producers of the removed types. - Caliper ingest (
POST /caliper/v1p2): anObservationEventwhose objecttypeisCaliperObservationis now rejected with 400. SendObservation. See Supported Entities. Breaking for producers still sendingCaliperObservation. - Content ingestion (packages uploaded via
getIngestUploadUrlPOST /content/1.0/ingest/upload-url): re-importing a Common Cartridge package now unlinks an item or sub-container from a package container when the manifest no longer lists it under that container. The item is not deleted, and its links to containers outside the package are unchanged. See Content Ingestion. Non-breaking.
2026.10.09.2
- Caliper ingest (
POST /caliper/v1p2): theObservationEventobject type is nowObservation.CaliperObservationis still accepted and stored asObservation. See Supported Entities. Non-breaking.
2026.10.09.1
- Org session list (
getOrgSessionsGET /insights/1.0/sessions): a caller can opt into listing resolved learning sessions whose integrity report carries an unauthorized-help tag, usingunauthorizedTagsorintegrityTags, and optionallyreviewState. Matching rows includeintegrityTags,noteCount, andreview, and the page includesintegrityTagCounts. Calls that omit those parameters keep the previous query and response. Non-breaking. - Session insights (
GET /insights/1.0/sessions/{sessionId}) andinsight.createdwebhooks now return and deliverAcademicIntegrityNoDevicesoccurrences on non-proctored learning sessions, where everyAcademicIntegrityoccurrence on such a session was previously suppressed. A student still receives no notification, warning or enforcement from anAcademicIntegrityNoDevicesoccurrence on a learning session, and every otherAcademicIntegritytype still applies to proctored sessions only. See Insight Types. Non-breaking.
2026.10.08.1
- Session integrity reports (
upsertSessionIntegrityReportPOST /insights/1.0/sessions/{sessionId}/integrity-report,getSessionIntegrityReportGETon that path,getIntegrityReportRollupGET /insights/1.0/integrity-reports): each session object now includes requiredsessionMode,learningorproctored. The writer stamps it from the session. The producer does not send it. Non-breaking.
2026.10.07.4
- Session integrity reports:
upsertSessionIntegrityVerdictPOST /insights/1.0/sessions/{sessionId}/integrity-verdict,getSessionIntegrityVerdictGETon that path, andgetIntegrityVerdictRollupGET /insights/1.0/integrity-verdictsare nowupsertSessionIntegrityReport,getSessionIntegrityReport, andgetIntegrityReportRolluponPOSTandGET /insights/1.0/sessions/{sessionId}/integrity-reportandGET /insights/1.0/integrity-reports. See Session Integrity Reports. Breaking for callers of the previous paths. - Outbound webhooks: the event type
insights_session_integrity_verdict.readyis nowinsights_session_integrity_report.ready, and the documented refetch path isGET /insights/1.0/sessions/{sessionId}/integrity-reportinstead ofGET /insights/1.0/sessions/{sessionId}/integrity-verdict. The payload is still{ sessionId }. Breaking for subscribers filtering on the old event type.
2026.10.07.3
- Caliper ingest (
POST /caliper/v1p2): aSystemIdentifierinsideotherIdentifiers, and anLtiSessioninsessionorfederatedSession, no longer rejects the envelope. Neither value is stored as a Caliper entity. Non-breaking.
2026.10.07.2
- Session integrity verdicts (
upsertSessionIntegrityVerdictPOST /insights/1.0/sessions/{sessionId}/integrity-verdict,getSessionIntegrityVerdictGETon that path,getIntegrityVerdictRollupGET /insights/1.0/integrity-verdicts) are now in the published API Reference. A caller withevents.writecan store one verdict per session. A caller withevents.readonlycan read that verdict, including a session that has no row yet, or a test-level roll-up computed over the named sessions. See Session Integrity Verdicts. Non-breaking.
2026.10.07.1
- Outbound webhooks: a subscriber can receive
insights_session_integrity_verdict.readywhen a session integrity verdict becomes readable throughGET /insights/1.0/sessions/{sessionId}/integrity-verdict, including when a later judgement replaces the stored one, then refetch the verdict bysessionId. The event carries onlysessionId. Non-breaking.
2026.10.06.5
- Caliper ingest (
POST /caliper/v1p2): a DigitalResourcelearningObjectivesvalue, as a full object or a bare IRI, no longer rejects the envelope and is not stored. Non-breaking.
2026.10.06.4
- Caliper ingest (
POST /caliper/v1p2): once a session is closed byLoggedOutorTimedOut, a later event that names the session no longer moves itsstartedAtTimeorendedAtTime. An event that names a closed session and is stamped after itsendedAtTimeis not stored and is not retried; events stamped at or before it are still stored and linked. See Session Management. Breaking for producers that send events naming a session after itsLoggedOutorTimedOut.
2026.10.06.3
- Student config (
GETandPUT /rostering/1.0/students/{sourcedId}/config,GET /rostering/1.0/students/{sourcedId}/config/change-requests/latest,GET /rostering/1.0/config-change-requests) now also acceptshttps://timeback-platform.trilogy.com/student-config/scope/student-config.readonlyon the three reads andhttps://timeback-platform.trilogy.com/student-config/scope/student-config.writeon the write. The roster scopes those operations already required still authorize them. Non-breaking.
2026.10.06.2
- Outbound webhooks: a subscriber can receive
xp.created,xp.updated, andxp.deletedwhen an XP ledger entry becomes visible, its value changes, or it leavesGET /xp/1.0/users/{userId}/entries, then refetch the entry byledgerEntryId. Non-breaking.
2026.10.06.1
- Caliper ingest (
POST /caliper/v1p2): an entity type the platform does not ingest rejects the whole envelope with HTTP 400 and the descriptionThe [Type1, Type2] entity types are not supported.target,referrer,group,membership,extensions, andattributesare outside the check. The accepted types are listed in Supported Entities. Breaking.
2026.10.05.3
- Insights session summaries (
GET /insights/1.0/users/{userId}/sessions, org session listings): a sitting in an app that declares exactly one subject now carries that subject from the moment the sitting is created, recorded or not.subjectnull means the app does not declare exactly one subject and the sitting has not been through a vision-end write. Non-breaking.
2026.10.05.2
- Org config (
GETandPUT /rostering/1.0/orgs/{sourcedId}/config):signalsActionRulesaccepts a fourth template key,academic-integrity-full-screen-required, with{ enforced?, message? }.enforceddefaults to false, so an organization must set it true before this action mints. Non-breaking.
2026.10.05.1
- Org config (
GETandPUT /rostering/1.0/orgs/{sourcedId}/config):signalsActionRulesis now a map of template key to{ minimumInsightCount?, windowHours?, message? }, not an array of full rules. Insight types and action version stay on the template and are rejected on write. GET returns the nearest stored map, not the effective rules: a field missing from that map can still apply from an ancestor when an action is evaluated. Breaking for callers that read or write the previous array shape.
2026.10.01.1
- External graders guide:
POST /content/1.0/gradewaits up to 45 seconds for a bound grader (was 20). The caller may wait up to 60 seconds. A grader timeout or unusable grader result is HTTP 200 withgradingProgress: FailedandscoreGiven: null, not HTTP 504 or 502. Invalid request bodies still return 4xx before any response body. A platform error after the response has started streaming is also HTTP 200 withgradingProgress: Failed. See External Graders. Breaking for callers that treated HTTP 504 or 502 as the timeout or unusable-grader signal. - Insights session summaries (
GET /insights/1.0/users/{userId}/sessions,GET /insights/1.0/sessions/{sessionId}/insights, org session listings):subjectSourcemay now beassessment, meaning the subject came from the sitting's Alpha Test assessments (gradebook line-item subject, or the assessment name when that field is missing). Non-breaking.
2026.09.30.1
- External graders guide:
POST /content/1.0/gradeacceptsitemIdentifierasuuid-plus a content-item id of at most 36 characters, or as the bare content-item id. Non-breaking. - Insights session summaries (
GET /insights/1.0/users/{userId}/sessions,GET /insights/1.0/sessions/{sessionId}/insights, org session listings):subjectSourcemay now beactivity, meaning the subject came from curriculum activity the parser recorded asAssignableEventCompletedin that session. Non-breaking. - Session enforcement state (
GET /insights/1.0/sessions/{sessionId}/enforcement-state): onlockout,triggeringSessionIdis always null. Key ontriggeringCaliperSessionId. Non-breaking.
2026.09.29.1
- Webhooks guide:
student.config.updatedis now in the event catalog. It fires when a student's config row set changes throughPUT /rostering/1.0/students/{sourcedId}/configor an approved parent config change request. Payload:{ studentId }. Refetch the current config withGET /rostering/1.0/students/{studentId}/config. A subscription receives it when its org scope covers the student's primary organization or any organization on the student's roles. Non-breaking. - Applications OneRoster error envelope:
imsx_codeMinorFieldValuenow includesbad_gatewayandgateway_timeout. Non-breaking. - Org config (
GETandPUT /rostering/1.0/orgs/{sourcedId}/config):signalsActionRulesreplacessignalsIncidentRules. Each rule fieldactionVersionreplacesincidentVersion. Stored values are carried over. The previous key is gone. Breaking for callers that read or write the old key or field.
2026.09.28.2
- Insights:
GET /insights/1.0/users/{userId}accepts optionalsessionId, a CSV of up to 64 Caliper session IRIs (percent-encoded). Exclusive withafter/before. A named id owned by another user 403s the whole request; unknown and revoked ids are omitted from a 200. See Insights. Non-breaking. - Insights:
GET /insights/1.0/users/{userId}lists a student's insights across sessions whose start time falls inafter/before.after/beforeaccept RFC 3339 timestamps with an offset (not onlyZ).limitaccepts up to 1000 (default remains 20). See Insights. Non-breaking.
2026.09.28.1
- Insights session summaries (
GET /insights/1.0/users/{userId}/sessions,GET /insights/1.0/sessions/{sessionId}/insights, org session listings):subjectSourcemay now beenrollment, meaning the subject came from the student's app-scoped course enrolment on the session date. Non-breaking. - Insights org session listings (
GET /insights/1.0/sessions), user session and insight reads (GET /insights/1.0/users/{userId}/sessions,GET /insights/1.0/users/{userId},GET /insights/1.0/sessions/{sessionId}), and user overview (GET /insights/1.0/users/{userId}/overview) return sessions by the school stamped on each session. Overview accepts optionalorgIdandincludeChildOrganizations. Unstamped sessions follow the prior live-enrollment rule. Breaking for callers that relied on a student's current school to surface another school's stamped sessions.
2026.09.27.1
- Session enforcement state (
GET /insights/1.0/sessions/{sessionId}/enforcement-state): onlockout,triggeringSessionIdis null for lockouts written from this release on; the field was already nullable and its type is unchanged. Key ontriggeringCaliperSessionId, which is now set whenever the triggering session has been ingested, including before any insight was raised on it. Non-breaking.
2026.09.24.2
- Insights session lists (
GET /insights/1.0/sessionsandGET /insights/1.0/users/{userId}/sessions) and nested session summaries on session insight reads now include atestsarray on each Alpha Test session. Each element carriesattemptId,assessmentId, andtestNameso consumers can group multi-session tests byattemptId. Non-Alpha-Test sessions returntests: []. Non-breaking.
2026.09.24.1
- Insights session summaries (
GET /insights/1.0/users/{userId}/sessions,GET /insights/1.0/sessions/{sessionId}/insights, org session listings):subjectSourcemay now bexp, meaning the subject came from the first XP the student earned in that session. Non-breaking.
2026.09.23.1
- List applications (
GET /applications/1.0):subjectson each application is now the canonical CASE subject titles declared for that app, de-duplicated. Tokens that previously differed only by spelling or case (for examplemathandMathematics) read back as one title.filterandsortonsubjectsuse those same titles. Non-breaking. - XP day-summary (
GET /xp/1.0/users/{userId}/day-summary): when a ledger row has no subject and no curriculum-item subject, the single-subject application fallback uses the application's CASE subject titles, not the retired text column. An app whose CASE join is empty stays inunassignedeven if the frozen text column still has a token. Non-breaking. - Student config parent approval (
POST /rostering/1.0/students/{sourcedId}/config/change-requests,GET /rostering/1.0/students/{sourcedId}/config/change-requests/latest,GET /rostering/1.0/config-change-requests): a student's primary organization with at-home camera and mic locked andatHomeCameraMicFlowModeset toemail_approvalcan queue a parent-approval request from the student app when an open parent or guardian with a notifiable email is linked to the student; the school can read the latest request per student and list requests across its students. Create returns 409 when that primary org is missing or not on email approval. Non-breaking. - Org config (
PUT /rostering/1.0/orgs/{sourcedId}/config): organizations can setatHomeCameraMicFlowModetoapioremail_approvalto choose whether at-home camera and mic changes go through the school portal or parent email approval when the lock is on. Non-breaking.
2026.09.22.2
- Session enforcement state (
GET /insights/1.0/sessions/{sessionId}/enforcement-state):currentSignalIncidentis no longer returned. Signals-pipeline incident delivery through this endpoint has been reverted. Breaking for any consumer reading that field. - XP:
GET /xp/1.0/users/{userId}/day-summaryreturns net XP for one org-local calendar day grouped by canonical CASE subject, with an explicitunassignedbucket and atotalXpthat reconciles to the ledger for the same event-time window. Non-breaking. - XP:
GET /xp/1.0/users/{userId}/entriestreats thebeforequery parameter as an exclusive upper bound on source event time, soafter/beforecan match a day-summarywindowwithout double-counting the instant atwindow.end. Breaking for callers that relied on inclusivebeforeat the boundary instant.
2026.09.22.1
- Org config (
PUT /rostering/1.0/orgs/{sourcedId}/config): organizations can setsignalsSanctionedDestinations, a list of host or app labels treated as allowed leave-test destinations so matching signals insights are excluded from incident evaluation. Non-breaking. - Platform MCP (
/mcp) and Developer-Platform MCP (/mcps/developer-platform): OAuth protected-resource metadata and the published authorization-server metadata now advertiseclient_credentialsfor machine clients. Both paths share thereadOnlyscopehttps://timeback-platform.trilogy.com/mcp/scope/readOnly. Google SSO on those paths is unchanged. The access token is threaded into tool context so webhook tools can authorize with the machine client's tenant grants. Insights and mastery reads stay requester-scoped: a machine token is rejected rather than falling through to unrestricted org access. Non-breaking. - Signals insights list (
GET /signals/1.0/sessions/{sessionId}/insights): callers passsessionIdas a path parameter (replacingGET /signals/1.0/insights?sessionId=…);studentId,from, andtoquery filters are removed. Each insight row returns only pipeline fields (id,type,version,rule,ruleVersion,startedAt,endedAt);dateCreated,studentId, andsessionIdsare removed. Breaking for integrators on the prior URL, query filters, or response fields. - Signals insight feedback submit (
PUT /signals/1.0/insights/{insightId}/feedback): required OAuth scope is nowhttps://timeback-platform.trilogy.com/signals/scope/feedback.write(wasinsights.write). Optionalnoteis capped at 5000 characters. Breaking for clients that requestinsights.writeor send longer notes. - Caliper ingest (
POST /caliper/v1p2): events that omitsessionare attributed likeurn:tag:auto-attachwhen the payload includes aPersonactor andedApp, so they attach to a running session for that student and app instead of being stored with no session link. Non-breaking.
2026.09.21.2
- Caliper ingest (
POST /caliper/v1p2): each event'sactormust resolve to a OneRoster user (urn:uuidonly) unless the event isGradeEvent/GradedorSessionEvent/TimedOut, and each presentedAppmust resolve to a registered LTI application; otherwise the envelope is rejected with HTTP400before queueing. TheCALIPER_EDAPP_REGISTRY_VALIDATION_ENABLEDenvironment toggle is removed —edAppvalidation is always on whenedAppis set. Breaking.
2026.09.21.1
- Signals insights (
GET /signals/1.0/insights,GET/PUT /signals/1.0/insights/{insightId}/feedback): school credentials and human callers can list pipeline insights in org or self scope, submitpositive/negativefeedback as one row per insight and submitter, and read feedback rows whose submitters are in scope. Non-breaking. - Session enforcement state (
GET /insights/1.0/sessions/{sessionId}/enforcement-state): contract version 2 platform-authority responses may includecurrentSignalIncident, the oldest unacknowledged signals-pipeline incident for the session student when no live insights presentation is shown and the session is not in lockout. Non-breaking.
2026.09.20.1
- Org config (
PUT /rostering/1.0/orgs/{sourcedId}/config): organizations can setsignalsIncidentRules, an array of rules that name which insight types open a signals incident, the count and rolling window, the student-facing message, and the incident version. Non-breaking.
2026.09.18.1
- Analytics database schema guide: the published view catalog and column descriptions are now generated from analytics view entity metadata rather than live Postgres catalog comments. The overview describes the analytics MCP catalog instead of QuickSight. Data Type labels may differ from the previous Postgres-derived values. Non-breaking.
- External Graders guide: the grade-time proxy section documents the consumer-backend caller with
content.read, lists HTTP401for missing or invalid tokens, and drops the Coming Later note that grade auth was still pending. See External Graders. Non-breaking.
2026.09.17.1
- Grading:
POST /content/1.0/gradenow requires a consumer-backend token withhttps://timeback-platform.trilogy.com/content/scope/content.read. Unauthenticated calls are rejected. The request and response body is unchanged. The platform still proxies a bound item to its registered grader and still sends that grader no student identity. See External Graders. Breaking for any caller that posted without a token. - Analytics guides: QuickSight dashboards, account invites, and scheduled snapshot export are no longer documented. Partners query the same curated analytics views through the Analytics MCP. Breaking for integrators who followed the retired QuickSight Setup guide.
2026.09.16.1
- Webhooks:
insight.creatednow fires only when an insight is auto-confirmed at creation.insight.deletedis no longer emitted. Theinsight.deletedevent type stays registered so existing subscriptions can still be updated. Breaking for consumers that treated a later review confirmation as a create or a review reversal as a delete. - Grading:
POST /content/1.0/gradenow runs a platform-owned grader-hacking check on the student answer before forwarding a bound item to an external grader. A detected injection is a real grade of 0 with an emptycommentandgradingProgress: FullyGraded; the grader is never called. If the check itself is down, the endpoint returns HTTP 502 with no score so the renderer can retry. See External Graders. Non-breaking.
2026.09.15.3
- API Reference: published component names are now independent of unpublished modules. Collision suffixes such as
InternalError22andimsxCodeMinorFieldDType11are gone; names that still collide among published operations are prefixed with the owning module (InsightsBadRequest,CaseNotFound). Breaking for anyone who generated a client against the previous component names. - Rostering classes and courses (
PUT/DELETE/rostering/1.0/classes/{sourcedId}and/rostering/1.0/courses/{sourcedId}) and student config (GET/PUT/rostering/1.0/students/{sourcedId}/config): the 403 envelope is now the users module's ownimsxStatusInfoDType(additionalProperties: false, with the same required fields and enums as the 400/404/500 on those operations). It is no longer the events module's Forbidden schema that the merge previously substituted. Non-breaking. - Caliper ingest (
POST /caliper/v1p2) and session heartbeat (POST /events/1.0/sessions/{sessionId}/heartbeat): the 500 envelope is now the events module's ownimsxStatusInfoDTyperather than the users module's identically named schema the merge previously substituted. Same required fields and enums; descriptions are shorter andadditionalPropertiesis unspecified. Non-breaking. - Insights guide: gate 2 of the customer-read gates no longer names
insights_config.is_visibleas the hide control. That boolean was retired; a finding's rollout stage is frozen at detection from the policy pinned on its session, so hide versus publish is the rollout stage and org policy alone. The guide previously said a hidden config stamped the findingSHADOW. Non-breaking. - Insights guide: gate 3 now names the per-type minimum occurrence duration, and findings a later event withdraws, alongside context-predicate misses as reasons a segment is stored as
suppressedand kept off the Insights API,insight.*webhooks, and coaching analytics views. The guide previously gave a context-predicate miss as the only reason. Non-breaking. - Caliper ingest: a
SessionEvent.ArchivedcarryingSessionRecording.subject=Unknownno longer overwrites a subject the platform already classified.Unknownis treated as no information, so a producer that has no classification yet can send it safely. A named subject still updates the session's subject. See Caliper Events Reference. Non-breaking.
2026.09.15.2
- Schools can read and set a student's at-home camera and microphone preference at
GET/PUT /rostering/1.0/students/{sourcedId}/config(atHomeCameraMicEnabled). When the student has no stored override, the school's org default for that key is used; when the school has not set a default, the platform default is off. Org config also gainsatHomeCameraMicLocked(off by default), which makes the in-app toggle read-only without rewriting stored student values. School-authenticated writes succeed whether or not the lock is on. Non-breaking.
2026.09.15.1
- Grading:
POST /content/1.0/gradenow proxies a bound item to its registered external grader and returns that grader'sscoreGivenandcommentin the existing flat response. Timeout is 20 seconds (HTTP 504). An unusable result, unreachable grader, or a binding to a revoked grader is HTTP 502 with the reason and no score. Items with no binding still take the internal path. See External Graders. Non-breaking. - XP: MobyMax Language hole-filling pays both the lesson (5) and its
Lesson Test:sibling (2) in the same UTC day. A student who completes both earns 7. This supersedes the 2026.09.12.1 rule that credited at most one of the pair. Historicaldeclined_lesson_test_siblingscoring decisions remain on the record and are not restated. Non-breaking. - Insights catalog:
AcademicIntegrityNoPaste(Pasted Into The Test) is registered in the OnlyTheTest group at SHADOW. Student messages and strikes stay off until rollout leaves SHADOW. Non-breaking. - Content ingestion: a published item may declare
externalGraderIdin extended metadata. The platform stores that as a nullable FK on the content item, or fails ingest if the grader is missing or revoked. Omitting the attribute leaves the default internal grade. See Content Ingestion. Non-breaking. - Analytics MCP:
timeback_execute_querynow has a 110-second statement timeout (was 25 seconds). The 500-row cap is unchanged. See Choosing an Integration Surface and Analytics. Non-breaking.
2026.09.12.1
- XP: MobyMax Language hole-filling now credits at most one of the lesson (5) and its
Lesson Test:sibling (2) per base skill per UTC day. When the assignment already lists the lesson test, the lesson completion is declined (declined_lesson_test_sibling) and only the passing lesson test pays 2. A missing stamp still pays the lesson 5. Non-breaking.
2026.09.10.1
- Insights:
POST /insights/1.0/sessions/{sessionId}/shareslets an organization-grantedclient_credentialsapp mint a session share and receive a Vault/share/{id}URL plus a seven-day expiry, so a partner can store that URL and deliver it on their own channel. Requires the sameevents.readonlyscope as session insights. Non-breaking.
2026.09.09.1
- Caliper ingest accepts
SessionEventwith theArchivedaction: a Person actor delivers an inlineSessionRecordingobject (proctored status, webcam usage, recording times, storage key, subject, extensions) for an existing session, and the platform applies the same session-metadata writes asPOST /insights/1.0/sessions. The event never creates a session and never changes session start or end times. See Caliper Events Reference and Session Management. Non-breaking.
2026.09.08.2
- Rostering users (
GET /rostering/1.0/users,GET /rostering/1.0/users/{sourcedId}, and the role-scoped user lists): theagentsarray now contains only open agent relationships. Relationships the roster has ended (inactive, or carrying an end date) are excluded, matching the/users/{sourcedId}/agentsand/users/{sourcedId}/linkedUsersendpoints. Breaking for integrators that readagentsas the full relationship history.
2026.09.08.1
- Webhooks:
proctoring_enforcement.recordednow also fires forexited_mid_test(client-written when the student leaves the mid-test readiness screen without resuming). Filter ondata.enforcementType. Analytics:proctoring_enforcement_actions.action_typeincludes that kind. Non-breaking. - Webhooks:
proctoring_enforcement.recordednow also fires forblocked_mid_test(platform-minted when a CLIENT START fact carried a trustedREADINESS_GATEmark) andunblocked_mid_test(client-written when the mid-test readiness dialog dismissed). Filter ondata.enforcementType. Analytics:insight_events.enforcement_surfaceisREADINESS_GATEwhen that mark was trusted, otherwise null. Non-breaking. - Store refunds: storefront purchases use an optional per-app refund window (default 7 days) set with
set_app_refund_window; in-app refunds stay on the global 7-day window. Non-breaking.
2026.09.07.2
- Breaking: IRI-only
actorandedAppvalues that have no Caliper entity yet are defined from the matching OneRoster user or LTI application. If neither registry has a match, ingest rejects the event instead of creating a stub. Other entity references keep stub semantics. See General Concepts.
2026.09.07.1
- Analytics schema:
proctoring_enforcement_actionsandinsight_notificationswithhold internal catalogue rule identities instead of dropping those rows. When the resolved type visibility is internal,insight_typeandinsight_groupare null and the newrule_visibilitycolumn isinternal.insight_notifications.insight_typeis now nullable (zero current rows affected). Non-breaking for callers that already treated those identity columns as optional on enforcement actions.
2026.09.03.1
- Store Discount Codes guide: documents
POST /apps/v1/discount-codes/validate(Cognito client-credentials, samepurchases.writescope as in-app purchases). Parent checkout remainsPOST /store/v1/discount-codes/validatewith a parent session. Non-breaking. - Insights guide:
insightGroupis required when the resulting type is notJournal. AJournaltype may omit it (insightGroup: null). An update whose merged state is a non-Journal type without a group is refused. Previously the guide said a group was required on every new type. Non-breaking.
2026.09.01.1
- New insight findings are no longer hidden by
insights_config.is_visibleor orginsightTypeConfigOverrides.isVisible. Hide vs publish isrollout_stateand org policy only. The override JSON key is still accepted and ignored. Non-breaking for readers; operators who hid a detector only via that boolean should use aSHADOWorg policy.
2026.08.31.1
- Insights guide and webhooks: new findings default to
SHADOWwhen the session has no pinned rollout stage for that type. RemainingrolloutStatenulls will be filled toSHADOW; until that fill, a null stage still passes the customer-read gate. New unpinned detections stay off the customer read API andinsight.*events.
2026.08.28.2
- Insight types can carry a minimum occurrence duration. Occurrences shorter than that minimum are stored as suppressed rows and are absent from the Insights API, webhooks, and coaching analytics views. Types with no minimum configured are unchanged. Non-breaking.
2026.08.27.2
- Insights types
IgnoringHelpandTopicShoppingstop producing new detections in this release.GET /insights/1.0/typeskeeps both in the catalog withdeprecated: trueandsunsetAt: 2026-11-26T00:00:00.000Z; after that datetime they leave the catalog. Insights already recorded against either type remain readable. Non-breaking.
2026.08.27.1
- Insights guide: customer reads of detections now also require
insights_insight.outcome = raised. Segments whose context predicate failed (for example an academic-integrity signal on a standard session, or minutes outside an assessment window) are stored as suppressed rows and are absent from the Insights API, webhooks, and coaching analytics views. Non-breaking for callers that already consumed only raised detections; suppressed minutes no longer inflate waste or integrity totals.
2026.08.26.1
- Insights API Reference:
GET /insights/1.0/typesnow returnsdeprecated(boolean, always present) andsunsetAt(nullable RFC 3339 datetime) on each type. During a deprecation window the type stays in the catalog; aftersunsetAtit leaves the catalog and stops producing new insights. Previously recorded insights remain readable. Non-breaking.
2026.08.24.1
- Webhooks guide:
org.config.updatedis now in the event catalog. It fires when an organization's config row set is written throughPUT /rostering/1.0/orgs/{sourcedId}/config(any key write). Payload:{ orgId }. Subscription routing follows the standard org-scope rule. Non-breaking.
2026.08.17.1
- Insights API Reference:
GET /insights/1.0/insight-groupsis now published. It returns the registered insight groups with family, membership rule, and a count of types visible to the caller in each group. Non-breaking.
2026.08.11.1
- Insights API Reference:
GET /insights/1.0/cataloghas been removed from the published surface. It returned locale-keyed message bundles for catalog-managed proctoring insights and was consumed at session start. Breaking for integrators that called it directly.
2026.08.03.1
- The insight types the guide used to list are marked deprecated: they are being retired and will stop being populated. Pull the current list from the type catalog. Breaking for integrators that hard-coded those slugs.
