> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vacademy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Learners

> Find learners, enrol them into courses and edit their details.

Each tool below is one switch in **Settings → MCP Server**. Your AI app sees a tool only when it is switched on for your role; every call is checked again on the server.

## `learners`

**Learners: view** · Read only

Find learners by name, email or phone, and see their profile and the courses they are enrolled in, plus each course's invites and the bulk-enrol CSV template.

| Action | What it does |
| :- | :- |
| `find` | learners whose name, email, phone or username matches, with their courses. When several match, list them (name, email, phone, courses) and ask the admin which one — never guess. |
| `get` | one learner's full profile and enrolments — the fields learner\_edit can change. |
| `enroll_options` | each course's batches and the invites a learner can be enrolled through (name, price / payment type, default or not). Ask the admin which invite to use when a course has more than one. Batches sold to organisations are marked enrollable=false (enrol those from the dashboard). Also says whether the welcome email / login-details email may be sent, and which automations run on enrolment (they may send their own welcome message). |
| `enroll_template` | the bulk-enrol CSV columns (same as the dashboard's template) as a header + sample row — hand it to the admin as a .csv file to fill in, then pass the rows (or the CSV text) to learner\_enroll. |

<Accordion title="Parameters">
  <ParamField path="action" type="string" required>
    The action to run: `find`, `get`, `enroll_options`, `enroll_template`.
  </ParamField>

  <ParamField path="query" type="string">
    find: name, email, phone or username (part is fine).
  </ParamField>

  <ParamField path="learner_id" type="string">
    get: the learner's learner\_id (from find).
  </ParamField>

  <ParamField path="course_ids" type="string[]">
    enroll\_options: course ids from courses(action='list').
  </ParamField>
</Accordion>

<Accordion title="What your AI app is told about this tool">
  ```text theme={null}
  Look up the institute's learners, and what is needed to enrol or edit them. Read-only. Pick an `action`:
  - find (query): learners whose name, email, phone or username matches, with their courses. When several match, list them (name, email, phone, courses) and ask the admin which one — never guess.
  - get (learner_id): one learner's full profile and enrolments — the fields learner_edit can change.
  - enroll_options (course_ids: [..], max 10): each course's batches and the invites a learner can be enrolled through (name, price / payment type, default or not). Ask the admin which invite to use when a course has more than one. Batches sold to organisations are marked enrollable=false (enrol those from the dashboard). Also says whether the welcome email / login-details email may be sent, and which automations run on enrolment (they may send their own welcome message).
  - enroll_template: the bulk-enrol CSV columns (same as the dashboard's template) as a header + sample row — hand it to the admin as a .csv file to fill in, then pass the rows (or the CSV text) to learner_enroll.
  ```
</Accordion>

## `learner_edit`

**Learners: edit details** · Makes changes · Changes live data — the change applies straight away. · Turned on separately (opt-in)

Let the connected AI app change a learner's details — name, phone, password, address, parents and custom fields — after showing you the before and after and getting your confirmation. Changes apply right away. Email and username can never be changed from here.

<Note>
  **What keeps it safe:** confirm-gated live edit, the admin's explicit choice: changes one learner of this institute at a time; never email or username; needs the confirm\_token of a preview that showed every before → after
</Note>

| Action | What it does |
| :- | :- |
| `preview` | checks the change and shows each field's current → new value. Nothing is saved. Returns a confirm\_token (valid 15 min). |
| `apply` | saves it. |

<Accordion title="Parameters">
  <ParamField path="action" type="string" required>
    The action to run: `preview`, `apply`.
  </ParamField>

  <ParamField path="learner_id" type="string" required>
    The learner's learner\_id (from learners(action='find')).
  </ParamField>

  <ParamField path="changes" type="object">
    \{field: new value} — only the fields to change.
  </ParamField>

  <ParamField path="password" type="string">
    A new login password.
  </ParamField>

  <ParamField path="custom_fields" type="object">
    \{label or field\_id: value}.
  </ParamField>

  <ParamField path="send_credentials_via" type="string[]">
    —
  </ParamField>

  <ParamField path="confirm_token" type="string">
    apply: the token preview returned.
  </ParamField>
</Accordion>

<Accordion title="What your AI app is told about this tool">
  ```text theme={null}
  Change a learner's details: name, mobile number, password, gender, date of birth, address, city, state, PIN code, parents' names / phones / emails, school, and the institute's custom fields. Email and username can never be changed here. First find the learner with learners(action='find') — when several match, show them (name, email, phone, courses) and ask which one; never guess. Then:
  - preview (learner_id, changes?: {field: new value}, password?, custom_fields?: {label or field_id: value}): checks the change and shows each field's current → new value. Nothing is saved. Returns a confirm_token (valid 15 min).
  - apply (same arguments + confirm_token, send_credentials_via?: [EMAIL, WHATSAPP] — after a password change, sends the learner their login details; ask the admin): saves it.
  changes keys: full_name, mobile_number, gender, date_of_birth, address_line, city, region, pin_code, fathers_name, mothers_name, parents_mobile_number, parents_email, parents_to_mother_mobile_number, parents_to_mother_email, linked_institute_name. gender: MALE | FEMALE | OTHER. date_of_birth: YYYY-MM-DD. Phone numbers with country code. A field cannot be blanked from here. The password is set to exactly what the admin gives (min 6 characters, no spaces) — never make one up unless asked, and do not repeat it back in the chat.
  ```
</Accordion>

## `learner_enroll`

**Learners: enrol into courses** · Makes changes · Changes live data — the change applies straight away. · Turned on separately (opt-in)

Let the connected AI app enrol learners — one, a list or a CSV, existing or new — into one or more courses through the invite you pick. It always shows you a preview (who is new, who is already enrolled) and enrols only after you confirm. It asks you every time whether to send the welcome email and the login-details email, and whether you want a CSV of the learners' usernames and passwords (delivered as a private download link that expires after 30 minutes, never shown in the chat). Never removes anyone from a course. Batches sold to organisations stay dashboard-only.

<Note>
  **What keeps it safe:** additive + confirm-gated: only ENROLS (never de-assigns; duplicates SKIP or ERROR, never RE\_ENROLL) and only through this institute's active invites of the chosen batch; refuses organisation batches; every write needs the confirm\_token of a dry-run preview of the identical request
</Note>

| Action | What it does |
| :- | :- |
| `preview` | checks everything and runs a dry run. Nothing is saved. Returns the per-learner outcome and a confirm\_token (valid 15 min). |
| `enroll` | does it. Changed arguments need a new preview. |

<Accordion title="Parameters">
  <ParamField path="action" type="string" required>
    The action to run: `preview`, `enroll`.
  </ParamField>

  <ParamField path="learners" type="object[]">
    \[\{learner\_id}] for existing learners and/or new-learner rows.
  </ParamField>

  <ParamField path="csv" type="string">
    The filled-in enroll\_template as CSV text.
  </ParamField>

  <ParamField path="courses" type="object[]">
    \[\{course\_id, batch\_id?, invite\_id?, access\_days?}]
  </ParamField>

  <ParamField path="options" type="object">
    —
  </ParamField>

  <ParamField path="confirm_token" type="string">
    enroll: the token preview returned.
  </ParamField>
</Accordion>

<Accordion title="What your AI app is told about this tool">
  ```text theme={null}
  Enrol learners into courses through an invite — one learner or a whole list / CSV, into one or several courses at once (every learner goes into every course listed, like the dashboard's Enroll Learner dialog). Never removes or unenrols anyone. Steps: learners(action='enroll_options') for the courses → ask the admin which invite when a course has several (never pick a price for them) → preview → show the admin the outcome (who is new, who is already enrolled and skipped, which invite / price) and get a clear yes → enroll with the SAME arguments plus confirm_token. Pick an `action`:
  - preview (learners and/or csv, courses, options?): checks everything and runs a dry run. Nothing is saved. Returns the per-learner outcome and a confirm_token (valid 15 min).
  - enroll (same arguments + confirm_token): does it. Changed arguments need a new preview.
  learners: [{learner_id} (an existing learner, from learners(action='find')) | a new-learner row using the enroll_template columns, e.g. {full_name, email, mobile_number, …, custom_fields?: {label: value}}] (max 200). csv: the filled-in template as CSV text (header row first). A row whose email / mobile already belongs to a learner of this institute enrols that learner and leaves their profile as is.
  courses: [{course_id, batch_id? (needed when the course has several batches), invite_id? (needed when the course has several invites), access_days?}] (max 10).
  options: {send_welcome_email: bool (the 'Welcome to <institute>' enrolment email — ASK the admin), send_credentials: bool (email username + password to NEW learners — ASK the admin; only asked when new accounts are created), duplicate_handling?: SKIP (default: already-enrolled learners are skipped) | ERROR (reported as failed), payment_date?: YYYY-MM-DD (offline payment received), transaction_id?, credentials_file: bool (a CSV of every enrolled learner's username + password, delivered as a private download link valid 30 minutes — ASK the admin)}. Never assume these answers: preview returns error 'ask_admin' until they are given (a switch turned off in Course Settings is not asked). Hand the credentials link to the admin as is; never open it. The preview also lists the enrolment automations that will run anyway — they may send their own welcome message; tell the admin.
  ```
</Accordion>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.