> 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/student/link-a-student-to-a-school.md).

# Link a student to a school

Use this endpoint to add one school to a student without sending their whole profile. `{school_id}` is the school's short name, matched exactly. A student can belong to several schools, and linking a school that's already linked returns 200 with no change. The response is the student's profile, with their schools and departments.

## POST /student/{student\_username}/school/{school\_id}

>

```json
{"openapi":"3.0.0","info":{"title":"Stellic for Developers","version":"1.0"},"tags":[{"name":"Student"}],"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":{"StudentLinkResponseSuccess":{"type":"object","properties":{"status":{"type":"string"},"state":{"type":"object","properties":{"username":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"photo_url":{"type":"string","nullable":true},"level":{"type":"integer"},"year_begin":{"type":"integer"},"campus":{"type":"string","nullable":true,"description":"The student's primary campus name, or `null` if no campus is set."},"schools":{"type":"array","items":{"type":"object","properties":{"campus":{"type":"object","nullable":true,"description":"The campus the school belongs to, or `null` if the school has no campus.","properties":{"id":{"type":"integer"},"name":{"type":"string"},"screen_name":{"type":"string"}}},"name":{"type":"string"},"short_name":{"type":"string"}}}},"departments":{"type":"array","description":"The student's departments. Each one carries its name and code but not its short name.","items":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string","nullable":true,"description":"The department's first registered code, or `null` if the department has no codes."},"school":{"type":"object","properties":{"campus":{"type":"object","nullable":true,"description":"The campus the parent school belongs to, or `null` if the school has no campus.","properties":{"id":{"type":"integer"},"name":{"type":"string"},"screen_name":{"type":"string"}}},"name":{"type":"string"},"short_name":{"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":{"/student/{student_username}/school/{school_id}":{"post":{"tags":["Student"],"parameters":[{"name":"student_username","in":"path","required":true,"description":"The student's username, matched exactly (not lowercased). Stored usernames are usually lowercase. Archived students and test accounts return `400`.","schema":{"type":"string"}},{"name":"school_id","in":"path","required":true,"description":"The school's short name, matched exactly (case- and whitespace-sensitive). Unknown and deleted schools return `400`.","schema":{"type":"string"}}],"responses":{"200":{"description":"School linked, or was already linked (no change). A search refresh is attempted during the call; a refresh failure does not change the success response. `state` is the student's profile with their schools and departments. `state.schools` lists each linked school once, including schools linked for different terms, without term-specific membership information.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentLinkResponseSuccess"}}}},"400":{"description":"Validation failure on the student or the school.\n\nCommon causes:\n- Student not found - returns `No student exists with username: {student_username}`\n- Student is archived and isn't a test account - returns `Student with username {student_username} is archived`\n- Student is a test account - returns the same `No student exists with username: {student_username}` as a missing user. This can include a student record converted to staff, depending on how your institution is set up. Ask your Stellic Representative how your institution is set up.\n- No school, or only a deleted one, has this short name - returns `No school exists with short_name: {school_id}`","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/StudentLinkResponseFailure"},{"type":"object","properties":{"identifiers":{"type":"object","properties":{"student_username":{"type":"string"},"school_id":{"type":"string"}}}}}]}}}},"401":{"description":"Missing or invalid Bearer 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 error while saving the link change; the change wasn't saved. Body is `{\"status\": \"failure\", \"identifiers\": {...}, \"errors\": [{\"message\": \"Stellic couldn't process your request\"}]}`, with `errors[]` in place of `message`."}}}}}}
```

#### What happens after the call

* The school is linked during the call. Search can still show the old links if its refresh fails.
* When you link a school that wasn't already linked, updates to general requirements and advisor access are scheduled in background tasks. The general requirements update targets primary plan types, not secondary plans.
* The general requirements update recalculates program order even if the requirements don't change. This invalidates diploma requirements built from that order and resets the cached audit for each recalculated plan, regardless of whether its general requirements change. The update also resets the cached audit for plans whose general requirements change.
* After general requirements are updated, automatically applied pathways are checked where available. The check uses a primary-type plan marked as default; a secondary-type default plan is not selected. On prospective instances, it uses an empty-plan type marked as default instead. The check can apply or remove automatically managed pathways when matches change. Ask your Stellic Representative how your institution is set up.
* Some student-set grants managed by your data sync aren't reapplied by this update. Ask your Stellic Representative to check your institution's access and data sync setup.
* A 200 confirms the link, not completion of the background updates. Linking an already linked school doesn't schedule these updates again, so reposting it isn't a retry.

#### Notes

* **Don't use this response to track school membership by term.** You can't use `state.schools` as a current-term school list or reconstruct term-specific membership from it.
* **You can't choose the primary school.** When a student has several schools, their primary school is the one that was added to Stellic first, whatever order you link them in.
* **Your data sync can change schools linked here.** If your data sync sends student schools, the next run replaces them.
* **Usernames must match exactly** and aren't lowercased. Archived students who aren't test accounts return `Student with username {student_username} is archived`.

#### Related APIs

* [`DELETE /student/{student_username}/school/{school_id}`](/stellic-partner-api/student/unlink-a-student-from-a-school.md) to unlink the school.
* [`POST /student/{student_username}/department/{dept_id}`](/stellic-partner-api/student/link-a-student-to-a-department.md) to link a department. Linking a department doesn't link its school.
