> For the complete documentation index, see [llms.txt](https://docs.stellic.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stellic.com/stellic-partner-api/program-enrollments/get-a-student-s-program-enrollment.md).

# Get a student's program enrollment

Use this endpoint to read one program enrollment for a student: linked concentrations, certification status and date, and the program's audit order. It reads the student's default plan and returns only declared programs, not undeclared ones.

## GET /planner/enrollment/program/{username}/{program\_id}

>

```json
{"openapi":"3.0.0","info":{"title":"Stellic for Developers","version":"1.0"},"tags":[{"name":"Program Enrollments"}],"servers":[{"url":"https://{institution}.stellic.com/partnerapi/v1","variables":{"institution":{"default":"{institution}","description":"Your institution's Stellic subdomain: the part before `.stellic.com` in the URL you use to sign in. It becomes the host in every request, as in `https://{institution}.stellic.com/partnerapi/v1/...`. Replace the `{institution}` placeholder with your subdomain before sending."}}}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Personal Access Token issued by your Stellic integration partner. Send it as `Authorization: Bearer <token>` on every request. One token per institution; do not share across environments."}},"schemas":{"StudentProgramResponseSuccess":{"type":"object","properties":{"status":{"type":"string"},"state":{"type":"object","properties":{"program":{"type":"string","description":"The program's `short_name`, as passed in the path."},"certification_status":{"type":"boolean"},"certification_date":{"type":"string","nullable":true,"description":"Rendered as `Month DD, YYYY` with a zero-padded day (for example `May 05, 2026`), not ISO."},"order":{"type":"integer","nullable":true},"concentrations":{"type":"array","description":"Every concentration linked to this enrollment, including ones the student has planned but isn't enrolled in (`enrolled` false).","items":{"type":"object","properties":{"name":{"type":"string"},"enrolled":{"type":"boolean"},"planned":{"type":"boolean"},"is_internal":{"type":"boolean"},"is_archived":{"type":"boolean"},"concentration_type":{"type":"object","properties":{"short_name":{"type":"string"},"name":{"type":"string"}}}}}},"units_label":{"type":"object","description":"Present only when the program is configured with a custom units label.","properties":{"field_name":{"type":"string"},"label_plural":{"type":"string"},"label_singular":{"type":"string"}}}}},"errors":{"type":"array","description":"Warning strings for optional fields that were skipped (`POST` and `PATCH` only; the `GET` response has no `errors` key).","items":{"type":"string"}}}},"StudentLinkResponseFailure":{"allOf":[{"$ref":"#/components/schemas/GenericResponseFailure"},{"type":"object","properties":{"identifiers":{"type":"object","properties":{"student_username":{"type":"string"}}}}}]},"GenericResponseFailure":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/planner/enrollment/program/{username}/{program_id}":{"get":{"tags":["Program Enrollments"],"parameters":[{"name":"username","in":"path","required":true,"description":"Student's Stellic username, as sent in your data sync. This endpoint does not lowercase or case-normalize the username.","schema":{"type":"string"}},{"name":"program_id","in":"path","required":true,"description":"The program's short name, as sent in your data sync. Matched exactly; case-sensitive.","schema":{"type":"string"}}],"responses":{"200":{"description":"Declared enrollment found. `state.certification_date` is rendered as `Month DD, YYYY`\nwith a zero-padded day (for example `\"May 05, 2026\"`) or `null`; it is NOT ISO.\n`state.order` is the program's audit order and may be `null`. `state.concentrations[]`\nincludes every concentration linked to this enrollment, including ones the student has\nplanned but isn't enrolled in (`enrolled: false`), so inspect that flag per entry.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentProgramResponseSuccess"}}}},"400":{"description":"Hard validation failure, OR no active enrollment exists for this (student, program).\n\nCommon causes (path-param validation, returned with `message`):\n- Student does not exist or is marked as a test account - returns `No student exists with username: {username}`. A non-archived student converted to staff can be marked as a test account when combined student and staff accounts are disabled.\n- Program does not exist - returns `No program exists with unique identifier: {program_id}`\n- Non-test student is archived - returns `Student with username {username} is archived`\n- Program is a compliance requirement (compliance requirements are not programs a student can be enrolled in through the API) - returns `Compliance requirements are not available via the API: {program_id}`\n- Student has no default plan - returns `{username} has no default plan`\n\nNo-enrollment case (returned with `errors[]` and `state: {}`):\n- Student was never enrolled, the enrollment was removed with `DELETE`, or the\n  program is on the student's plan as an undeclared program - returns\n  `program enrollment does not exist.` The response can't tell these apart. After a\n  `DELETE`, calling `POST` on this path creates a new enrollment; the removed\n  enrollment's concentrations are not restored.\n\nThe two shapes are mutually exclusive. The cleanest discriminator is the presence\nof `state`: only the no-enrollment response carries `state: {}`.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/StudentLinkResponseFailure"},{"type":"object","properties":{"identifiers":{"type":"object","properties":{"student_username":{"type":"string"},"program_id":{"type":"string"}}}}}]}}}},"401":{"description":"Missing or invalid Bearer token.\n\nCommon causes:\n- Unauthenticated / invalid token"},"403":{"description":"Your IP address isn't on the allowlist for this endpoint. Contact Stellic to add it; the response includes the `client_ip` Stellic saw.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"client_ip":{"type":"string"}}}}}},"500":{"description":"Unhandled server error. Retry with exponential backoff.\n\nCommon causes:\n- Unhandled server error - returns `Stellic couldn't process your request`"}}}}}}
```

#### Notes

* **"Not enrolled" comes back as a 400.** `program enrollment does not exist.` means the student was never enrolled, the enrollment was removed, or the program is on the student's plan as an undeclared program; the response can't tell these apart. This body carries `errors[]` and `state: {}`, while validation failures (unknown student or program) carry a single `message`, so check for `state` to tell "not enrolled" from a bad request.

#### Related APIs

* [`POST /planner/enrollment/program/{username}/{program_id}`](/stellic-partner-api/program-enrollments/enroll-a-student-in-a-program.md) to enroll the student in the program.
* [`PATCH /planner/enrollment/program/{username}/{program_id}`](/stellic-partner-api/program-enrollments/update-fields-on-an-existing-program-enrollment.md) to certify, reorder, change the catalog year, or add concentrations.
* [`DELETE /planner/enrollment/program/{username}/{program_id}`](/stellic-partner-api/program-enrollments/remove-a-student-s-program-enrollment.md) to remove the enrollment.
