> 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/readme.md).

# Overview

The Partner API lets your systems read from and write to Stellic as things change: a student declares a major, a hold is placed, a section cap moves. It complements your data sync, which sets the baseline. Where the data sync replaces what the API wrote, such as holds, tags, and registration tickets, the endpoint page says so.

Some behavior depends on how Stellic has set up your institution. Where an endpoint page says it varies by institution, ask your Stellic Representative how yours is set.

### Base URL

```
https://{institution}.stellic.com/partnerapi/v1/
```

Replace `{institution}` with your Stellic subdomain.

### OpenAPI spec

Import the spec into Postman, Insomnia, or a client generator. It covers every endpoint in this reference.

{% file src="/files/w6colvpn3H2bcLfBKtwM" %}
Stellic Partner API, OpenAPI 3.0 (JSON)
{% endfile %}

### Authentication

```
Authorization: Bearer <your-token>
```

Tokens are scoped to your institution and bound to the account that created them. Any valid token can call any endpoint; there are no OAuth-style scopes. A few calls also use that account: editing requirement rules, unlinking shared requirements, and publishing audits check its rights on the audit, and only the account that started an export can download it. Use separate tokens for production and test.

To get a token, contact Stellic with your institution, a contact name and email, your static egress IPs (Stellic allows only listed IPs), and what you plan to integrate. Keep tokens in a secrets manager or environment variable.

Check your setup with [`GET /health/`](broken://pages/SzzOyNlDkwx95c6Xz9B7).

### HTTP methods

| Method   | Usual behavior                                                                                                                                       |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET`    | Read.                                                                                                                                                |
| `POST`   | Create a record, or attach a tag, school, or department.                                                                                             |
| `PUT`    | Replace or upsert. Some, such as holds, registration tickets, section caps, and requirement rules, only update and fail if the record doesn't exist. |
| `PATCH`  | Partial update. The student profile PATCH also clears the name and email you leave out, so send them.                                                |
| `DELETE` | Remove. Most return an error when the record is already gone.                                                                                        |

Each endpoint page gives the exact behavior.

### Responses and errors

* **Check the body, not only the status.** Bulk endpoints return 200 with failed rows in `errors`, and the hold write endpoints return 200 with `"success": false` on failure.
* **Don't retry a 500 before checking the endpoint page.** Many endpoints don't validate every field, so a malformed date or an ID of the wrong kind returns a 500 every time.
* **Retry 503s with backoff and jitter.** A 503 means you've hit a rate limit.

{% hint style="warning" %}
**Error bodies differ by endpoint.** Each endpoint page shows its own. Parse the body for the endpoint you called rather than assuming one shape.
{% endhint %}

| Shape                                                                        | Where you'll see it                                                                                                                                      |
| ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{"errors": [{"message": "..."}]}`                                           | Catalog, course and section enrollments, exports, and student reads (audits, planner, progress, GPAs). Exports sometimes put a plain string in `errors`. |
| `{"status": "failure", "identifiers": {...}, "message": "..."}`              | Program enrollments and student writes (profile, archive, tags, schools, departments). Some use `errors` instead of `message`.                           |
| `{"error": "..."}`                                                           | Programs, audits, and requirements.                                                                                                                      |
| `{"success": false, "message": "..."}` or `"errors": [...]`                  | Hold reads and registration tickets.                                                                                                                     |
| `{"success": false, "message": {"code": 404, "text": "..."}}`, with HTTP 200 | Hold writes.                                                                                                                                             |
| `{"success": false, "error": "..."}`                                         | Pathway reads.                                                                                                                                           |
| `{"status": "error", "message": "..."}`                                      | Transcript upload.                                                                                                                                       |
| `{"detail": "..."}`                                                          | Authentication (401), page numbers past the end, and some not-found responses.                                                                           |
| `{"<field>": ["..."]}`                                                       | Section constraints.                                                                                                                                     |

Some messages arrive wrapped as `"['...']"`. The endpoint pages show them as they arrive.

### Bulk endpoints

Endpoints that take a list, such as [`PUT /planner/enrollment/course/{username}/{term_id}`](/stellic-partner-api/course-enrollments/replace-a-student-s-course-enrollments-for-a-term.md) and [`PUT /catalog/section/bulk`](/stellic-partner-api/catalog-sections/bulk-update-section-enrollment-caps.md), return each row's result:

```json
{
  "success": [ /* rows saved */ ],
  "errors":  [ /* rows that failed, with reasons */ ]
}
```

Either key can be missing; treat a missing key as `[]`. Each failed row carries the identifier you sent, such as the course code or section ID.

### Exports

[`GET /exports/{property}`](/stellic-partner-api/exports/bulk-export-dispatcher.md) exports every dataset; `{property}` picks the dataset. Small exports come back as a file. Large ones run in the background and return a `file_name`, which you poll with [`GET /get_export_url/`](/stellic-partner-api/exports/poll-an-async-export-and-fetch-its-presigned-url.md) until `status` is `completed` or `failed`. The dispatcher page lists which datasets run in the background and how `delivery_channel` changes that.

### IDs and matching

* **Your identifiers are strings:** usernames, section and term IDs, hold IDs, tag IDs, and program `external_id` values. Don't convert them to numbers, or leading zeros are lost.
* **Stellic's own IDs are numbers:** audits, requirements, rules, `base_program`, `base_audit`, and `shared_requirement_id`.
* **Matching is exact unless a page says otherwise.** Profile and archive endpoints lowercase usernames, unless your institution signs students in with another identifier. Campus names, profile emails, and registration semester names are lowercased too. Program enrollment, tag, school, and department endpoints match usernames exactly.

### Rate limits

Limits apply per calling IP, at the web server in front of Stellic, and are set for each institution. Over the limit, requests get a 503, not a 429. For large sweeps, such as reading every student's audit, keep to 5 to 10 requests a second. Contact Stellic before migrations or load tests.

### Versioning

Every endpoint is under `/v1/`. New endpoints and optional fields are added without a version change; breaking changes go under a new version, such as `/v2/`.

### Getting help

Send Stellic the method and path, the request body (redact personal data), the response status and body, and the time in UTC.
