Skip to content

Registration API ​

Base URL: /api/v1/registration

Manage course enrollment, registration transactions, waitlists, holds, and degree planning.

Endpoints Overview ​

Enrollments ​

MethodEndpointDescription
GET/enrollmentsList enrollments
POST/enrollmentsCreate enrollment
GET/enrollments/{id}Get enrollment details
PATCH/enrollments/{id}Update enrollment
DELETE/enrollments/{id}Delete enrollment
POST/enrollments/registerRegister for a section
POST/enrollments/quick_registerQuick register with validation
GET/enrollments/by_studentGet enrollments by student
GET/enrollments/by_sectionGet enrollments by section
POST/enrollments/dropDrop or withdraw from a section (or request it, when advisor approval applies)
GET/enrollments/drop_previewWhat a drop would do today
POST/enrollments/enter_gradeEnter grade for enrollment
GET/enrollment-historyA student's enrollment status changes

Term Enrollments ​

MethodEndpointDescription
GET/term-enrollmentsList term enrollment summaries
GET/term-enrollments/{id}Get term enrollment details

Waitlists ​

MethodEndpointDescription
GET/waitlistsList waitlist entries (staff)
POST/waitlistsJoin a waitlist
GET/waitlists/for_studentA student's own waitlist entries
POST/waitlists/{waitlistID}/leaveLeave a waitlist (student)
DELETE/waitlists/{waitlistID}Remove from waitlist (staff)

Holds ​

MethodEndpointDescription
GET/hold-typesList hold types
POST/hold-types/{holdTypeID}/run_auto_createRun auto-create for one hold type
GET/student-holdsList student holds
POST/student-holdsCreate hold
GET/student-holds/my_holdsHolds on the caller's own record
POST/student-holds/bulk_createPlace holds on many students
POST/student-holds/bulk_create_from_listPlace holds from a student list
GET/student-holds/my_holdsGet current user's holds
POST/student-holds/check_holdsCheck holds for a student
POST/student-holds/bulk_createBulk create holds
POST/student-holds/{holdID}/clearClear one hold

GPA & Class Standing ​

MethodEndpointDescription
GET/gpaCalculate GPA
GET/class-standingGet class standing
POST/gpa/bulk-recalculateRecalculate GPA for multiple students

Degree Planning ​

MethodEndpointDescription
GET/planningList planned courses
POST/planningAdd planned course
DELETE/planning/{plannedID}Remove planned course
POST/planning/check_prerequisitesPrerequisite check (with minimum grades)
POST/planning/check_corequisitesCorequisite check
POST/planning/check_credit_limitCredit load and overload check
POST/planning/check_repeatRepeat-limit check
POST/planning/convert_to_registrationSubmit a term's plans as a registration request
POST/students/{studentID}/failed-course-cascadeRemove plans stranded by a failed course

Transactions ​

MethodEndpointDescription
GET/transactions/mineThe caller's own transactions
POST/transactionsCreate registration transaction
DELETE/transactions/{transactionID}Cancel a transaction
POST/transactions/{transactionID}/validateValidate transaction
POST/transactions/{transactionID}/submitSubmit transaction
POST/transactions/{transactionID}/completeComplete transaction
POST/transactions/{transactionID}/add_itemAdd an item to a transaction
DELETE/transactions/{transactionID}/items/{itemID}Remove an item
POST/transactions/{transactionID}/transitionMove the transaction to another step
POST/transactions/{transactionID}/overrideApply a registration override
GET/transactions/{transactionID}/historyTransaction history
GET / POST/transactions/{transactionID}/notesRead / add notes (student, registrar)

Approvals ​

MethodEndpointDescription
GET/approvalsRequests waiting for the caller's decision
GET/approvals/{transactionID}One request, as the approver sees it
POST/transactions/{transactionID}/approveApprove
POST/transactions/{transactionID}/rejectReject with a reason
GET / POST/approvals/{transactionID}/notesRead / add notes (advisor, registrar)

Hold Evaluation Logs ​

MethodEndpointDescription
GET/hold-evaluation-logsList hold evaluation logs

Enrollments ​

List Enrollments ​

GET /api/v1/registration/enrollments

Query Parameters ​

ParameterTypeDescription
studentintegerFilter by student ID
student_idintegerFilter by student ID (alias)
sectionintegerFilter by section ID
section_idintegerFilter by section ID (alias)
term_idintegerFilter by term ID
status_idintegerFilter by status
grade_idintegerFilter by grade
is_auditbooleanFilter audit enrollments
is_pass_failbooleanFilter pass/fail enrollments
searchstringSearch by student number, course code

Success Response (200 OK) ​

json
{
  "count": 25000,
  "results": [
    {
      "enrollment_id": 1,
      "student_id": 1001,
      "student_number": "STU001234",
      "section_id": 512,
      "course_code": "MATH 101",
      "course_title": "College Algebra",
      "section_code": "001",
      "term_code": "FA2024",
      "status_code": "REGISTERED",
      "status_display": "Registered",
      "registration_date": "2024-04-15",
      "grade": null,
      "is_graded": false,
      "credits_attempted": 3.0,
      "credits_earned": 0.0,
      "is_audit": false,
      "is_pass_fail": false
    }
  ]
}

Get Enrollment Details ​

GET /api/v1/registration/enrollments/{id}

Success Response (200 OK) ​

json
{
  "enrollment_id": 1,
  "student_id": 1001,
  "student_number": "STU001234",
  "student_name": "John Smith",
  "section_id": 512,
  "course_code": "MATH 101",
  "course_title": "College Algebra",
  "section_code": "001",
  "term_id": 8,
  "term_code": "FA2024",
  "term_name": "Fall 2024",
  "status_id": 1,
  "status_code": "REGISTERED",
  "status_display": "Registered",
  "registration_date": "2024-04-15",
  "drop_date": null,
  "grade_id": null,
  "grade": null,
  "grade_display": null,
  "grade_date": null,
  "is_graded": false,
  "credits_attempted": 3.0,
  "credits_earned": 0.0,
  "is_audit": false,
  "is_pass_fail": false,
  "notes": null,
  "created_at": "2024-04-15T10:30:00Z",
  "updated_at": "2024-04-15T10:30:00Z"
}

TypeScript Types ​

typescript
interface Enrollment {
  enrollment_id: number
  student_id: number
  student_number: string
  student_name?: string
  section_id: number
  course_code: string
  course_title: string
  section_code: string
  term_id: number
  term_code: string
  term_name?: string
  status_id: number
  status_code: string
  status_display: string
  registration_date: string
  drop_date: string | null
  grade_id: number | null
  grade: string | null
  grade_display: string | null
  grade_date: string | null
  is_graded: boolean
  credits_attempted: number
  credits_earned: number
  is_audit: boolean
  is_pass_fail: boolean
  notes: string | null
}

Create Enrollment ​

POST /api/v1/registration/enrollments

Request Body ​

FieldTypeRequiredDescription
student_idintegerYesStudent ID
section_idintegerYesSection ID
is_auditbooleanNoAudit enrollment
is_pass_failbooleanNoPass/fail grading
notesstringNoEnrollment notes

Register for Section ​

POST /api/v1/registration/enrollments/register

Register a student for a course section with full validation.

Request Body ​

FieldTypeRequiredDescription
student_idintegerYesStudent ID
section_idintegerYesSection ID
is_auditbooleanNoAudit enrollment
is_pass_failbooleanNoPass/fail option
creditsnumberNoThe chosen credits on a variable-credit section (migration 279). Must lie within the section's range, on its credit_increment grid from the minimum (the maximum is always allowed). Defaults to the minimum; ignored on a fixed section. Recorded as credits_attempted
allow_repeatbooleanNoRegister despite a repeat restriction. Needs REGISTRATION.OVERRIDE.DUPLICATE
override_sequence, sequence_override_reasonboolean, stringNoBypass a sequencing deadline. Needs REGISTRATION.OVERRIDE.SEQUENCE
override_capacity, capacity_override_reasonboolean, stringNoEnroll into a full section. Needs REGISTRATION.OVERRIDE.CAPACITY

Validations Performed ​

  • Section availability and capacity
  • The term's registration period and the student's registration window. A caller holding REGISTRATION.OVERRIDE.DEADLINE is not held to the window
  • Repeat limits (COURSE_REPEAT)
  • Sequencing deadlines
  • Hold checks

Credit limits are not checked on this route. They apply to registration transactions.

Success Response (201 Created) ​

json
{
  "enrollment_id": 150,
  "student_id": 1001,
  "section_id": 512,
  "course_code": "MATH 101",
  "status_code": "REGISTERED",
  ...
}

Error Response (400 Bad Request) ​

json
{
  "error": "Section MATH 101-001 is full. Enrollment: 30/30"
}

Quick Register ​

POST /api/v1/registration/enrollments/quick_register

Register with full prerequisite validation and optional override.

Request Body ​

FieldTypeRequiredDescription
student_idintegerYesStudent ID
section_idintegerYesSection ID
override_prerequisitesbooleanNoSkip prerequisite check
override_reasonstringConditionalReason for override

Error Response with Prerequisites ​

json
{
  "success": false,
  "error": "Prerequisites not met",
  "prerequisites": [
    {
      "course_code": "MATH 095",
      "min_grade": "C",
      "status": "NOT_COMPLETED"
    }
  ],
  "can_override": true
}

Enrollments by Student ​

GET /api/v1/registration/enrollments/by_student

Get all enrollments for a specific student.

Query Parameters ​

ParameterTypeDescription
student_idintegerStudent ID
term_idintegerFilter by term

Enrollments by Section ​

GET /api/v1/registration/enrollments/by_section

Get all enrollments for a specific section.

Query Parameters ​

ParameterTypeDescription
section_idintegerSection ID

Drop Enrollment ​

POST /api/v1/registration/enrollments/drop

Drop a student from an enrolled section. Whether it is a drop or a withdrawal is decided by the section's term deadlines (see Drops and Withdrawals).

Request Body ​

FieldTypeRequiredDescription
student_idintegerYesStudent ID
section_idintegerYesSection ID
reasonstringNoReason, recorded in the enrollment history (and as the first note when the drop becomes a request)

Outcomes ​

StatusoutcomeWhen
200DROPPEDOn or before drop_deadline: status DROPPED, off the transcript
200WITHDRAWNAfter drop_deadline, on or before withdrawal_deadline: status WITHDRAWN, a W
202PENDING_APPROVALThe caller is the student and DROP_REQUIRES_ADVISOR_APPROVAL / WITHDRAWAL_REQUIRES_ADVISOR_APPROVAL is on: a one-item transaction was created and submitted; nothing changed yet
409—After withdrawal_deadline (no override on this route: use a transaction with override_deadline), or the enrollment is already dropped or withdrawn
404—The student has no enrollment in the section
json
{
  "success": true,
  "message": "Your withdrawal request was sent to your advisor for approval.",
  "outcome": "PENDING_APPROVAL",
  "phase": "WITHDRAW",
  "transaction_id": 4812
}

phase is DROP or WITHDRAW. A completed drop sets drop_date, offers the seat to the waitlist and emails the student and their advisors (COURSE_DROP_* templates).


Drop Preview ​

GET /api/v1/registration/enrollments/drop_preview?student_id={id}&section_id={id}

What dropping the section would do today, for the confirmation dialog. Writes nothing.

json
{
  "phase": "WITHDRAW",
  "drop_deadline": "2026-09-30",
  "withdrawal_deadline": "2026-11-13",
  "appears_on_transcript": true,
  "requires_advisor_approval": false
}
FieldDescription
phaseDROP, WITHDRAW or CLOSED (too late without a registrar override)
drop_deadline, withdrawal_deadlineThe term's dates; omitted when unset (an unset deadline is not enforced)
appears_on_transcriptTrue for a withdrawal
requires_advisor_approvalTrue when this caller's request would wait for the primary advisor

Enter Grade ​

POST /api/v1/registration/enrollments/enter_grade

Enter or update a grade for an enrollment.

Request Body ​

FieldTypeRequiredDescription
enrollment_idintegerYesEnrollment ID
grade_idintegerYesGrade lookup ID
grade_datedateNoDate grade was assigned

Waitlists ​

List Waitlist Entries ​

GET /api/v1/registration/waitlists

Query Parameters ​

ParameterTypeDescription
sectionintegerFilter by section ID
studentintegerFilter by student ID

Waitlist entry ​

Every waitlist route returns entries in this shape:

json
{
  "waitlist_id": 1,
  "section_id": 512,
  "student_id": 1001,
  "position": 1,
  "added_at": "2026-04-15T11:00:00Z",
  "status_id": 2,
  "status_code": "NOTIFIED",
  "status_display": "Notified",
  "is_waiting": false,
  "is_notified": true,
  "notified_at": "2026-04-20T09:12:00Z",
  "notification_expires_at": "2026-04-22T09:12:00Z",
  "student_number": "STU001234",
  "student_name": "John Smith",
  "course_code": "MATH 101",
  "course_title": "College Algebra",
  "section_code": "001",
  "term_code": "2026FA",
  "term_name": "Fall 2026",
  "created_at": "2026-04-15T11:00:00Z",
  "updated_at": "2026-04-20T09:12:00Z"
}
FieldDescription
status_codeWAITING, NOTIFIED, EXPIRED, ENROLLED or REMOVED
positionPlace in line among the entries still open (closes up as others leave)
is_notifiedA seat has been offered and the offer has not lapsed. False once notification_expires_at has passed, even before the row is marked EXPIRED
notification_expires_at48 hours after the offer
removed_at, removal_reasonSet when the entry closes (Enrolled, Offer expired, ...)

A freed seat (drop, withdrawal, cancelled request, cascade, an offer-holder leaving) is offered to the next WAITING entry. The offer is a notice only: the seat is not held, and no email is sent. See Waitlist.


Join a Waitlist ​

POST /api/v1/registration/waitlists

Gated on REGISTRATION.REGISTER, so a student can join for themselves.

Request Body ​

FieldTypeRequiredDescription
student_idintegerYesStudent ID
section_idintegerYesSection ID

Returns 201 with the entry. Refused with 409 when the section still has open seats, its positive waitlist_capacity is reached, the student is already on the list or enrolled. Also refused by a hold that blocks everything, or before the student's registration window opens.


A Student's Waitlists ​

GET /api/v1/registration/waitlists/for_student?student_id={id}
POST /api/v1/registration/waitlists/{waitlistID}/leave

The student-facing pair, on REGISTRATION.REGISTER and limited to the caller's own record. for_student returns a paginated envelope of entries. leave closes the entry as REMOVED (204) and offers any seat the student held on offer to the next in line. Staff remove an entry with DELETE /waitlists/{waitlistID} (REGISTRATION.WAITLISTS).

POST /waitlists/{waitlistID}/convert_to_transaction (REGISTRATION.WAITLISTS) is the staff screen's Promote. It adds the entry's section as an ADD item to the student's IN_PROGRESS transaction for the section's term, creating one when none is open, and returns that transaction (200, the same shape as GET /transactions/{id}). The body is optional: {"campus_id": n} is used only when a transaction is created.

StatusWhen
404No such entry, or outside the caller's student scope
409The entry is closed; the student's transaction for the term is SUBMITTED; or the section is already in it

The entry stays open until the enrollment is written, when it is closed as ENROLLED.


Holds ​

List Hold Types ​

GET /api/v1/registration/hold-types

Success Response (200 OK) ​

json
{
  "count": 10,
  "results": [
    {
      "hold_type_id": 1,
      "hold_type_code": "FINANCIAL",
      "name": "Financial Hold",
      "description": "Outstanding balance due",
      "prevents_registration": true,
      "prevents_transcript": true,
      "prevents_graduation": true,
      "is_active": true
    }
  ]
}

Auto-Create Hold Types ​

POST /api/v1/registration/hold-types/{holdTypeID}/run_auto_create

Automatically create standard hold types based on system defaults.


List Student Holds ​

GET /api/v1/registration/student-holds

Query Parameters ​

ParameterTypeDescription
studentintegerFilter by student ID
hold_typeintegerFilter by hold type
is_activebooleanFilter active holds

Success Response (200 OK) ​

json
{
  "count": 25,
  "results": [
    {
      "hold_id": 1,
      "student_id": 1001,
      "student_number": "STU001234",
      "student_name": "John Smith",
      "hold_type_id": 1,
      "hold_type_code": "FINANCIAL",
      "hold_type_name": "Financial Hold",
      "reason": "Outstanding tuition balance",
      "placed_date": "2024-11-01",
      "placed_by": "bursar@university.edu",
      "release_date": null,
      "released_by": null,
      "is_active": true,
      "prevents_registration": true,
      "prevents_transcript": true
    }
  ]
}

Create Hold ​

POST /api/v1/registration/student-holds

Request Body ​

FieldTypeRequiredDescription
student_idintegerYesStudent ID
hold_type_idintegerYesHold type ID
reasonstringNoReason for hold
placed_datedateNoDate placed (default: today)

Release Hold ​

POST /api/v1/registration/student-holds/{holdID}/clear

Holds are cleared, not edited: there is no PATCH or DELETE on /student-holds. Clearing end-dates the hold and leaves the record in place, so the history of why a student was held survives.


My Holds ​

GET /api/v1/registration/student-holds/my_holds

Get holds for the currently authenticated student.


Check Holds ​

POST /api/v1/registration/student-holds/check_holds

Check if a student has any active holds that prevent registration.

Query Parameters ​

ParameterTypeDescription
student_idintegerStudent ID to check

Bulk Create Holds ​

POST /api/v1/registration/student-holds/bulk_create

Create holds for multiple students at once.

Request Body ​

json
{
  "student_ids": [1001, 1002, 1003],
  "hold_type_id": 1,
  "reason": "Outstanding balance"
}

Clear Holds ​

POST /api/v1/registration/student-holds/{holdID}/clear

Clear (release) holds for a student or set of students.

Request Body ​

json
{
  "student_ids": [1001, 1002],
  "hold_type_id": 1
}

Transactions ​

Create Transaction ​

POST /api/v1/registration/transactions

Create a new registration transaction.


Validate Transaction ​

POST /api/v1/registration/transactions/{transactionID}/validate

Validate a registration transaction before submission.


Submit Transaction ​

POST /api/v1/registration/transactions/{transactionID}/submit

Submit a registration transaction for processing.


Complete Transaction ​

POST /api/v1/registration/transactions/{transactionID}/complete

Mark a registration transaction as complete.


Transition Transaction ​

POST /api/v1/registration/transactions/{id}/transition

Transition a transaction to a new state.


Override Transaction ​

POST /api/v1/registration/transactions/{transactionID}/override

Excuse specific validation failures. Needs REGISTRATION.OVERRIDE.

FieldTypeRequiredDescription
reasonstringYesMax 1,000 characters. Also written to the notes thread as an OVERRIDE note
override_prereqsbooleanNoUnmet prerequisites
override_deadlinebooleanNoREGISTRATION_CLOSED (the term's period or the student's registration window) and DROP_DEADLINE (a drop after the withdrawal deadline)
override_credit_limitbooleanNoCREDIT_LIMIT (over the normal load)
override_campusbooleanNoCAMPUS_MISMATCH
override_sequencebooleanNoSEQUENCE_DEADLINE
override_repeatbooleanNoCOURSE_REPEAT. Also needs REGISTRATION.OVERRIDE.DUPLICATE (403 otherwise)

At least one flag is required. Overrides accumulate and are never cleared by a later call. A closed (completed or cancelled) transaction is refused with 409. Validation messages that an override covers drop to INFO severity with "(overridden)" appended. The validation state reports needs_*_override and applied_*_override for each kind.

Overload requests (migration 296) also carry is_overload_request, overload_reason, overload_credits, overload_advisor_approved_at and overload_advisor_name.


Approvals ​

GET  /api/v1/registration/approvals
GET  /api/v1/registration/approvals/{transactionID}
POST /api/v1/registration/transactions/{transactionID}/approve
POST /api/v1/registration/transactions/{transactionID}/reject

On REGISTRATION.APPROVALS. Which role may decide is the PENDING_APPROVAL step's role list. An advisor decides only for students they are primary advisor to.

reject takes {"reason": "..."} (required, max 1,000). The transaction returns to DRAFT with its seats, and the reason is also written as a REJECT note.

approve enrolls every item together or none. Possible outcome values include COMPLETED, BOUNCED (nothing enrolled, returned to the student), APPROVED_PENDING_CLEARANCE (a blocks-completion hold), and OVERLOAD_ADVISOR_APPROVED. The last means the primary advisor's signature on an overload request was recorded and the request waits for the registrar. The registrar approving an overload before the advisor gets 409, unless the student has no current primary advisor.


Transaction Notes ​

GET  /api/v1/registration/transactions/{transactionID}/notes
POST /api/v1/registration/transactions/{transactionID}/notes
GET  /api/v1/registration/approvals/{transactionID}/notes
POST /api/v1/registration/approvals/{transactionID}/notes

One append-only thread per transaction (migration 278). The /transactions/... pair is on REGISTRATION.REGISTER (student, registrar) and the /approvals/... pair on REGISTRATION.APPROVALS (advisor, registrar). Both apply the same row-level visibility.

POST body: {"note_text": "..."}, 1 to 2,000 characters. There is no edit or delete route, and the database refuses UPDATE, DELETE and TRUNCATE on the table.

json
{
  "note_id": 912,
  "transaction_id": 4812,
  "note_kind": "NOTE",
  "note_text": "Please confirm the lab section works with your job.",
  "step_id": 40,
  "step_name": "Pending Approval",
  "author_person_id": "8b0c...",
  "author_name": "Dana Advisor",
  "author_role_code": "ADVISOR",
  "created_at": "2026-10-20T14:03:00Z"
}

note_kind is NOTE, OVERRIDE or REJECT. The list is oldest first.


Hold Evaluation Logs ​

List Hold Evaluation Logs ​

GET /api/v1/registration/hold-evaluation-logs

View logs of hold evaluation runs.


GPA Calculation ​

Calculate GPA ​

GET /api/v1/registration/gpa

Query Parameters ​

ParameterTypeRequiredDescription
student_idintegerYesStudent ID
term_idintegerNoSpecific term (cumulative if omitted)

Success Response (200 OK) ​

json
{
  "student_id": 1001,
  "gpa_type": "cumulative",
  "gpa": 3.45,
  "credits_attempted": 48.0,
  "credits_earned": 45.0,
  "quality_points": 165.6,
  "courses_completed": 16
}

Class Standing ​

GET /api/v1/registration/class-standing

Query Parameters ​

ParameterTypeRequiredDescription
student_idintegerYesStudent ID

Success Response (200 OK) ​

json
{
  "student_id": 1001,
  "class_standing": "Sophomore",
  "credits_earned": 45.0,
  "thresholds": {
    "freshman": { "min": 0, "max": 29 },
    "sophomore": { "min": 30, "max": 59 },
    "junior": { "min": 60, "max": 89 },
    "senior": { "min": 90, "max": null }
  }
}

Degree Planning ​

List Planned Courses ​

GET /api/v1/registration/planning

Query Parameters ​

ParameterTypeDescription
studentintegerFilter by student ID
termintegerFilter by planned term
statusstringFilter by status (PLANNED, COMPLETED, DROPPED)

Success Response (200 OK) ​

json
{
  "count": 8,
  "results": [
    {
      "planned_course_id": 1,
      "student_id": 1001,
      "course_id": 201,
      "course_code": "CS 201",
      "course_title": "Data Structures",
      "credits": 3,
      "planned_term_id": 9,
      "planned_term_code": "SP2025",
      "status": "PLANNED",
      "notes": "Required for major",
      "created_at": "2024-11-15T10:00:00Z"
    }
  ]
}

Add Planned Course ​

POST /api/v1/registration/planning

Request Body ​

FieldTypeRequiredDescription
student_idintegerYesStudent ID
section_idintegerYesSection to plan (the term comes from it)
requirement_item_id, requirement_block_idintegerNoThe requirement this plan is for
credits_selectednumberNoChosen credits on a variable-credit section; validated against the section's range and increment, ignored otherwise
override_prereq, prereq_override_reasonboolean, stringNoPlan despite an unmet prerequisite. Needs REGISTRATION.OVERRIDE.PREREQ
override_sequence, sequence_override_reasonboolean, stringNoNeeds REGISTRATION.OVERRIDE.SEQUENCE
override_capacity, capacity_override_reasonboolean, stringNoReserve a seat in a full section. Needs REGISTRATION.OVERRIDE.CAPACITY
override_repeat, repeat_override_reasonboolean, stringNoPlan a course the student may not take again. Needs REGISTRATION.OVERRIDE.DUPLICATE and a reason of at least 10 characters; the override is kept on the plan
override_conflict, override_reasonboolean, stringNoSchedule-conflict override (recorded)
notesstringNoPlanning notes

Sequencing and repeat limits are enforced on this route. A repeat refusal comes back as a COURSE_REPEAT error with the reason. The other checks are the advisory endpoints below, which the planning dialog calls first.


Planning Checks ​

All POST, all on REGISTRATION.REGISTER, all read-only.

EndpointBodyReturns
/planning/check_prerequisitesstudent_id, course_id, term_idis_satisfied, messages (MISSING_PREREQ, with the minimum grade and the grade earned when that is why), and prerequisites that are only planned
/planning/check_corequisitesstudent_id, course_id, term_idhas_coreqs and a message naming any corequisite not arranged for the term
/planning/check_credit_limitstudent_id, section_id, credits (optional, for a variable section)See below
/planning/check_repeatstudent_id, section_idblocked, message, attempts, max_attempts (0 = none), limit_source (course, major <code> or institution), can_override
/planning/check_sequencestudent_id, section_idSequencing verdict
/planning/check_conflictsstudent_id, section_idOverlapping meetings

Prerequisites are read from Colleague's requisite rules (course_requisite_links, migration 285): timing P must be met in an earlier term, E in an earlier or the same term, and C rules are corequisites. A pass below the rule's minimum grade (migration 286) does not meet it.

Credit limit check ​

json
{
  "is_within_limit": false,
  "current_term_credits": 15,
  "section_credits": 4,
  "max_credits": 17.5,
  "overload_ceiling": 21,
  "is_overload": true,
  "credits_after_adding": 19,
  "message": "Adding this course would bring your total to 19 credits, above the normal 17.5-credit load. ...",
  "can_override": true
}

max_credits is the student's normal load (MAX_CREDITS_UNDERGRAD or MAX_CREDITS_GRADUATE) and overload_ceiling the matching *_OVERLOAD setting. is_overload means past the normal load but within the ceiling. can_override is false past the ceiling. See Credit Load and Overloads.


Submit Plans for Registration ​

POST /api/v1/registration/planning/convert_to_registration

Submits every PLANNED course the student has in a term as one transaction at PENDING_APPROVAL.

FieldTypeRequiredDescription
student_idintegerYesStudent ID
term_idintegerYesTerm
overload_reasonstringConditionalRequired when the term would pass the normal load (max 1,000 characters)
  • Past the overload ceiling: refused (400) with the total.
  • Past the normal load without overload_reason: a validation error on overload_reason. Resubmit with the reason.
  • Past the normal load with a reason: submitted as an overload request (is_overload_request: true in the response and on the transaction). The primary advisor approves first, then the registrar.
  • Before the student's registration window opens: refused.
json
{
  "success": true,
  "transaction_id": 4812,
  "plans_converted": 6,
  "plans_not_eligible": 0,
  "is_overload_request": true,
  "pending_clearance_hold": null
}

Failed-Course Cascade ​

POST /api/v1/registration/students/{studentID}/failed-course-cascade[?preview=1]

On REGISTRATION.APPROVALS. Cancels the student's PLANNED courses whose prerequisites a failed course, or a pass below a prerequisite's minimum, has made unreachable, down the dependency chain. Plans inside a transaction, plans with a prerequisite override and live enrollments are reported, not touched. preview=1 writes nothing. The same code runs on grade entry, on final-grade release and hourly. This route is for repair and backfill.

The response lists failed_courses, below_minimum_courses and what was (or would be) removed and reported.


Enrollment Status History ​

GET /api/v1/registration/enrollment-history

A student's section-enrollment status changes, newest first. A drop is not on the transcript, but it is here. On REGISTRATION.REGISTER, limited to records the caller may see, so a student reads their own.

Query Parameters ​

ParameterTypeDescription
student_idintegerRequired
term_idintegerNarrow to one term
page, page_sizeintegerPagination

Success Response (200 OK) ​

json
{
  "count": 2,
  "results": [
    {
      "history_id": 2,
      "student_section_enrollment_id": "5f0c...",
      "section_id": 512,
      "course_code": "MATH 101",
      "course_title": "College Algebra",
      "term_code": "2026FA",
      "term_name": "Fall 2026",
      "old_status_code": "REGISTERED",
      "old_status_display": "Registered",
      "new_status_code": "WITHDRAWN",
      "new_status_display": "Withdrawn",
      "changed_at": "2026-10-14T14:00:00Z",
      "changed_by_person_id": "8b0c...",
      "reason": "Dropped after the drop deadline; recorded as a withdrawal (W)",
      "appears_on_transcript": true
    }
  ]
}

GET /enrollment-history/{historyID} is a stub that always returns 404.




Complete endpoint reference ​

Every route this domain registers, with the permission node that gates it. Generated from the route table, so it is complete by construction — the sections above explain behaviour, this one guarantees nothing is missing.

Paths are relative to /api/v1/registration. A node in italics is an exemption rather than a grant: selfservice acts only on the caller's own record, public needs no session at all, and custom carries its own wrapper.

MethodEndpointPermission nodeDescription
GET/approvalsREGISTRATION.APPROVALSList requests awaiting the caller's decision
GET/approvals/{transactionID}REGISTRATION.APPROVALSGet one request (approver view)
GET/approvals/{transactionID}/notesREGISTRATION.APPROVALSList the request's notes
POST/approvals/{transactionID}/notesREGISTRATION.APPROVALSAdd a note
GET/class-standingREGISTRATIONGet class standing
POST/class-standingREGISTRATIONCreate class standing
GET/cohort/cohortsREGISTRATION.COHORT_REGISTRATIONCohorts the caller may register
POST/cohort/planREGISTRATION.COHORT_REGISTRATION.PLANPlan sections for cohort members
POST/cohort/registerREGISTRATION.COHORT_REGISTRATIONRegister cohort members
POST/cohort/validate_sectionREGISTRATION.COHORT_REGISTRATION (VIEW)Each member's verdict for one section
GET/cohort/{cohortID}/membersREGISTRATION.COHORT_REGISTRATIONList cohort members
GET/enrollment-historyREGISTRATION.REGISTERA student's enrollment status changes
GET/enrollment-history/{historyID}REGISTRATIONGet one enrollment history
GET/enrollmentsREGISTRATIONList enrollments
POST/enrollmentsREGISTRATIONCreate a enrollment
GET/enrollments/by_sectionREGISTRATIONGet by section
GET/enrollments/by_studentREGISTRATIONGet by student
POST/enrollments/dropREGISTRATION.REGISTERDrop or withdraw (202 when sent for advisor approval)
GET/enrollments/drop_previewREGISTRATION.REGISTERWhat a drop would do today
POST/enrollments/enter_gradeGRADING.ROSTERCreate enter grade
POST/enrollments/quick_registerREGISTRATION.REGISTERCreate quick register
POST/enrollments/registerREGISTRATION.REGISTERCreate register
DELETE/enrollments/{enrollmentID}REGISTRATIONDelete a enrollment
GET/enrollments/{enrollmentID}REGISTRATIONGet one enrollment
PATCH/enrollments/{enrollmentID}REGISTRATIONUpdate a enrollment
GET/gpaGRADING.GPAGet GPA
POST/gpaGRADING.GPACreate GPA
POST/gpa/bulk-recalculateGRADING.GPABulk recalculate
GET/hold-evaluation-logsREGISTRATION.HOLDSList hold evaluation logs
GET/hold-evaluation-logs/{logID}REGISTRATION.HOLDSGet one hold evaluation log
GET/hold-typesADMIN.HOLD_TYPESList hold types
POST/hold-typesADMIN.HOLD_TYPESCreate a hold type
DELETE/hold-types/{holdTypeID}ADMIN.HOLD_TYPESDelete a hold type
GET/hold-types/{holdTypeID}ADMIN.HOLD_TYPESGet one hold type
PATCH/hold-types/{holdTypeID}ADMIN.HOLD_TYPESUpdate a hold type
POST/hold-types/{holdTypeID}/run_auto_createADMIN.HOLD_TYPESRun auto create for a hold type
POST/holdsREGISTRATION.HOLDSCreate a hold
GET/holds/check/{studentID}REGISTRATION.HOLDSGet one check
GET/holds/student/{studentID}REGISTRATION.HOLDSGet one student
POST/holds/{holdID}/releaseREGISTRATION.HOLDSAdd release to a hold
POST/planned-coursesREGISTRATION.REGISTERCreate a planned cours
DELETE/planned-courses/{plannedID}REGISTRATION.REGISTERDelete a planned cours
PATCH/planned-courses/{plannedID}REGISTRATION.REGISTERUpdate a planned cours
GET/planned-courses/{studentID}REGISTRATION.REGISTERGet one planned cours
GET/planningREGISTRATION.REGISTERGet planning
POST/planningREGISTRATION.REGISTERCreate planning
POST/planning/check_conflictsREGISTRATION.REGISTERCheck conflicts
POST/planning/check_corequisitesREGISTRATION.REGISTERCheck corequisites
POST/planning/check_credit_limitREGISTRATION.REGISTERCheck credit limit
POST/planning/check_prerequisitesREGISTRATION.REGISTERCheck prerequisites
POST/planning/check_repeatREGISTRATION.REGISTERCheck repeat limits
POST/planning/check_sequenceREGISTRATION.REGISTERCheck sequence
POST/planning/convert_to_registrationREGISTRATION.REGISTERConvert to registration
GET/planning/courses_for_patternREGISTRATION.REGISTERGet courses for pattern
GET/planning/search_coursesREGISTRATION.REGISTERList search courses
GET/planning/sections_for_courseREGISTRATION.REGISTERGet sections for course
GET/planning/suggest_prereq_plansREGISTRATION.REGISTERSuggest prereq plans
DELETE/planning/{plannedID}REGISTRATION.REGISTERDelete a planning
GET/planning/{plannedID}REGISTRATION.REGISTERGet one planning
GET/student-holdsREGISTRATION.HOLDSList student holds
POST/student-holdsREGISTRATION.HOLDSCreate a student hold
POST/students/{studentID}/failed-course-cascadeREGISTRATION.APPROVALSRemove plans stranded by a failed course (?preview=1)
POST/student-holds/bulk_createREGISTRATION.HOLDSBulk create
POST/student-holds/bulk_create_from_listREGISTRATION.HOLDSBulk create from list
POST/student-holds/check_holdsREGISTRATION.HOLDSCheck holds
GET/student-holds/my_holdsREGISTRATION.MY_HOLDSList my holds
GET/student-holds/{holdID}REGISTRATION.HOLDSGet one student hold
POST/student-holds/{holdID}/clearREGISTRATION.HOLDSClear for a student hold
GET/term-enrollmentsREGISTRATIONList term enrollments
POST/term-enrollmentsREGISTRATIONCreate a term enrollment
DELETE/term-enrollments/{enrollmentID}REGISTRATIONDelete a term enrollment
GET/term-enrollments/{enrollmentID}REGISTRATIONGet one term enrollment
PATCH/term-enrollments/{enrollmentID}REGISTRATIONUpdate a term enrollment
GET/transactionsREGISTRATION.ALL_TRANSACTIONSList transactions
POST/transactionsREGISTRATION.REGISTERCreate a transaction
GET/transactions/mineREGISTRATION.MY_TRANSACTIONS (VIEW)The caller's own transactions
DELETE/transactions/{transactionID}REGISTRATION.REGISTERCancel a transaction
GET/transactions/{transactionID}REGISTRATION.REGISTERGet one transaction
POST/transactions/{transactionID}/add_itemREGISTRATION.REGISTERAdd item for a transaction
POST/transactions/{transactionID}/approveREGISTRATION.APPROVALSApprove a request
POST/transactions/{transactionID}/completeREGISTRATION.REGISTERComplete for a transaction
GET/transactions/{transactionID}/historyREGISTRATION.REGISTERGet the transaction's history
DELETE/transactions/{transactionID}/items/{itemID}REGISTRATION.REGISTERDelete a item
GET/transactions/{transactionID}/notesREGISTRATION.REGISTERList the transaction's notes
POST/transactions/{transactionID}/notesREGISTRATION.REGISTERAdd a note
POST/transactions/{transactionID}/overrideREGISTRATION.OVERRIDEOverride for a transaction
POST/transactions/{transactionID}/rejectREGISTRATION.APPROVALSReject a request with a reason
POST/transactions/{transactionID}/submitREGISTRATION.REGISTERSubmit for a transaction
POST/transactions/{transactionID}/transitionREGISTRATION.REGISTERTransition for a transaction
POST/transactions/{transactionID}/validateREGISTRATION.REGISTERValidate for a transaction
POST/waitlistREGISTRATION.REGISTERCreate waitlist
GET/waitlist/section/{sectionID}REGISTRATION.WAITLISTSGet one section
GET/waitlist/student/{studentID}REGISTRATION.WAITLISTSGet one student
POST/waitlist/{waitlistID}/cancelREGISTRATION.WAITLISTSCancel for a waitlist
GET/waitlistsREGISTRATION.WAITLISTSList waitlists
POST/waitlistsREGISTRATION.REGISTERJoin a waitlist
GET/waitlists/for_studentREGISTRATION.REGISTERA student's own waitlist entries
DELETE/waitlists/{waitlistID}REGISTRATION.WAITLISTSRemove from a waitlist
GET/waitlists/{waitlistID}REGISTRATION.WAITLISTSGet one waitlist entry (stub: always 404)
POST/waitlists/{waitlistID}/convert_to_transactionREGISTRATION.WAITLISTSPromote: add the section to the student's registration transaction
POST/waitlists/{waitlistID}/leaveREGISTRATION.REGISTERLeave a waitlist

Student Information System Documentation