> 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/attach-a-tag-to-a-student.md).

# Attach a tag to a student

Use this endpoint to add an existing tag to a student, for example to place them in a cohort that advisors, student sets, or section restrictions use. `{tag_sis_id}` matches either the tag's SIS ID or its name, exactly. The tag must already exist; create it with [`POST /tag/{tag_sis_id}`](/stellic-partner-api/student/create-a-student-tag-definition.md). The response lists all of the student's tags by name.

## POST /student/{student\_username}/tags/{tag\_sis\_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":{"StudentTagResponseSuccess":{"type":"object","description":"Standard tag-operation success envelope. `state.tags` is the student's full current tag list after the operation,\nby tag display name (not SIS ID).\n","properties":{"status":{"type":"string"},"state":{"type":"object","properties":{"username":{"type":"string"},"tags":{"type":"array","description":"The student's full current tag list after the operation, by tag display name (not SIS ID).\n","items":{"type":"string"}}}}}},"StudentTagResponseFailure":{"allOf":[{"$ref":"#/components/schemas/GenericResponseFailure"},{"type":"object","properties":{"identifiers":{"type":"object","properties":{"student_username":{"type":"string"},"tag_sis_id":{"type":"string"}}}}}]},"GenericResponseFailure":{"type":"object","properties":{"status":{"type":"string"},"message":{"type":"string"}}},"StudentTagResponse500":{"type":"object","description":"Unhandled server-error envelope for the tag endpoints. Note the missing `status` key: 400 responses\ncarry `status: \"failure\"` and a singular `message`, but 500 responses on this path are an array of\nobjects with no `status` key.\n","properties":{"identifiers":{"type":"object","properties":{"student_username":{"type":"string"},"tag_sis_id":{"type":"string"}}},"errors":{"type":"array","items":{"type":"object","properties":{"message":{"type":"string"}}}}}}}},"paths":{"/student/{student_username}/tags/{tag_sis_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\nlowercase. Archived students return `Student with username {student_username} is archived`;\ntest accounts return the same `No student exists with username: {student_username}` as a\nmissing user.\n","schema":{"type":"string"}},{"name":"tag_sis_id","in":"path","required":true,"description":"The tag's SIS ID or name, matched exactly. The tag must already exist; this call doesn't\ncreate it. If one tag's name equals another tag's SIS ID, you can't control which of the two\nis attached, so use SIS IDs that don't match another tag's name.\n","schema":{"type":"string"}}],"responses":{"200":{"description":"Tag attached. `state.tags` is the student's full current tag list after the attach, returned by tag `name` (not `sis_id`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentTagResponseSuccess"}}}},"400":{"description":"Lookup or duplicate-attach failure. Envelope is `{\"status\": \"failure\", \"identifiers\": {\"student_username\": ..., \"tag_sis_id\": ...}, \"message\": \"...\"}` (single string, no `errors` array).\n\nCommon causes:\n- Student not found or test account - returns `No student exists with username: {student_username}`\n- Student archived - returns `Student with username {student_username} is archived`\n- Tag definition not found - returns `No student tag exists with id: {tag_sis_id}`\n- Tag already on this student - returns `Tag already exists on student with username: {student_username}`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentTagResponseFailure"}}}},"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 server error during the attach. Envelope is `{\"identifiers\": {...}, \"errors\": [{\"message\": \"Stellic couldn't process your request\"}]}` with no `status` key, different from the 400 shape.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentTagResponse500"}}}}}}}}}
```

#### What happens after the call

* The tag is attached right away.
* If the tag's types include `audit` or `general`, the student's audit is recalculated on its next read.
* If they include `auditcriteria` or `general`, the student's programs are moved to the audit version that matches their tags during the call. Certified and locked programs and general requirements keep their version.
* Student sets, advisor access, and search are updated in a background task after the tag is saved.
* General requirements are refreshed in the background. At some institutions, the refresh does not update the student's selected plans; ask your Stellic Representative how this applies to your institution. The audit can be recalculated even when general requirements do not change.
* After the general-requirement refresh succeeds, automatically applied pathways are recalculated if your institution uses the pathway experience. The refresh selects non-archived primary plans at non-prospective institutions and non-archived plans of type `empty` at prospective institutions. A selected plan must also be marked default. A secondary plan is not selected at a non-prospective institution, even if it is marked default.

#### Notes

* **The refresh can update other students' plans.** If no plans are selected for the student, the refresh can update other students' eligible plans. Contact your Stellic Representative before attaching a tag if the student has no eligible primary plan.
* **Attaching a tag twice returns a 400.** `Tag already exists on student with username: {student_username}`. Treat that message as success if you retry.
* **Use SIS IDs that don't match another tag's name.** If one tag's name equals another tag's SIS ID, you can't control which of the two is attached, and a student who has one can be refused the other.
* **Your data sync can remove tags attached here.** If your data sync sends student tags, a tag that isn't in it is removed on the next run.
* **Usernames must match exactly** and aren't lowercased. Archived students return `Student with username {student_username} is archived`.

#### Related APIs

* [`POST /tag/{tag_sis_id}`](/stellic-partner-api/student/create-a-student-tag-definition.md) to create the tag.
* [`DELETE /student/{student_username}/tags/{tag_sis_id}`](/stellic-partner-api/student/detach-a-tag-from-a-student.md) to detach it.
* [`GET /student/{student_username}/tags/{tag_sis_id}`](/stellic-partner-api/student/check-whether-a-tag-is-attached-to-a-student.md) to check whether it's attached.
* [`POST /catalog/section/restriction/{id}`](/stellic-partner-api/catalog-sections/add-a-restriction-to-a-section.md) to restrict a section by tag.
