> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs-unsw-v6.advance-uac.com/overview/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs-unsw-v6.advance-uac.com/_mcp/server. # Overview The UNSW Advance Institution API is how you feed Advance the two fundamental pieces it needs to assess credit: **the curriculum data of programs and subjects/courses**, and **who is applying**. Your access token identifies you on every request, so there is no institution id to pass. Reads and writes are authorised from the token. ## Trying it out These pages are the reference. To poke at a running instance, each environment serves a live Swagger UI, where you can paste a token and fire real requests: * [Test](https://unsw-v6-test.advance-uac.com/institution-api/q/swagger-ui/), which is what an integrator can call today * [Dev](https://unsw-v6-dev.advance-uac.com/institution-api/q/swagger-ui/), which runs ahead of test and is less stable Both serve their raw spec at `/q/openapi.json` on the same host. See [Authentication](/authentication) for getting the token you'll need to paste in. ## The two halves #### [Catalogue data](/unsw-advance-institution-api/catalogue/list-programs) Your reference data: programs, subjects, specialisations, and the curriculum structures that tie them together. Maintained once, then kept up to date. #### [Application data](/unsw-advance-institution-api/applications/submit-a-new-application) Applicants and their applications, including the qualifications they hold and any supporting documents. The catalogue comes first. An application names a program code and year, so that program has to exist before anyone can apply to it. ## Everything is identified by code and year A program, subject or specialisation is identified by its **code plus the year it applies to**. `3584` in `2026` is a different record from `3584` in `2027`. Curricula change between years, and an application is always assessed against the rules of its own intake year, so both parts matter. Neither can be changed after creation. To correct a code, delete the record and create it again. ## Your IDs, not ours Two separate mechanisms let you work with your own identifiers instead of storing ours. **`externalIds`** on catalogue records maps a record to its ID in each of your systems: ```json { "externalIds": { "sis": "PRG-3584", "crm": "C-000123" } } ``` Send it on create or update and it merges per system, so omitting a system leaves that system's ID alone. This helps when your own systems disagree about what a program is called. **`sources`** on applicants and applications records where a record came from and what you call it, such as your student number or your application number. An applicant or an application can carry one entry per system of record: ```json { "sources": [ { "sourceName": "SITS", "sourceRef": "z1234567" }, { "sourceName": "TRIM", "sourceRef": "T-99814" } ] } ``` You can then look records up by any of your own IDs, without having stored ours: ``` GET /institution/applicants?sourceRef=z1234567 GET /institution/applications?sourceRef=APP-2026-00123 ``` A `sourceRef` must be unique within a `sourceName`, and `sourceName` is required whenever you send a `sourceRef`, since an ID with no system to interpret it isn't findable. The first entry is the **primary**: it is what list views, search results and the change feed show, and what the `sourceName` / `sourceRef` pair on every response reports. Order is yours to set — send the entries in the order you want them. > **Note** > > The single `sourceName` / `sourceRef` pair is still accepted everywhere it was, and is > still returned on every response. Sending the pair counts as one entry, listed first; > sending it on a `PATCH` edits the first entry and leaves the rest alone. Nothing built > against the pair needs to change. It's worth supplying these on applicants. When you submit an application, an applicant carrying any of the references you send is matched on that first, ahead of name and date of birth. That way a returning applicant is still recognised after a name change or a corrected typo. If the applicant is matched on name and date of birth instead, the references you sent are added to the record rather than discarded. ## Replace or amend: PUT and PATCH | | Behaviour | | ------- | ---------------------------------------------------------------------------------------------------------------- | | `PUT` | **Replaces.** Every editable field is written as sent, so a field you omit is *cleared*. Send the whole record. | | `PATCH` | **Amends.** Only the fields present are touched. Send `null` to clear one explicitly; omit it to leave it alone. | **Catalogue records offer both.** Reach for `PATCH` when you're changing one thing, particularly on subjects, where a `PUT` that forgets `description` or `learningOutcomes` will wipe them. **Applicants and applications offer `PATCH` only**, deliberately — see [Correcting records](/corrections) for why, and for the rules on what can still be changed once an application has been assessed. An unrecognised field name in a `PATCH` body is rejected rather than ignored, so a typo can't silently do nothing. `externalIds` is the one exception in both: it always merges per system, and sending it as `null` is refused rather than wiping every id you've registered. ## Curriculum structures A program's curriculum is a tree of containers, such as "Core Courses" or "Prescribed Electives", each holding subject entries and, optionally, child containers. Containers are built as `DRAFT`, which lets you assemble and review a tree before anything uses it. Attaching it to a program or specialisation, or nesting it under another container, is only allowed while it is a draft. Publishing sets it `LIVE`. ## Assessment is asynchronous Submitting an application stores it and returns immediately with status `RECEIVED`. Assessment happens afterwards. `GET /institution/applications/{id}` reports where intake got to: | Status | Meaning | | ------------ | ------------------------------------------------------ | | `RECEIVED` | Stored and awaiting assessment | | `READY` | You have told us the supporting documents are adequate | | `PROCESSING` | Taken up for assessment | | `WITHDRAWN` | Withdrawn and closed. Terminal | | `FAILED` | Intake errored; see `statusDetail` | The credit itself is a separate endpoint: ``` GET /institution/applications/{id}/outcome ``` `PROCESSING` means an assessment has *started*, not that it has finished. A credit officer may still be reviewing it, so poll the outcome until its `finalOutcome` is `true`. See [Credit outcomes](/credit-outcomes) for how to read it, and for the difference between "not assessed yet" and "assessed, and awarded nothing". `READY` and `WITHDRAWN` are yours to set, by posting to `/institution/applications/{id}/ready` and `/institution/applications/{id}/withdraw`. Both arrived on 18 September, along with the rename of `PROCESSED` to `PROCESSING`. See [that release](/releases/2026-09-18) if you are migrating. ## Getting a token Authentication is OAuth 2.0 **client credentials** against Keycloak. Request a token with your client id and secret, then send it as a bearer token on every call. See [Get access token](/unsw-advance-institution-api/get-access-token) for the exact request. Tokens are short-lived. Request a new one when it expires rather than caching it indefinitely. ## A typical integration 1. Load your catalogue: programs, subjects and specialisations for the intake year 2. Build curriculum structures for each program, and publish them 3. Submit applications as they arrive, with the applicant's qualifications attached 4. Attach supporting documents (transcripts, syllabi) to the application 5. Poll [the outcome](/credit-outcomes) until `finalOutcome` is `true` 6. [Correct](/corrections) anything your own systems change afterwards Steps 1 and 2 are usually a one-off load followed by incremental amendments; steps 3 to 6 are your day-to-day traffic. > What this API is for, and how the pieces fit together ## Docs - [Authentication](https://docs-unsw-v6.advance-uac.com/authentication.md): Getting a token, using it, and what it grants you - [Curriculum structures](https://docs-unsw-v6.advance-uac.com/curriculum-structures.md): How a program's requirements are modelled, built and published - [Credit outcomes](https://docs-unsw-v6.advance-uac.com/credit-outcomes.md): Reading the credit decision on an application, and knowing when it is final - [Detecting changes](https://docs-unsw-v6.advance-uac.com/detecting-changes.md): Keeping your records in step without polling applications one at a time - [Correcting records](https://docs-unsw-v6.advance-uac.com/corrections.md): Amending an application or applicant you have already sent us - [Assessment workflows](https://docs-unsw-v6.advance-uac.com/workflows.md): The process an application goes through, and which of your programs use it - [Academic approval](https://docs-unsw-v6.advance-uac.com/academic-approval.md): When awarded credit goes to an academic, and what you can see of it - [Application ownership](https://docs-unsw-v6.advance-uac.com/application-ownership.md): Which team picks up an application, and how it gets decided