> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mesolab.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Recommend learning outcomes

> Suggest curriculum learning outcomes relevant to a topic.

Given a subject and a topic, returns the specification learning outcomes most
relevant to it, ranked. This is the retrieval step behind **MESO Align**.

Matching is semantic: the topic is embedded server-side and compared against
pre-computed embeddings of every outcome in the subject specification. Clients
pass natural language and never see a vector.

## Request

**subjectCode** `string` *required*

Specification code for the subject, e.g. `"ENG"` — **not** a display name like
`"English"`. See [supported subjects](#supported-subjects).

**topic** `string` *required*

The topic to match against, e.g. `"Shakespeare's Romeo and Juliet"`.

**selectedOutcomes** `string[]`

Outcomes the teacher has already chosen. These are excluded from the results,
so repeated calls keep surfacing new suggestions rather than the same top hits.

**k** `number` (default: 5)

How many recommendations to return.

```bash cURL theme={null}
curl -X POST "$BASE_URL/recommend-lo" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "subjectCode": "ENG",
        "topic": "Shakespeare'\''s Romeo and Juliet",
        "k": 5
      }'
```

## Response

**success** `boolean`

`true` on a successful match.

**recommendations** `object[]`

Ranked outcomes, most relevant first. Each entry carries the specification
metadata plus a `score`.

**metadata** `object`

Echoes `subjectCode` and `topic`, plus `count` and an ISO `timestamp`.

```json Response theme={null}
{
  "success": true,
  "recommendations": [
    {
      "id": 142,
      "subject_code": "ENG",
      "text": "explore the relationship between character and plot",
      "score": 0.83
    }
  ],
  "metadata": {
    "subjectCode": "ENG",
    "topic": "Shakespeare's Romeo and Juliet",
    "count": 5,
    "timestamp": "2026-08-21T12:00:00.000Z"
  }
}
```

## Errors

Failures carry a machine-readable `code` alongside the message — this endpoint
and [`/recommend-as`](https://docs.mesolab.ai/api-reference/curriculum/recommend-as) are the only two
that do.

| `code` | Status | Cause |
| - | - | - |
| `METHOD_NOT_ALLOWED` | 405 | Anything other than `POST`. |
| `MISSING_SUBJECT_CODE` | 400 | `subjectCode` absent. |
| `UNSUPPORTED_SUBJECT` | 400 | Not in the supported list. The message names every code that is. |

## Supported subjects

Junior cycle: `ART`, `BUS`, `CLA`, `CSP`, `EGN`, `ENG`, `GEO`, `GRA`, `HEC`,
`HIS`, `IRT1`, `IRT2`, `MAT`, `MFL`, `MUS`, `PE`, `REL`, `SCI`, `SPH`, `TECH`,
`WOO`.

Senior cycle: `ARA_SC`, `BIO_SC`, `BUS_SC`, `CASD_SC`, `CHEM_SC`, `DFTS_SC`,
`GRK_SC`, `LAT_SC`, `PHY_SC`, `SPHE_SC`.

> [!NOTE]
>
> Codes are matched case-insensitively. A subject absent from this list has no
> embeddings built yet — the call fails rather than falling back to a weaker match.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.