---
title: "Create Import Plan"
method: POST
path: "/admin/import-plans"
tags: ["admin-import-plans"]
---

# Create Import Plan

`POST /admin/import-plans`

The school's plan for the year: the existing one if any (one plan per
school and year), else a new empty one. Writes the plan only.

## Query parameters

- `source` string — page or mcp

## Request body

- ImportPlanCreate
  - `school_id` string, required
  - `school_year` string, nullable

## Response `200`

Successful Response

- ImportPlanCreateResponse
  - `plan` ImportPlanResponse, required
    - `id` string, required
    - `school_id` string, required
    - `school_name` string, required
    - `school_year` string, required
    - `revision` integer, required
    - `created_at` string, date-time, required
    - `created_by` PlanAuthor, required — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
      - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
      - `email` string, nullable
      - `name` string, nullable
    - `updated_at` string, date-time, required
    - `updated_by` PlanAuthor, required — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
      - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
      - `email` string, nullable
      - `name` string, nullable
    - `state` string, required
    - `status_counts` object, required
    - `waiting_for` string, nullable
    - `page_url` string
    - `sources` SourceResponse[], required
      - `id` string, required
      - `file_name` string, required
      - `kind` string, required
      - `size_bytes` integer, required
      - `added_at` string, date-time, required
      - `added_by` PlanAuthor, required — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
        - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
        - `email` string, nullable
        - `name` string, nullable
      - `grid` FileGrid — One file: its sheets in workbook order (a CSV, a PDF or pasted text is a single sheet). `limits_hit` lists every cap that cut something, so a partial read is never mistaken for the whole file.
        - `file_name` string, required
        - `kind` 'xlsx' | 'xls' | 'ods' | 'csv' | 'pdf' | 'text', required
        - `size_bytes` integer
        - `sheets` SheetGrid[]
          - `name` string, required
          - `index` integer, required
          - `hidden` boolean
          - `rows` array[]
            - string[]
          - `declared_rows` integer
          - `declared_cols` integer
          - `hidden_rows` integer[]
          - `hidden_cols` string[]
          - `merged` string[]
          - `formulas` object
          - `truncated` string, nullable
        - `warnings` string[]
        - `limits_hit` string[]
        - `error` string, nullable
      - `sheets` SheetSummary[], required
        - `name` string, required
        - `hidden` boolean, required
        - `n_rows` integer, required
        - `n_cols` integer, required
        - `declared_rows` integer, required
        - `non_empty_rows` integer, required
        - `hidden_rows` integer, required
        - `hidden_cols` string[], required
        - `merged` integer, required
        - `formulas` integer, required
        - `formulas_sample` array[]
          - unknown[]
            - unknown
        - `truncated` string, nullable
      - `warnings` string[]
      - `limits_hit` string[]
      - `error` string, nullable
    - `mapping` StructureMapping, required
      - `sheets` SheetMappingOutput[]
        - `source_id` string, required
        - `sheet` string, required
        - `ignored` boolean
        - `regions` SheetRegion[]
          - `role` 'students' | 'teachers' | 'division_teachers', required
          - `header_row` integer, nullable
          - `first_row` integer, required
          - `last_row` integer, nullable
          - `skip_rows` integer[]
          - `columns` ColumnMeaning[]
            - `column` string, required
            - `meaning` 'full_name' | 'last_name' | 'first_name' | 'email' | 'division' | 'group_name' | 'teacher_for_subject' | 'subject_flag' | 'option_codes' | 'population_flag' | 'teacher_full_name' | 'teacher_last_name' | 'teacher_first_name' | 'teacher_email' | 'teacher_subjects' | 'teacher_divisions' | 'ignored', required
            - `subject` 'maths' | 'physique-chimie' | 'maths-complementaires' | 'maths-expertes', nullable
          - `group_name_from` CellSource — Where a value that is not in a column comes from: the sheet's name (a group per tab) or one cell (a title, a `Classe :` form field).
            - `kind` 'sheet_name' | 'cell', required
            - `cell` string, nullable
          - `division_from` CellSource — Where a value that is not in a column comes from: the sheet's name (a group per tab) or one cell (a title, a `Classe :` form field).
            - `kind` 'sheet_name' | 'cell', required
            - `cell` string, nullable
          - `teacher_from` CellSource — Where a value that is not in a column comes from: the sheet's name (a group per tab) or one cell (a title, a `Classe :` form field).
            - `kind` 'sheet_name' | 'cell', required
            - `cell` string, nullable
          - `teacher_subject` 'maths' | 'physique-chimie' | 'maths-complementaires' | 'maths-expertes', nullable
          - `region_subject` 'maths' | 'physique-chimie' | 'maths-complementaires' | 'maths-expertes', nullable
          - `level` 'sixieme' | 'cinquieme' | 'quatrieme' | 'troisieme' | 'seconde' | 'premiere' | 'terminale' | 'prepa', nullable
        - `population_filter` PopulationFilter — Only the rows with one of `values` in `column` enter the plan: "only the students with 1 in column Z" (the school's paid seats).
          - `column` string, required
          - `values` string[], required
        - `option_codes` object
        - `summary` string
        - `origin` 'model' | 'admin' | 'default'
      - `summary` string
    - `students` PlanStudent[], required
      - `id` string, required
      - `last_name` string, required
      - `first_name` string, required
      - `email` string, nullable
      - `division` string, nullable
      - `level` 'sixieme' | 'cinquieme' | 'quatrieme' | 'troisieme' | 'seconde' | 'premiere' | 'terminale' | 'prepa', nullable
      - `group_name` string, nullable
      - `subjects` string[]
      - `teachers_by_subject` object
      - `in_population` boolean
      - `name_ambiguous` boolean
      - `subject_info` boolean
      - `source` SourceRef, required
        - `source_id` string, required
        - `file_name` string, required
        - `sheet` string, required
        - `row` integer, required
      - `raw` string
      - `origin` 'file' | 'admin' | 'school_answer'
      - `edited` boolean
    - `filtered_out_count` integer, required
    - `teachers` PlanTeacher[], required
      - `id` string, required
      - `last_name` string, required
      - `first_name` string
      - `email_in_file` string, nullable
      - `subjects` string[]
      - `divisions` string[]
      - `names_in_file` string[]
      - `origin` 'file' | 'admin'
      - `status` 'account' | 'invitation' | 'to_invite' | 'ambiguous' | 'not_found' | 'out_of_scope'
      - `chosen` TeacherCandidate
        - `id` string, required
        - `kind` 'account' | 'invitation', required
        - `first_name` string, nullable
        - `last_name` string, nullable
        - `email` string
        - `in_school` boolean
        - `reason` string
      - `candidates` TeacherCandidate[]
        - `id` string, required
        - `kind` 'account' | 'invitation', required
        - `first_name` string, nullable
        - `last_name` string, nullable
        - `email` string
        - `in_school` boolean
        - `reason` string
      - `reason` string
      - `invite_email` string, nullable
      - `locked` boolean
    - `groups` PlanGroup[], required
      - `id` string, required
      - `name` string, required
      - `subject` 'maths' | 'physique-chimie' | 'maths-complementaires' | 'maths-expertes', required
      - `grade` 'sixieme' | 'cinquieme' | 'quatrieme' | 'troisieme' | 'seconde' | 'premiere' | 'terminale' | 'prepa', nullable
      - `teacher_ids` string[]
      - `candidate_teacher_ids` string[]
      - `student_ids` string[]
      - `divisions` string[]
      - `origin` 'file' | 'school_answer' | 'admin'
      - `rule` string, nullable
      - `rule_key` string, nullable
      - `readiness` 'ready' | 'probable' | 'waiting' | 'excluded', nullable
      - `status` 'up_to_date' | 'to_create' | 'to_complete' | 'to_confirm' | 'waiting_school' | 'excluded'
      - `reason` string
      - `hint` string, nullable
      - `links` ClassLink[]
        - `class_id` string, required
        - `class_name` string, required
        - `class_code` string, nullable
        - `teacher_ref` string, required
        - `teacher_kind` 'account' | 'invitation'
        - `matched` integer
        - `group_size` integer
        - `by` 'overlap' | 'admin'
      - `applied` AppliedClass[]
        - `teacher_id` string, required
        - `class_id` string, nullable
        - `class_code` string, nullable
        - `class_name` string, nullable
        - `pending_class_id` string, nullable
        - `created` boolean
        - `completed` boolean
        - `students_added` integer
        - `students_skipped` integer
        - `invitations_sent` integer
        - `student_ids_sent` string[]
        - `skipped_reason` string, nullable
        - `error` string, nullable
        - `at` string, date-time, nullable
      - `name_edited` boolean
      - `students_edited` boolean
      - `teachers_edited` boolean
      - `status_locked` boolean
    - `questions` PlanQuestion[], required
      - `id` string, required
      - `text` string, required
      - `detail` string
      - `category` 'groups' | 'teachers' | 'students' | 'file'
      - `group_ids` string[]
      - `teacher_ids` string[]
      - `student_ids` string[]
      - `status` 'open' | 'closed'
      - `answer` string, nullable
      - `origin` 'rule' | 'admin' | 'assistant' | 'mcp'
      - `rule_key` string, nullable
      - `closed_at` string, date-time, nullable
      - `closed_by` PlanAuthor — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
        - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
        - `email` string, nullable
        - `name` string, nullable
      - `sent_at` string, date-time, nullable
    - `notes` string[], required
    - `school_contact_name` string, nullable
    - `school_contact_email` string, nullable
    - `message_subject` string, required
    - `message_body` string, required
    - `message_sent_at` string, date-time, nullable
    - `message_sent_by` PlanAuthor — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
      - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
      - `email` string, nullable
      - `name` string, nullable
    - `history` HistoryEntry[], required
      - `revision` integer, required
      - `at` string, date-time, required
      - `kind` string, required
      - `summary` string, required
      - `payload` object
      - `author` PlanAuthor, required — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
        - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
        - `email` string, nullable
        - `name` string, nullable
      - `proposed_by` PlanAuthor — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
        - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
        - `email` string, nullable
        - `name` string, nullable
      - `proposal_id` string, nullable
      - `touched` string[]
    - `proposals` ProposalResponse[], required
      - `id` string, required
      - `title` string, required
      - `message` string
      - `author` PlanAuthor, required — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
        - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
        - `email` string, nullable
        - `name` string, nullable
      - `created_at` string, date-time, required
      - `base_revision` integer, required
      - `items` ProposalItem[]
        - `operation` union, required
          - AddSourceOpOutput
            - `kind` 'add_source'
            - `source` PlanSourceOutput, required
              - …
          - RemoveSourceOp
            - `kind` 'remove_source'
            - `source_id` string, required
          - SetSheetMappingOpOutput
            - `kind` 'set_sheet_mapping'
            - `mapping` SheetMappingOutput, required
              - …
          - SetMappingSummaryOp
            - `kind` 'set_mapping_summary'
            - `summary` string, required
          - SetColumnMeaningOp
            - `kind` 'set_column_meaning'
            - `source_id` string, required
            - `sheet` string, required
            - `column` string, required
            - `meaning` string, required
            - `subject` 'maths' | 'physique-chimie' | 'maths-complementaires' | 'maths-expertes', nullable
            - `region_index` integer
          - SetPopulationFilterOp
            - `kind` 'set_population_filter'
            - `source_id` string, required
            - `sheet` string, required
            - `column` string, nullable
            - `values` string[]
          - SplitGroupOp
            - `kind` 'split_group'
            - `group_id` string, required
            - `parts` GroupPart[], required
              - …
            - `origin` 'file' | 'school_answer' | 'admin'
          - MergeGroupsOp
            - `kind` 'merge_groups'
            - `group_ids` string[], required
            - `name` string, nullable
            - `group_id` string, nullable
          - MoveStudentsOp
            - `kind` 'move_students'
            - `student_ids` string[], required
            - `from_group_id` string, nullable
            - `to_group_id` string, required
          - AddGroupOp
            - `kind` 'add_group'
            - `name` string, required
            - `subject` 'maths' | 'physique-chimie' | 'maths-complementaires' | 'maths-expertes', required
            - `grade` 'sixieme' | 'cinquieme' | 'quatrieme' | 'troisieme' | 'seconde' | 'premiere' | 'terminale' | 'prepa', nullable
            - `student_ids` string[]
            - `divisions` string[]
            - `teacher_ids` string[]
            - `group_id` string, nullable
            - `origin` 'file' | 'school_answer' | 'admin'
          - RemoveGroupOp
            - `kind` 'remove_group'
            - `group_id` string, required
          - RenameGroupOp
            - `kind` 'rename_group'
            - `group_id` string, required
            - `name` string, required
          - SetTeachersOp
            - `kind` 'set_teachers'
            - `group_id` string, required
            - `teacher_ids` string[], required
          - SetGroupStatusOp
            - `kind` 'set_group_status'
            - `group_id` string, required
            - `status` 'up_to_date' | 'to_create' | 'to_complete' | 'to_confirm' | 'waiting_school' | 'excluded', nullable
            - `reason` string
          - LinkExistingClassOp
            - `kind` 'link_existing_class'
            - `group_id` string, required
            - `class_id` string, nullable
          - ResolveTeacherOp
            - `kind` 'resolve_teacher'
            - `teacher_id` string, required
            - `status` 'account' | 'invitation' | 'to_invite' | 'ambiguous' | 'not_found' | 'out_of_scope', required
            - `candidate_id` string, nullable
          - InviteTeacherOp
            - `kind` 'invite_teacher'
            - `teacher_id` string, required
            - `email` string, required
          - AddTeacherOp
            - `kind` 'add_teacher'
            - `last_name` string, required
            - `first_name` string
            - `email` string, nullable
            - `subjects` string[]
            - `teacher_id` string, nullable
          - AddQuestionOp
            - `kind` 'add_question'
            - `text` string, required
            - `detail` string
            - `category` 'groups' | 'teachers' | 'students' | 'file'
            - `group_ids` string[]
            - `teacher_ids` string[]
            - `student_ids` string[]
            - `question_id` string, nullable
          - CloseQuestionOp
            - `kind` 'close_question'
            - `question_id` string, required
            - `answer` string
          - AddStudentOp
            - `kind` 'add_student'
            - `last_name` string, required
            - `first_name` string, required
            - `email` string, nullable
            - `division` string, nullable
            - `group_ids` string[]
            - `student_id` string, nullable
          - RemoveStudentOp
            - `kind` 'remove_student'
            - `student_id` string, required
          - EditStudentOp
            - `kind` 'edit_student'
            - `student_id` string, required
            - `first_name` string, nullable
            - `last_name` string, nullable
            - `email` string, nullable
            - `division` string, nullable
          - SetSchoolContactOp
            - `kind` 'set_school_contact'
            - `name` string, nullable
            - `email` string, nullable
          - MarkMessageSentOp
            - `kind` 'mark_message_sent'
          - ApplyGroupsOp
            - `kind` 'apply_groups'
            - `group_ids` string[]
            - `options` ApplyOptions
              - …
            - `run_id` string, nullable
          - RefreshMatchingOpOutput
            - `kind` 'refresh_matching'
            - `context` SchoolContextOutput, required
              - …
          - RecordGroupAppliedOp
            - `kind` 'record_group_applied'
            - `run_id` string, required
            - `group_id` string, required
            - `results` AppliedClass[], required
              - …
          - FinishApplyOp
            - `kind` 'finish_apply'
            - `run_id` string, required
            - `error` string, nullable
        - `label` LabelPart[]
          - `kind` 'text' | 'strong' | 'del' | 'ins'
          - `value` string, required
        - `status` 'pending' | 'applied' | 'refused' | 'failed'
        - `error` string, nullable
        - `applied_revision` integer, nullable
      - `status` 'pending' | 'applied' | 'partial' | 'refused'
      - `decided_by` PlanAuthor — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
        - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
        - `email` string, nullable
        - `name` string, nullable
      - `decided_at` string, date-time, nullable
      - `notes` string[]
      - `stale` object
    - `apply_run` ApplyRun
      - `id` string, required
      - `status` 'running' | 'done' | 'failed'
      - `group_ids` string[]
      - `done_group_ids` string[]
      - `options` ApplyOptions
        - `send_student_invitations` boolean
        - `prepare_invited_teacher_classes` boolean
        - `invite_missing_teachers` boolean
      - `requested_by` PlanAuthor, required — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
        - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
        - `email` string, nullable
        - `name` string, nullable
      - `started_at` string, date-time, required
      - `finished_at` string, date-time, nullable
      - `error` string, nullable
    - `school_fetched_at` string, date-time, nullable
    - `school_classes` SchoolClassOption[], required
      - `id` string, required
      - `name` string, required
      - `code` string, nullable
      - `teacher_id` string, required
      - `teacher_kind` string, required
      - `teacher_name` string
      - `roster_size` integer
    - `school_teachers` SchoolTeacherOption[], required
      - `id` string, required
      - `kind` string, required
      - `name` string, required
      - `email` string, required
      - `in_school` boolean
    - `assistant_messages` AssistantMessage[], required
      - `id` string, required
      - `role` 'user' | 'assistant', required
      - `author` PlanAuthor, required — Who did something: an admin, the page assistant or Claude through the MCP (both acting for an admin), the model reading a file, the system.
        - `kind` 'admin' | 'assistant' | 'mcp' | 'system' | 'model', required
        - `email` string, nullable
        - `name` string, nullable
      - `content` string, required
      - `at` string, date-time, required
      - `proposal_id` string, nullable
  - `created` boolean, required

## Other responses

- `404` — Resource not found
- `409` — Business rule violated
- `422` — Validation Error

## Changes

> 30 revisions in range; 1 not diffed.

- **2026-10-02** `a0b4ce9a0d8f` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/excellence-ai/apis/excellence-learning/changes/admin/import-plans/post.md)

---

[API](https://skmtc.dev/excellence-ai/apis/excellence-learning.md) · [All operations](https://skmtc.dev/excellence-ai/apis/excellence-learning/llms.txt) · [OpenAPI document](https://skmtc.dev/excellence-ai/apis/excellence-learning/revisions/a0b4ce9a0d8f?raw)
