Skip to content
WorkRoad home
REST API

October 2026 v1 migration

Update integrations written against the earlier v1 API.

October 2026 changes to v1

This release changed v1 itself, because few integrations depended on it yet. It did not add /api/v2. Clients written against the earlier v1 need these updates:

  • Reference fields are named subjectId, parentId and termId, and timestamps are createdAt and updatedAt. Path parameters have matching names such as {taskId} and {setId}; the URLs are the same.
  • cursor takes only the opaque nextCursor value from a previous page. A row id is rejected with 400 invalid_query.
  • Date fields accept only strings. A number or boolean returns 400 invalid_request.
  • Unknown fields in a request body or query string return 400 that names the field. Before, they were ignored.
  • An unknown or foreign subjectId on POST /tasks returns 400 invalid_request, where it was 404. A folderId on POST /notes that is not one of the user's folders also returns 400.
  • A set, note or recording id in a request body that isn't the user's returns 400 invalid_request with details.field and details.reason (unknown-set, unknown-note or unknown-recording), not 404. This covers sourceSetIds and sourceNoteIds on POST /tests, noteId on POST /sets/generate, and a start_generation action that names a recording on POST /copilot/messages/{messageId}/actions. A 404 on those endpoints means the path's own resource is missing.
  • Copilot messages page with cursor and nextCursor, not before and nextBefore. Conversations use the same opaque cursor.
  • GET /jobs/{jobId} and POST /jobs/{jobId}/cancel check the job's kind against the key's scopes (see Jobs). A copilot:use key reads and cancels its copilot jobs and reads, applies and discards the generations they start. A tests:view or files:view key reads the jobs of its domain. A key with no scope for a kind gets 403.
  • POST /tests requires a body requestId and creates no test when it is refused with 402 or 429. Before, a 402 left a failed test.
  • Study set generation's result has setId and termCount, not studySetId.
  • insert-end on a generation refuses a note that would pass 200,000 visible characters.
  • Terms, definitions, hints and teacher names have length caps, listed under study sets and subjects.
  • A task's type must be one of the user's task types; an unknown one returns 400 unknown-task-type unless the request sends createType: true. Before, any text was stored as the type.
  • A task's dueDate or recurrence endsAt sent as YYYY-MM-DD is the start of that day in the user's time zone, not UTC midnight.