> 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/create-a-student-tag-definition.md).

# Create a student tag definition

Use this endpoint to create a tag you can attach to students. `{tag_sis_id}` becomes the tag's SIS ID; send its display name as `tag_name` and a list of `tag_types`: `general`, `audit`, `auditcriteria`, or `studentset`. Tags apply across the institution. The response is `{"success": true, "state": {...}}`, not the `status` envelope other student endpoints use.

## POST /tag/{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":{"StudentTagRequestBody":{"type":"object","properties":{"tag_name":{"type":"string","description":"Display name for the tag. Capped at 150 characters."},"tag_types":{"type":"array","items":{"type":"string"},"description":"List of tag types. Valid values are `studentset`, `auditcriteria`, `audit`, and `general`. Send a list of strings, even for a single type. Unknown strings are dropped and the tag is created with the valid ones. The call returns 400 if none are valid, if the value isn't a list, or if any list item isn't a string."}},"required":["tag_name","tag_types"]},"StudentTagCreateResponseBody":{"type":"object","properties":{"success":{"type":"boolean","description":"Boolean success flag. Note: unlike other partner endpoints that return a string `\"status\": \"success\"`, this endpoint returns a boolean `\"success\": true`. Branch on the HTTP code, not on the field name."},"state":{"type":"object","properties":{"sis_id":{"type":"string"},"name":{"type":"string"},"types":{"type":"array","items":{"type":"string"},"description":"Tag types linked to this tag. Reflects only the valid values from the request (unknown values were silently dropped). Sorted alphabetically by type name."}}}}}}},"paths":{"/tag/{tag_sis_id}":{"post":{"tags":["Student"],"parameters":[{"name":"tag_sis_id","in":"path","required":true,"description":"The SIS ID for the new tag, up to 150 characters. If a tag with this SIS ID already exists, including an archived one, the call returns 400. Reusing the SIS ID of a deleted tag restores that tag with the new name and types.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentTagRequestBody"}}}},"responses":{"200":{"description":"Tag created. Response envelope is `{\"success\": true, \"state\": {...}}` (boolean `success`, not the string `status` used elsewhere in the partner API).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentTagCreateResponseBody"}}}},"400":{"description":"Validation failure. Body shape: `{\"status\": \"failure\", \"identifiers\": {\"tag_sis_id\": \"...\"}, \"message\": \"...\"}`.\n\nCommon causes:\n- A tag with this SIS ID already exists, including an archived one - returns `Tag with {tag_sis_id} sis_id already exists. Cannot create a duplicate tag with the same sis_id.`\n- The body isn't a JSON object - returns `The request body must be a JSON object.`\n- Missing `tag_name` or `tag_types` - returns `The parameter(s) {missing} is missing from the request`\n- Empty `tag_name` - returns `The 'tag_name' is a required field and cannot be empty.`\n- `tag_types` has no valid values, isn't a list, or contains any non-string value - returns `The 'tag_types' is a required field and must be a list of valid tag types.`\n- A conflict while creating the tag, including an existing tag without a SIS ID whose name matches the requested SIS ID - returns `Cannot create tag {tag_sis_id}: it conflicts with an existing tag with this sis_id, or with no sis_id and this name.`"},"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":"Error while saving the tag. Body shape: `{\"identifiers\": {...}, \"errors\": [{\"message\": \"Stellic couldn't process your request\"}]}`, with no `status` key (unlike the `400`).\n\nCommon causes:\n- `tag_name` or `tag_sis_id` longer than 150 characters."}}}}}}
```

#### What happens after the call

* The tag and its type links are saved together during the call. If saving either fails, neither change is kept.

#### Notes

{% hint style="warning" %}
**If your data sync sends tags, it deletes tags that aren't in it.** On each run, a tag missing from the sync is archived if it's in use, for example attached to students, and deleted if it isn't. Add tags you create here to your data sync, or create them only there.
{% endhint %}

* **Unknown `tag_types` are dropped.** The call succeeds with only the valid types. Send a list of strings, even for one type; a list containing any non-string value is rejected rather than partially accepted.
* **Each SIS ID can be used once.** A tag with the same SIS ID, including an archived one, returns a 400. Reusing the SIS ID of a deleted tag restores that tag with the new name and types. Choose an SIS ID that doesn't match the name of an existing tag without a SIS ID.
* **Keep `tag_name` and `{tag_sis_id}` to 150 characters.** Longer values return a 500.
* **Tags can't be renamed or deleted through the API.** Use your data sync or Stellic.

#### Related APIs

* [`POST /student/{student_username}/tags/{tag_sis_id}`](/stellic-partner-api/student/attach-a-tag-to-a-student.md) to attach the tag to a student.
* [`POST /catalog/section/restriction/{id}`](/stellic-partner-api/catalog-sections/add-a-restriction-to-a-section.md) to restrict a section by tag.
