Loopwise Docs
Admin APIMutations

Student Mutations

Create students and update their profile and admin tags in your Loopwise school

The student mutations allow you to create students and update an existing student's profile fields and admin-managed tags.

Student entity mutations:

  • createStudent — Creates a new student, or returns the existing user if the email already matches one
  • updateStudent — Updates a student's name, phone number, and/or admin tags

Both mutations require a token with the students:write scope.

Note: Admin tags can gate access to tag-restricted consulting services, so tag writes are an access-granting operation — grant students:write accordingly.


Create a Student

The createStudent mutation creates a new student in your school, or returns the existing user if the email already matches one. It is idempotent — safe to retry — and does NOT send any email.

Input Parameters

FieldTypeRequiredDescription
emailString!YesEmail of the student. Used as the idempotency key within the school.
nameStringNoDisplay name of the student. When omitted or blank, the email is used as the display name. For existing users, an incoming name is ignored unless the existing name is blank or the placeholder "Student".
phoneNumberStringNoPhone number. Ignored if the user already exists.

Return Type

type AdminCreateStudentPayload {
  # The created or existing student
  student: AdminUser!

  # True if a new user was created, false if the email matched an existing user
  created: Boolean!
}

Example

mutation CreateStudent {
  createStudent(
    email: "jane@example.com"
    name: "Jane Doe"
    phoneNumber: "0912345678"
  ) {
    student {
      id
      email
      name
      phoneNumber
    }
    created
  }
}

Sample Response

{
  "data": {
    "createStudent": {
      "student": {
        "id": "user_12345",
        "email": "jane@example.com",
        "name": "Jane Doe",
        "phoneNumber": "+886912345678"
      },
      "created": true
    }
  }
}

Common Errors

CodeDescription
STUDENT-002Invalid email format
STUDENT-004Failed to create new user

Update a Student

The updateStudent mutation performs a partial update on an existing student in your school. Only the input keys you provide are applied — omitted keys leave the corresponding field unchanged. All writes are absolute sets, so the mutation is idempotent — safe to retry.

Note: email is intentionally NOT updatable through this mutation. Email is the idempotency key used by createStudent and is never changed through the Admin API.

Who is updatable: any user holding the student role in the school. Teaching assistants without the student role and unknown or out-of-school IDs return a not-found error.

Input Parameters

FieldTypeDescription
idString!ID of the student to update
inputAdminStudentUpdateInput!Partial-update fields (see below)

AdminStudentUpdateInput Fields

FieldTypeRequiredDescription
nameStringNoDisplay name. Omit to leave unchanged. Explicit null or a blank string is rejected — students must keep a display name.
phoneNumberStringNoPhone number. Omit to leave unchanged; pass null to clear it. Numbers are normalized with a TW default country code and echoed back normalized (e.g. 0912345678+886912345678).
tags[String!]NoAdmin tags. Replaces the entire list — pass all tags every time. An empty array ([]) clears all admin tags; explicit null is a no-op, same as omitting the key. Tags containing commas are rejected. Tag names match case-insensitively but preserve the casing of first use. System-managed tags are never touched.

To modify tags safely, read the current list first from the tags field on AdminUser (see Users Query), modify it, and write the full list back.

Return Type

type AdminUpdateStudentPayload {
  # The updated student, null if the update failed
  student: AdminUser

  # Validation errors, if any occurred during the update
  errors: [String!]
}

Example

mutation UpdateStudent {
  updateStudent(
    id: "user_12345"
    input: {
      name: "Jane Doe"
      phoneNumber: "0912345678"
      tags: ["vip", "beta-tester"]
    }
  ) {
    student {
      id
      name
      phoneNumber
      tags
    }
    errors
  }
}

Sample Response

{
  "data": {
    "updateStudent": {
      "student": {
        "id": "user_12345",
        "name": "Jane Doe",
        "phoneNumber": "+886912345678",
        "tags": ["beta-tester", "vip"]
      },
      "errors": null
    }
  }
}

Partial Update Example

Omitted keys (including tags) are left untouched:

mutation UpdateStudentNameOnly {
  updateStudent(id: "user_12345", input: { name: "Jane Smith" }) {
    student {
      id
      name
      phoneNumber   # unchanged
      tags          # unchanged
    }
    errors
  }
}

Clearing All Tags

Pass an empty array to remove all admin tags from a student (tags: null would be a no-op):

mutation ClearStudentTags {
  updateStudent(id: "user_12345", input: { tags: [] }) {
    student {
      id
      tags
    }
    errors
  }
}

Common Errors

CodeDescription
STUDENT-005User not found — the id does not resolve to a user with the student role in the current school (unknown ID, out-of-school user, or a teaching assistant without the student role)
STUDENT-003Name cannot be blank — explicit null or blank name is rejected
STUDENT-007Invalid tag value — tags must be non-blank and must not contain commas
STUDENT-006Failed to update user

Model validation failures (e.g. an invalid phone number) are returned in the errors field of the payload rather than as GraphQL errors.

On this page