Skip to content

Core concepts

This page is the mental model behind the API: how learners are identified, which identifier you join on, what the cognitive assessment produces, how support and evidence are modelled, and what your credentials can see. It explains meaning, and it is the one place other pages link back to for the identifiers, the result codes, and the access scope.

For the exact fields, types, and full enums of any object, follow the link to the API reference. That is the source of truth for schemas, and this page never duplicates it.

Read this once, then head to the guides for the task in hand.

On this page, jump to the concept you need:

Learners and identifiers

A learner is the central record. You create one with POST /v1/learners and read it back with GET /v1/learners/{learnerId}. Each learner carries several identifiers, and each has a job to do. Get the roles right once and the rest of the integration is straightforward.

  • Join on clientReference. It is the learner's id in your own system, which you supply and should send on every create. It is the durable key you store on both sides and reconcile against. You own it and keep it unique; the API treats it as an opaque string.
  • Store learnerId and learnerUserId from the create response, and use learnerId for every later call about the learner.
  • Resolve or recover with email. A learner's email is unique within your organisation, so GET /v1/learners/{email} returns the one learner, and the paged list carries it. Use it to find or confirm a learner, not as your stored join, because an email can change.
  • Carry a ULN in learnerUniqueReference if you hold one. It is an optional secondary reference, validated on create and unique within your organisation, but optional, so it is not a substitute for clientReference.
Identifier Role Notes
clientReference Primary join key you build on Your own id for the learner. Always set it on create. You keep it unique; the API does not enforce that for you.
learnerId Cognassist learner id Returned on create. Use on every learner-scoped call. Store it.
learnerUserId Cognassist user id Returned on create. Store it alongside learnerId.
email Reliable lookup, not a stored join Required on create and the invite address. Unique within your organisation, so GET /v1/learners/{email} resolves one learner. It can change over time.
learnerUniqueReference Optional secondary identifier The slot for a ULN. Validated on create and unique within your organisation. Optional, so not your primary join.

Create does not duplicate, and does not update

Because a learner's email is unique within your organisation, creating a learner whose email already belongs to a learner is rejected, not silently duplicated, and POST /v1/learners never updates an existing learner. So reconcile on your clientReference and look a learner up by email before you create, so two enrolment paths cannot try to create the same person. See create and manage learners for the full flow.

There is no native ULN field (learnerUniqueReference above is the nearest slot) and no server-side filter on clientReference. The provider itself (your organisation) is identified by its UKPRN. Full field lists live in the API reference.

Field casing: camelCase in REST bodies, PascalCase in webhook payloads

The same logical field is spelled two ways depending on the surface, so build one model and map between them. REST request and response bodies use camelCase (clientReference, learnerId, firstName, learnerUniqueReference). Webhook payloads use PascalCase: both the envelope (Data, SystemEvent, DataId) and the learner export records (ClientReference, LearnerUniqueReference, FirstName, IdentifiedDomains, CoverageCheckStatus).

So ClientReference in an export is the same join key as the clientReference you set on create, and LearnerUniqueReference is the same field as learnerUniqueReference, not a different key or a typo. When you reconcile export records back to learners created or read via REST, map PascalCase to camelCase on that boundary. The API reference is the source of truth for the exact casing on each surface.

Your organisation is a single client

Your organisation is one Cognassist client with one credential set, however many campuses or sites it spans. You do not create a separate credential set per site: one integration, against one set of credentials, covers the whole organisation.

Planned: Location will make the distinction between sites within an organisation a first-class, filterable field, so you can report by site directly. It is not exposed by the API today; see the roadmap.

What the list returns vs a single learner

This distinction shapes how you reconcile, so it is worth stating plainly. The paged list and a single-learner read return different shapes, and the key consequence is that the list carries email, not clientReference. Because email is unique within your organisation, matching list rows on email is reliable; fetch a single learner when you need clientReference.

GET /v1/learners returns, per learner, only these six fields, plus a top-level totalRecords:

  • learnerId
  • learnerUserId
  • firstName
  • lastName
  • email
  • proactivelyProvidingSupport

It does not return clientReference or learnerUniqueReference, and there is no server-side filter on either. To reconcile the whole estate, page until you have collected totalRecords and match rows on email (reliable, because email is unique within your organisation); the base page index is not published, so confirm it in the API reference. Fetch a single learner when you need the clientReference join. For the exact list-projection schema, see LearnerListResult in the API reference.

GET /v1/learners/{learnerId} and GET /v1/learners/{email} return the full learner, which does include clientReference and learnerUniqueReference alongside the rest of the profile. See the API reference for the full object.

The cognitive profile

When a learner finishes the assessment, the assessment result returns their profile. It measures nine cognitive domains, which roll up into six indexes. A cognitive profile is a signal, not a diagnosis and not a deficit label. It describes how a learner works best and where they may benefit from support.

Cognitive domains (1 to 9) Cognitive indexes (1 to 6)
1 Verbal Memory · 2 Literacy · 3 Numeracy · 4 Visual Information Processing Speed · 5 Non Verbal Memory · 6 Executive Function · 7 Verbal Reasoning · 8 Visual Perception · 9 Reading Decoding 1 Language · 2 Visual · 3 Memory · 4 Speed of working · 5 Non-speed of working · 6 Speed of working difference

Each domain result pairs a domain with an outcome, and from those results the API derives two summary signals: a three-tier classification (learnerStatus) and a support-likelihood rating (supportLikelihoodRating). These are decision-support signals for the people delivering learning, not gates.

The result codes are small, stable, and display-critical enums, so they are decoded in full below. The API reference remains the source of truth for the exhaustive schema; the tables here exist because they carry the integer-to-meaning mapping a caller needs to render a result, which the reference does not spell out in prose.

Result codes: domainResult, learnerStatus, supportLikelihoodRating, status

domainResult: the outcome for a single domain.

Code Meaning
1 Not identified
2 Identified
3 Insufficient data

learnerStatus: the three-tier classification.

Code Meaning
10 No need identified
20 Monitor and review
30 Consider a needs assessment

supportLikelihoodRating: how confidently a need is indicated. Higher is a stronger signal, and an index match outranks a domain match.

Code Meaning
-1 Not applicable
0 None
1 One domain
2 Two domains
3 Three or more domains
4 One index
5 Two indexes
6 Three indexes

status: the assessment lifecycle state. All three values are from the LearnerAssessmentStatus enum in source.

Label Integer
Awaiting results 10
Not completed 20
Completed 30

Worked example: a result of status: Completed (30), learnerStatus: 20, supportLikelihoodRating: 4 decodes to Completed · Monitor and review · one index identified.

See retrieve and render results for how to display these signals responsibly.

Evidence and support records

Support records are the record of support delivered. List them with GET /v1/learners/{learnerId}/supportrecords and read one with GET /v1/learners/{learnerId}/supportrecords/{supportRecordId}. Two enums are worth knowing:

  • supportType distinguishes a session type: 10 Regular or 20 Above and beyond (the latter also captures session type and duration).
  • coverageStatus grades the evidence: 10 Blank (no coverage data recorded yet), 20 Needs improvement, or 30 Meets standard.

Records differ by endpoint — the list returns summary fields only; the single-record read returns the full detail:

Field List (GET .../supportrecords) Single record (GET .../supportrecords/{id})
id, supportType, coverageStatus, startDate, endDate, lastUpdatedDate, createdBy
supportProvided, supportReflections
supportSessionType, durationOfSupport ✓ (Above and beyond records only)
selectedModules, selectedReasonableAdjustments
coverage (the three I's)

The supportType and coverageStatus values above are the canonical decode; other pages, including the export webhook that delivers this same shape in bulk, link here rather than restate them. Full schemas are in the API reference.

Reasonable adjustments and the three I's

Reasonable adjustments are the practical changes made so a learner can work around an identified barrier. Everyday adjustments of this kind are recognised by most awarding organisations. Today you read them as selectedReasonableAdjustments on evidence records.

Each support record also carries a coverage object recording the three I's, the questions that make an adjustment defensible, each with a matching free-text reasoning field:

The three I's Question it answers
Intent Was the adjustment planned with clear intent?
Implementation Was it actually put in place?
Impact Did it make a difference for the learner?

Planned: exposing the agreed support plan and its reasonable adjustments as structured data (name, implementation, goals, impact per adjustment), plus plan and review webhook events. Today you read adjustment evidence through support records; the structured plan itself is not yet on the API. See the roadmap.

The golden thread

Each support record links its reasonable adjustments back to the barrier the assessment identified:

flowchart LR
    A[Assessed barrier] --> B[Reasonable adjustment] --> C[Support delivered<br/>session] --> D[Coverage recorded<br/>the three I's]

Preserve that link when you store or display evidence. This unbroken chain is what makes the data audit-grade evidence you can feed into your own funding and audit processes, and it helps you evidence inclusion and impact for Ofsted.

Cost recovery remains your decision under your own eligibility and quality policy: Cognassist supplies the evidence, and you use it within your own funding and audit processes with the DfE. The learner export packages this whole chain, per learner, in one payload.

Access scope, roles, and visibility

This is the canonical definition of what your credentials can see; other pages link here rather than restate it.

Your credentials are scoped to your organisation. Every endpoint only returns your organisation's learners. A learner outside that scope simply is not in your results; that is expected, not an error.

Who sees which learner is governed by assignment on top of coarse roles, not a fine-grained permission grid:

  • Each learner has one primary tutor plus any number of secondary tutors. Assigning a tutor requires a manager or admin.
  • A tutor sees their assigned learners; a tutor manager sees their tutors' learners; an admin sees everyone in the organisation.
  • Primary vs secondary is a professional convention (the primary tutor is the person who reviews the plan and records evidence), not an app-enforced read-only lock.
  • Leadership dashboards (Insights) are admin-only.

Tutors exist in the Cognassist app, not via the API. There is no endpoint to create or list tutors, so provision your staff accounts in the app before your first create call: a learner's primaryTutorEmail must resolve to a tutor who already exists, which is the most common first-integration trip-up. You can assign that existing tutor as primary on create, name secondary tutors on create with secondaryTutorEmails, and change the secondary set later with PUT /v1/learners/{learnerId}/secondarytutors.

Planned: staff-assignment endpoints (creating or listing tutor accounts through the API), filterable Tags (for example course codes, kept separate from the course description that drives personalisation), and Location (see your organisation is a single client above) are not exposed by the API today; see the roadmap.

Where to go next