Creates a content record in created (draft) state.
A request can carry at most one upload item (elearning, video or image) plus one non-upload item (rich_text or url). For each upload item the response returns a signedPutUrls entry — PUT the artefact to that URL to complete the item. Upload items and url items are processed asynchronously; rich_text items complete synchronously.
authorRef is required. It is your organisation's reference for the acting user and drives the recorded authorship. The user must exist in your organisation and be active. A new, suspended, expired or deleted user is rejected. An optional collaborationId makes the collaboration own the content; the author is then recorded as the actor and must be a member of that collaboration.
skills and topics are only stored when publishWhenReady is true; without it the request is rejected, because they would be discarded. To tag a draft, publish it with skills and topics later. Every skill must already exist in your organisation; a topic is a free name. Both are stored in the content tags, and the reads return tags, skills and topics.
completionType: on_elearning_completion never completes for a web format e-learning package. The request is rejected when meta.format: web is supplied explicitly; when the format is detected during processing, the content stays in created state instead.
isOfficial: true creates the content as endorsed. A cpdCategoryId is only accepted on endorsed content, so send it together with isOfficial: true; without it the request is rejected with 400. The category must exist in your organisation, or the request is rejected with 422.
A thumbnail is required before the content can publish. This endpoint does not take image bytes. Send thumbnail: { uploadId } with a UUID you generate, and the response returns a matching signedPutUrls entry. PUT the image (JPEG, PNG, GIF or WebP) to that URL, the same way you PUT an item file. Thumbnail processing is asynchronous: the content stays created until the image has been resized and stored, then it becomes ready, and it publishes on its own when publishWhenReady is true. The URL is valid for about 10 minutes. To get a new one, or to replace the thumbnail later, send a PATCH with thumbnail again. Content without a thumbnail never becomes ready. Bytes that are not a readable image end as a placeholder thumbnail, which still counts as a thumbnail for readiness, so check what you upload. The uploadId must differ from every item uploadId in the same request (400 otherwise).
OAuth2 (Cognito) tokens need the api/write or api/all scope. API tokens are not scoped.
HTTP Basic authentication using your Tenant ID and API secret.
- Username is the Tenant ID (i.e.
eu-west-2_AbcdEfghI) - Password is the API secret you would have received.
You can also authenticate using OAuth 2.0 client credentials (oauth2 security scheme) instead of Basic auth.
OAuth 2.0 client credentials authentication.
Use the following token endpoints (replace :tenantId with your Tenant ID):
Public API access tokens
- Staging:
https://public.api.learnstaging.link/oauth2/token/:tenantId - Production:
https://public.api.learn.link/oauth2/token/:tenantId - Staging MEA:
https://public.api.meastaging.learn.tech/oauth2/token/:tenantId - Production MEA:
https://public.api.mea.learn.tech/oauth2/token/:tenantId
- Staging:
Webhooks access tokens
- Staging:
https://user.api.learnstaging.link/oauth2/token/:tenantId - Production:
https://user.api.learn.link/oauth2/token/:tenantId - Staging MEA:
https://user.api.meastaging.learn.tech/oauth2/token/:tenantId - Production MEA:
https://user.api.mea.learn.tech/oauth2/token/:tenantId
- Staging:
All access tokens must be sent using the Authorization: Bearer <access_token> header.
Scopes
For API access (non-webhooks), the following scopes are available:
api/all– Full read and write access to the API.api/read– Read-only access to the API.api/write– Write access to the API.
For webhooks, the following scopes are available:
api/webhooks– Access to webhook functionality.api/all– Full read and write access to the API, including webhooks.
Tokens must include appropriate scopes for the endpoints you wish to call.
An e-learning package with a welcome text
Creates a draft with one upload item and one rich text item, and stores a skill and a topic with it. It also asks for a thumbnail upload URL. PUT the package bytes and the thumbnail image to the two returned signedPutUrls entries; once both are processed the content publishes itself.
{
"title": "Onboarding pack",
"languageCode": "en-gb",
"authorRef": "UID30084022",
"publishWhenReady": true,
"thumbnail": {
"uploadId": "8b1e3d2a-4c5f-4e6a-9b7c-0d1e2f3a4b5c"
},
"skills": [
"leadership"
],
"topics": [
"onboarding"
],
"completionType": "on_elearning_completion",
"items": [
{
"type": "elearning",
"rank": 0,
"meta": {
"name": "course.zip",
"uploadId": "123e4567-e89b-42d3-a456-426614174000"
}
},
{
"type": "rich_text",
"rank": 1,
"summary": "Welcome",
"meta": {
"body": "Welcome to the team!
"
}
}
]
}authorRef and, when present, collaborationId are validated in your organisation before anything is created.
The content language, for example en-gb.
Your organisation's reference for the acting user. The user becomes the recorded actor, and the author unless a collaboration owns the content. The user must be active. A new, suspended, expired or deleted user is rejected.
The collaboration that owns the content. The authorRef user must be a member of it, or the request is rejected with 422.
Publish automatically when the content becomes ready: every item has completed processing and the content has a thumbnail. Send thumbnail to get a thumbnail upload URL in the same response; without a thumbnail the content stays created. The flag is stored so the publish happens as soon as the record is ready.
Skills to associate with the content. Each name must be an existing skill in your organisation, or the request is rejected with 422. Only accepted together with publishWhenReady: true. Stored in the content tags alongside the topics.
Topics to associate with the content. Free names; a topic is not checked against your organisation's tags. Only accepted together with publishWhenReady: true. Stored in the content tags alongside the skills. A name cannot appear in both lists.
The declared category. A default is inferred when it is omitted. The value is case insensitive, but send it in lower case.
How the content is completed. Defaults to auto. auto, confirm and external apply to any content; on_elearning_completion requires an e-learning item. The quiz, assessment and interactive types require item types this API cannot create yet, so they are rejected with a 409.
A custom duration in milliseconds.
Create the content as endorsed by your organisation. Defaults to false.
The CPD category to record this content against. Only accepted together with isOfficial: true (400 otherwise). The category must exist in your organisation (422 otherwise).
Asks for a thumbnail upload URL. The content thumbnail is uploaded like an item file: give the upload a UUID here and PUT the image bytes (JPEG, PNG, GIF or WebP) to the signedPutUrls entry that echoes it. The uploadId is not stored; it only pairs this request with its response entry, so it must differ from every item uploadId in the same request (400 otherwise). A content has one thumbnail, and a later upload replaces it. Processing is asynchronous: the thumbnail counts for readiness once the image has been resized and stored.
A UUID you generate for this upload.
The content items. At most one upload item (elearning, video or image) plus one non-upload item (rich_text or url) per request. Each rank must be unique.
The display position of the item.
A short description of the item.
The rich text body. May contain HTML.
A public HTTP(S) address. The link preview is generated asynchronously.
The package file name, for example course.zip.
A client-generated UUID for the upload. The response echoes it in signedPutUrls.
The package format. Normally detected during processing — supply it only when known.
The file kind. The file extension in meta.name must match it.
The file name, for example intro.mp4 or cover.png.
A client-generated UUID for the upload. The response echoes it in signedPutUrls.
Whether learners can download the file.
Created — the content is in created (draft) state
The created content with its presigned upload URLs. In the rare case that the content was created but could not be read back, the response is the minimal form: id, status and signedPutUrls only. The content exists in both cases — do not retry the request. A full body also satisfies the minimal shape, so this is anyOf.
Unique identifier for the content
Title of the content
Detailed description of the content, may contain HTML
List of tags associated with this content. Omitted when the tag source cannot be read, so an absent field means "tags unavailable" rather than "no tags".
The tags entries that the taxonomy marks as a skill. Additive: every name is also in tags. A tag the taxonomy does not hold is in neither skills nor topics. Both fields are absent when the taxonomy cannot be read.
The tags entries that the taxonomy marks as a topic. Additive: every name is also in tags. A tag the taxonomy does not hold is in neither topics nor skills. Both fields are absent when the taxonomy cannot be read.
The kind of artifact associated with this content record.
Courses are represented as pathway. Pathways will be served by a dedicated Pathways API in a future release and will stop appearing on this endpoint at that point, so treat pathway as temporary here.
Timestamp when the content was created
Timestamp when the content was last updated
User ID who authored this content. Nullable for auto-curated content.
Whether the content has been recognized for its importance or validity by the customer organization
The CPD category the content is recorded against, or null when it has none. Present when a record is read by its id or returned by a v2 create or update, for content held by the content source that carries CPD data. The field is not present in the results of the list endpoint, nor on a record that exists only in the legacy content source.
The expected time to complete the content. Null for Event content types. For SAP-imported content, this value may reflect a system default rather than a precise measured duration.
Duration in the specified unit. Null when no duration is available (e.g. pathways).
The unit of the duration value. Always 'minutes'.
Chronological history of actions on this content (from content-service). May be empty when there is no recorded history.
Type of change or event recorded for the content.
When the action occurred.
Kind of actor (for example user or system).
Identifier or value associated with the actor.
Last actor who updated the content, derived from history (or author fallback). Null when neither history nor author resolves.
User ID or service identifier.
Email from the user view when available.
External reference (e.g. HR id) when stored on the user view.
The content provider. Defaults to Thrive for natively created content.
Provider identifier key.
Human-readable provider display name.
Lifecycle status of the content. A legacy (content-service) record derives the value: archived content reports archived, content with a publish time reports published, and all other content reports created. A content-core record maps its lifecycle status onto the same values, where draft and ready both report created. deleted is a filter value only and is never returned: a legacy record returned by a deleted status filter reports its pre-deletion state, and a deleted content-core record is physically gone.
The items that make up a content record, with per-item processing state. Only GET /contents/{id} returns this field, and only for records served from content-core; the GET /contents list never includes it.
One item within a content record, with its processing state.
Unique identifier for the item
The item type
The item's position within the content, lowest first
A short label for the item, shown to learners
The item's processing state. An item must reach ok before the content can become ready.
Why processing failed, when status is error
One entry for each upload item in the request, plus one for the thumbnail when the request carried thumbnail. Empty when the request carried neither. In the rare case that the thumbnail URL could not be issued, its entry is missing while the content was still created; send a PATCH with thumbnail to get one.
A presigned URL to PUT one upload's bytes to: an item file, or the content thumbnail image.
The uploadId you supplied for the item, or for the thumbnail, this URL belongs to
The presigned URL. Time-limited (about 10 minutes) — upload promptly.
Unique identifier for the content
On a create, one entry for each upload item in the request. On an update, one entry for each upload item added and each item whose file was replaced. Plus one for the thumbnail when the request carried thumbnail. Empty when the request carried none.
A presigned URL to PUT one upload's bytes to: an item file, or the content thumbnail image.
The uploadId you supplied for the item, or for the thumbnail, this URL belongs to
The presigned URL. Time-limited (about 10 minutes) — upload promptly.
Bad Request — a cross-field rule failed (more than one upload or non-upload item, skills or topics without publishWhenReady, a name in both skills and topics, on_elearning_completion with a web format item, cpdCategoryId without isOfficial: true, a thumbnail uploadId that repeats an item uploadId), or the upstream content source rejected the payload (see violations when present)
The error envelope of the V2 endpoints.
Present on field validation failures. One entry per failed rule.
One failed validation rule.
The dotted path of the field that failed, for example items.0.meta.body. Empty for a body-level rule.
Why the field failed.
Unauthorized
Unauthorized
Forbidden — the OAuth2 token does not carry the api/write or api/all scope
The error envelope of the V2 endpoints.
Present on field validation failures. One entry per failed rule.
One failed validation rule.
The dotted path of the field that failed, for example items.0.meta.body. Empty for a body-level rule.
Why the field failed.
Conflict — the upstream content source reported a conflict, for example a duplicate import reference
The error envelope of the V2 endpoints.
Present on field validation failures. One entry per failed rule.
One failed validation rule.
The dotted path of the field that failed, for example items.0.meta.body. Empty for a body-level rule.
Why the field failed.
Unsupported Media Type — Content-Type must be application/json
The error envelope of the V2 endpoints.
Present on field validation failures. One entry per failed rule.
One failed validation rule.
The dotted path of the field that failed, for example items.0.meta.body. Empty for a body-level rule.
Why the field failed.
Unprocessable Content — a field failed validation (see violations), authorRef does not match an active user, collaborationId does not resolve in this organisation, the author is not a member of the collaboration, a skill is not an existing skill in this organisation, or cpdCategoryId does not match a CPD category in this organisation
The error envelope of the V2 endpoints.
Present on field validation failures. One entry per failed rule.
One failed validation rule.
The dotted path of the field that failed, for example items.0.meta.body. Empty for a body-level rule.
Why the field failed.
Too Many Requests — the upstream content source is rate limiting this organisation. Retry after the Retry-After header when it is present.
The error envelope of the V2 endpoints.
Present on field validation failures. One entry per failed rule.
One failed validation rule.
The dotted path of the field that failed, for example items.0.meta.body. Empty for a body-level rule.
Why the field failed.
Internal Server Error — the request failed inside the API service. The content may not have been created.
The error envelope of the V2 endpoints.
Present on field validation failures. One entry per failed rule.
One failed validation rule.
The dotted path of the field that failed, for example items.0.meta.body. Empty for a body-level rule.
Why the field failed.
Upstream content source failure, or the skills or the CPD category could not be verified — the content was not created
The error envelope of the V2 endpoints.
Present on field validation failures. One entry per failed rule.
One failed validation rule.
The dotted path of the field that failed, for example items.0.meta.body. Empty for a body-level rule.
Why the field failed.
An unexpected error has occurred
When any default error occurs it may be a system failure and persistent errors may require support.
The server is unable to process the request