1. People
Handwrite Classroom
  • Handwrite Regular Accounts
    • Schemas
      • Error
      • Principal
      • Role
      • Access
      • ContentType
      • Language
      • FileRef
      • Document
      • Tombstone
      • DocumentPage
      • CreateDocument
      • UpdateDocument
      • FileInfo
      • CommitUpload
      • Upload
      • DownloadLink
      • Extracted
      • ExtractionFailed
      • CommittedDocument
      • ExtractedDocument
      • SearchHit
      • SearchPage
      • Export
      • Permission
      • Share
      • ChangeRole
      • Invitation
      • Permissions
      • ReceivedInvitation
      • AcceptedInvitation
      • Me
      • WebhookEventType
      • Webhook
      • CreateWebhook
      • CreatedWebhook
      • WebhookDelivery
      • AudioFormat
      • Speech
      • WordTiming
      • SpeechMarks
      • AudioLink
      • Voice
      • Quota
      • SettingEntry
      • Settings
      • SettingsPatch
      • PatchedSettings
      • OAuthToken
      • OAuthError
  • Handwrite Team
    • Schemas
      • Error
      • Principal
      • Access
      • ContentType
      • Language
      • FileRef
      • Document
      • Tombstone
      • DocumentPage
      • OrgKind
      • OrgRole
      • Organisation
      • CreateOrganisation
      • RenameOrganisation
      • Member
      • AddMember
      • ChangeMember
      • InviteMember
      • OrgInvitation
      • ReceivedOrgInvitation
  • 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
        GET
      • Add an existing person to a class
        POST
      • Change a class member role
        PATCH
      • Remove an ordinary class membership
        DELETE
      • Leave an ordinary class
        POST
    • 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
    • Schemas
      • Error
      • Principal
      • Access
      • ContentType
      • Language
      • FileRef
      • Document
      • Tombstone
      • DocumentPage
      • OrgKind
      • OrgRole
      • Organisation
      • CreateOrganisation
      • RenameOrganisation
      • Member
      • AddMember
      • ChangeMember
      • InviteMember
      • OrgInvitation
      • ReceivedOrgInvitation
  1. People

README — POST /api/v1/orgs/{id}/members

Add an existing person to a class#

POST /api/v1/orgs/{id}/members · Operation ID: addMember

Application use#

Use an existing user principal and a valid class role. A teacher can assign class roles; a co-teacher can add only students. This creates a membership, not a managed school student account. Use the school Students workflow for school-owned identities. The route checks seats and existing membership; it is not an account lookup endpoint.

Authentication and permission#

Bearer credential with orgs:manage. Teacher or co-teacher with members.manage and orgs:manage; assignable roles are narrowed by the caller.
Scopes, membership, current role, effective policy and applicable plan checks all apply. A managed student token cannot grant organisation-management authority. A student-pool login JWT is not a public-API bearer credential. See Classroom identity and roles.

Example#

Replace placeholders using an authorised disposable test class. Mutation examples change real data when run. Keep tokens on the server; never copy student credentials into diagnostics.
curl --fail-with-body -X POST 'https://handwrites.io/api/v1/orgs/REPLACE_ORG_ID/members' \
  -H "Authorization: Bearer $HANDWRITE_API_TOKEN" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"principal":"user:REPLACE_USER_ID","role":"student"}'

Parameters#

NameInRequiredDetails
idpathYesAn organisation ID (org_…).
Idempotency-KeyheaderNo1–255 visible ASCII characters (a UUID per operation). A retry with the same key and identical request within 24 hours replays the first 2xx response with Idempotent-Replayed: true; a different request with the key gets 422 idempotency_mismatch; a retry while the first runs gets 409 idempotency_in_progress.

Request body#

application/json (required).
FieldRequiredDetails
principalYesA person.
roleYesTeam roles: owner, admin, billing, manager, developer, member. Class roles: teacher, co-teacher, billing, student.

Responses and recovery#

StatusMeaningFormat
201The membership.application/json
400invalid_request (the message names the field), validation_failed.application/json
401unauthorized: no token, or it's invalid, revoked or expired.application/json
403insufficient_scope, forbidden (you can see it but not do this), app_test_restricted, account_deleted (the account is scheduled for deletion; any request).application/json
404not_found: it doesn't exist or you can't see it (never 403 for documents you can't see).application/json
409conflict (changed meanwhile, already a member) or idempotency_in_progress (with Retry-After).application/json
422limit_reached, idempotency_mismatch, unreadable_file, no_text, empty_document.application/json
429rate_limited (burst or daily cap) or quota_exceeded (no characters left).application/json
500internal_error.application/json
The paired API reference holds the shared machine-readable schema. Additional role, policy, seat and plan failures are described in API specification notes. Do not parse 204 or 304 responses as JSON, and do not treat 403 as a transient retry.
Modified at 2026-10-26 13:24:24
Previous
README — GET /api/v1/orgs/{id}/members
Next
README — PATCH /api/v1/orgs/{id}/members/{principal}
Built with