1. Handwrite Classroom
Handwrite Classroom
  • Handwrite Classroom
    • Start here — Classroom for developers
    • Classroom API specification notes
    • Classroom socket specification notes
    • Classroom live socket — README
    • Classroom identities, credentials and roles
    • School and student workflows
    • Classroom policy and data-use notes
    • Class setup
      • README — GET /api/v1/orgs
      • README — POST /api/v1/orgs
      • README — GET /api/v1/orgs/{id}
      • README — PATCH /api/v1/orgs/{id}
      • README — DELETE /api/v1/orgs/{id}
      • Class setup API — README
      • Choose a class from the returned organisations
      • Create an ordinary class
      • Read the selected class
      • Rename a class
      • Delete an ordinary class
    • Invitations
      • README — GET /api/v1/orgs/invitations
      • README — POST /api/v1/orgs/invitations/{inviteId}/accept
      • README — POST /api/v1/orgs/invitations/{inviteId}/decline
      • README — GET /api/v1/orgs/{id}/invitations
      • README — POST /api/v1/orgs/{id}/invitations
      • README — DELETE /api/v1/orgs/{id}/invitations/{inviteId}
      • Invitations API — README
      • Read invitations to the signed-in person
      • Accept a class invitation
      • Decline a class invitation
      • List pending class invitations
      • Invite a person by email
      • Cancel a pending invitation
    • People
      • README — GET /api/v1/orgs/{id}/members
      • README — POST /api/v1/orgs/{id}/members
      • README — PATCH /api/v1/orgs/{id}/members/{principal}
      • README — DELETE /api/v1/orgs/{id}/members/{principal}
      • README — POST /api/v1/orgs/{id}/leave
      • People API — README
      • Read the visible membership roster
      • Add an existing person to a class
      • Change a class member role
      • Remove an ordinary class membership
      • Leave an ordinary class
    • Documents
      • README — GET /api/v1/orgs/{id}/documents
      • Documents API — README
      • List class-owned documents
    • Plan and usage
      • README — GET /api/v1/orgs/{id}/billing
      • README — GET /api/v1/orgs/{id}/usage
      • README — GET /api/v1/orgs/{id}/usage/live
      • README — GET /api/v1/orgs/{id}/members/{principal}/usage
      • README — GET /api/v1/orgs/{id}/insights
      • Plan and usage API — README
      • Read classroom plan and seat information
      • Read classroom usage totals
      • Read the recent classroom activity window
      • Read one member usage
      • Read classroom collaboration insights
    • Policies
      • README — GET /api/v1/orgs/{id}/policies
      • README — PUT /api/v1/orgs/{id}/policies
      • README — GET /api/v1/orgs/{id}/members/{principal}/policy
      • README — PUT /api/v1/orgs/{id}/members/{principal}/policy
      • README — DELETE /api/v1/orgs/{id}/members/{principal}/policy
      • Policies API — README
      • Read class-wide policy
      • Replace class-wide policy rules
      • Read one member policy
      • Replace one member policy override
      • Clear one member override
    • Managed tokens
      • README — GET /api/v1/orgs/{id}/members/{principal}/tokens
      • README — POST /api/v1/orgs/{id}/members/{principal}/tokens
      • README — DELETE /api/v1/orgs/{id}/members/{principal}/tokens/{tokenId}
      • Managed tokens API — README
      • List tokens issued to a member
      • Issue a managed student token
      • Revoke a managed token
  1. Handwrite Classroom

Classroom socket specification notes

Handwrite uses one binary WebSocket protocol for live document co-editing. Classroom has no separate roster socket, student-auth socket, attendance stream or Socket.IO protocol. The HTTP live-usage endpoint is a polled snapshot.
The authoritative wire reference is Regular Accounts socket specification: it defines frame numbers, varint/string encoding, Yjs sync, awareness, status messages, full-text subscription, UTF-16 splices, close codes and reconnect rules. Classroom uses that same protocol.

Admission for a classroom document#

A public integration with an authorised user-owned credential calls POST /api/v1/documents/{id}/live with documents:read. The app's signed-in student path is a separate opted-in session route; the student-pool JWT itself is not accepted by the public wrapper. A managed student key is still subject to document access, its scopes, the issuing plan and effective policy.
The document must be accessible, the owning class must have the live feature, and effective liveEditing policy must permit it. For personal documents, the user instead needs an eligible organisation membership. Organisation-owned tokens and isolated app-testing tokens cannot become live participants.
Admission returns a URL, short-lived room token, expiry, name, colour and viewer or editor role. Use the returned URL and token, convert HTTPS to WSS, and URL-encode the token. Never put a REST API key into the socket query. Room admission lasts ten minutes; obtain fresh admission on reconnect.
Students normally have viewer access to class-owned documents. A valid editor grant can change their actual document access. Admission does not promote a viewer because they are in a live classroom. Respect welcome, role, readonly and denied statuses immediately and retain local work after an unexpected disconnect.

Shared wire summary#

TypeFrameMeaning
0SYNCYjs state vector or update, with sync step and length-prefixed payload
1AWARENESSLength-prefixed awareness update
2STATUSServer JSON status inside a binary string field
3QUERYAsk for current awareness state
4 / 5PING / PONGApplication heartbeat frames
6TEXTSubscribe to or receive full text
7SPLICEUTF-16 index, deletion count and inserted string
Frames are binary, not standalone JSON text. An unmodified y-websocket client is not automatically compatible. Use the complete shared specification for encoding. Viewer writes are refused; repeated writes can close the connection. Malformed frames, revoked access and oversized messages have distinct close codes.
There is no per-edit durable commit acknowledgement. Socket send success and PONG do not prove persistence. Use Yjs state-vector reconciliation after reconnect; positional splice replay is not safe conflict resolution. During an active room, REST text replacement may return 409 live_session_active.
This spec is source-verified. No real student or live-room connection was used for this documentation task. Do not claim end-to-end classroom collaboration is deployed until the host, student identity path, two-client sync, revocation and durable round trip have been tested.
Modified at 2026-10-26 13:24:24
Previous
Classroom API specification notes
Next
Classroom live socket — README
Built with