> 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/archive-or-restore-a-student.md).

# Archive or restore a student

Use this endpoint when a student leaves active status for good (graduated, withdrew, transferred out) or comes back. Send `{"state": "archived"}` to archive or `{"state": "unarchived"}` to restore. Archiving is not for a temporary leave: it signs the student out of Stellic, removes most access to their record, and freezes their audit as it stood.

## PUT /student/{student\_username}/state/

>

```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":{"StudentStateRequestBody":{"type":"object","properties":{"state":{"type":"string","enum":["archived","unarchived"],"description":"Target archive state. Only `archived` and `unarchived` are accepted; any other value (including\nempty body) returns a 400.\n"}},"required":["state"]},"StudentStatusUpdateSuccess":{"type":"object","description":"`PUT` archive/restore response. `state` is a human-readable sentence, not an object.\nThere is no `errors` field on a `200`.\n","properties":{"status":{"type":"string"},"state":{"type":"string","description":"Human-readable confirmation of the transition the call performed."}}},"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}/state/":{"put":{"tags":["Student"],"parameters":[{"name":"student_username","in":"path","required":true,"description":"Student's platform username. Lowercased before lookup unless your institution signs students in with\nan identifier other than the username, in which case the case you send must match the record. The\nlookup also excludes test accounts; a username that matches a test account returns the same\n`No student exists with username: {username}` 400 as a missing user.\n","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentStateRequestBody"}}}},"responses":{"200":{"description":"State change processed. `state` in the body is a human-readable sentence, not an object.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentStatusUpdateSuccess"}}}},"400":{"description":"Required-field, body-type, or lookup failure. Response body is `{\"status\": \"failure\", \"identifiers\": {...}, \"message\": \"...\"}` (single string, no `errors` array).\n\nCommon causes:\n- Body is not a JSON object - returns `request body must be a JSON object.`\n- Missing or empty body - returns `request body with state is required.`\n- Invalid state value - returns `invalid state, valid values are ['archived', 'unarchived']`\n- Student not found or test account - both return `No student exists with username: {student_username}`","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/StudentLinkResponseFailure"}]}}}},"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":"State transition failure. Response body is `{\"status\": \"failure\", \"identifiers\": {...}, \"errors\": [{\"message\": \"...\"}]}` (array of objects), not the singular `message` shape used by 400s. A failed archive transition returns `Stellic couldn't archive the student`. Other caught errors return `Stellic couldn't process your request`."}}}}}}
```

#### What happens after the call (archive)

* The student is archived right away, and their plans, courses, and holds are archived with them. Enrollments stay on the plan and come back on restore.
* The student can no longer sign in. At institutions that allow combined student and staff accounts, a person who is also staff keeps signing in as staff; only their student record is archived.
* Staff access to the student is reduced to viewing their profile, plan, and audit, so advisors can still look them up.
* In a background task, the student's audit is saved as it stood, and search is updated. While the student is archived, their audit keeps showing that saved version, so later catalog changes don't alter it.
* Activity entries for the archive are recorded, only after the archive changes are saved.

#### What happens after the call (restore)

* The student is restored right away and their saved audit is discarded; the next audit read computes a fresh one.
* Access and search are recalculated in a background task. Programs on a retired audit version move to the current version, except locked programs and programs with a diploma awarded.
* Restoring also schedules staff access from the student's existing student sets to be reapplied, even if a permission load is already in progress.
* The student is **not** able to sign in again automatically. Sign-in is restored by your data sync (or an administrator), not by this call.
* Activity entries for the restore are recorded, only after the restore changes are saved and only when the student has a default plan.

#### Notes

{% hint style="warning" %}
**Check the state before retrying a 500.** A failed archive transition is rolled back and does not start the background task that saves the audit. A restore that fails during its state changes is also rolled back. Read [`GET /student/{student_username}/state/`](/stellic-partner-api/student/read-a-student-s-current-archive-state.md) before retrying.
{% endhint %}

* A student without a default plan can still be restored, but no restore activity entry is recorded. Use [`GET /student/{student_username}/state/`](/stellic-partner-api/student/read-a-student-s-current-archive-state.md) to confirm their archive state rather than relying on activity history alone.
* **Staff access is removed about six months after the archive.** At institutions that don't keep archived students long term, the view access kept at archive time is removed once six months have passed. The student record itself stays.
* **Archiving again restarts the six-month clock.** Archiving a student who is already archived isn't a no-op; check the state first if you only want to archive once.
* **Archived students' plans can't be changed.** Course, section, and program enrollment updates for an archived student fail. Restore the student first.
* **The profile endpoints reject archived students.** Restore first, then send the profile update.
* **Test accounts return the not-found 400**, `No student exists with username: {username}`. Usernames are lowercased before the lookup unless your institution signs students in with an identifier other than the username.

#### Related APIs

* [`GET /student/{student_username}/state/`](/stellic-partner-api/student/read-a-student-s-current-archive-state.md) to read the current state.
* [`PUT /student/{student_username}/profile/`](/stellic-partner-api/student/upsert-a-student-profile.md) to update the profile after a restore.
