Coming soon. This endpoint is not available yet, and the details below may change before release.
Creates a content record and its items. A content record is a single container holding one or more items of different kinds — an e-learning package, a document, a video, a block of rich text, a link, and so on.
Created is not the same as publishable
A new record starts in draft. Before it can be published it must reach ready, and that needs both of the following, both of which happen asynchronously after this call returns:
- Every item processed. Upload items (e-learning, file, video,
audio, image) start at
processing. Upload the artefact to the matching URL insignedPutUrls, and the item flips tookonce the platform has processed it. Aurlitem is scraped for its title, description and image. Arich_textitem is ready immediately. - A thumbnail. Content cannot reach
readywithout one, and there is no default. Either pass athumbnailUrland we fetch it for you, orPUTyour image to thethumbnailUploadUrlreturned below.
Poll GET /rest/v1/contents/{id} to follow progress. For content created through this API, that read also returns the record's overall status and the processing state of each of its items. It is the only place per-item state is reported — the content list cannot show it.
Publishing
There are three ways to publish, and you choose:
- Set
publishWhenReady: truehere, and the record publishes itself the moment it becomes ready. Because readiness waits on the slowest of e-learning unpacking, link scraping and thumbnail processing, this can be some time after the call returns. - Leave it unset and call
POST /contents/{id}/publishwhen you are ready. - Leave it unset and publish manually in the authoring UI.
Skills and topics
skills and topics are only stored on creation when publishWhenReady is also set. Sending them without it is rejected with 422, rather than accepting them and silently dropping them. In every other case, set them on the publish call.
Other limits
Backdating is not available here. To record an original publish date, use the
publishedAtfield on the publish call.At most one upload item plus one non-upload item per request. Two upload items in one call is rejected. Add further items with
PATCH /contents/{id}.At most one e-learning item per content record, ever.
Every item needs a unique
rank, and every upload item a uniqueuploadId. Repeating either within one request is rejected.languageCodeis normalised for you:enanden-GBboth resolve toen-gb. A language the platform does not support is rejected.
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.
Create with an e-learning package
Creates a record holding a SCORM package and a short welcome note, and asks the platform to publish it as soon as it is ready. Skills and topics are allowed here because publishWhenReady is set. The response returns a presigned URL for course.zip and one for the thumbnail.
{
"title": "Onboarding pack",
"primaryCategory": "elearning",
"authorRef": "UID30084022",
"languageCode": "en-gb",
"publishWhenReady": true,
"completionType": "on_elearning_completion",
"skills": [
"leadership"
],
"topics": [
"onboarding"
],
"items": [
{
"type": "elearning",
"rank": "0",
"summary": "Onboarding course",
"meta": {
"name": "course.zip",
"uploadId": "4f1c2b7e-9a3d-4c8e-b2f1-6d0a7c5e3b91"
}
},
{
"type": "rich_text",
"rank": "1",
"summary": "Welcome",
"meta": {
"body": "Welcome to the team.
"
}
}
]
}Create from a link
The cheapest kind of content to create — no file to upload. The link is fetched in the background for its title, description and image. A thumbnailUrl is supplied so the record can reach ready without a separate thumbnail upload. Skills and topics are omitted because publishWhenReady is not set; they are set on the publish call instead.
{
"title": "Company handbook",
"primaryCategory": "article",
"authorRef": "UID30084022",
"languageCode": "en-gb",
"thumbnailUrl": "https://example.com/thumb.png",
"items": [
{
"type": "url",
"rank": "0",
"summary": "Handbook",
"meta": {
"url": "https://example.com/handbook"
}
}
]
}The content record to create, along with its initial items.
Title of the content
How the content should be categorised in the catalogue. Taken as you declare it — it is not inferred from the items you send.
The language of the content. Normalised before it is stored: en and en-GB both resolve to en-gb, de-at resolves to de. A language the platform does not support is rejected.
Publish the content automatically as soon as it becomes ready. Because readiness waits on item processing and the thumbnail, this normally happens some time after this request returns.
How a learner completes this content. auto, confirm and external apply to any content; on_elearning_completion requires an e-learning item; on_passing_quizzes, on_passing_observer_completed_quizzes and on_passing_assessments apply to quiz and assessment items, which are not yet supported by this API.
Note that on_elearning_completion combined with a web-format e-learning package can never reach ready.
Skills to associate with the content. Only stored when publishWhenReady is also set — sending skills without it is rejected with 422. Otherwise set them on the publish call.
Topics to associate with the content. Only stored when publishWhenReady is also set — sending topics without it is rejected with 422. Otherwise set them on the publish call.
A publicly reachable image we should fetch and use as the content thumbnail. Content cannot reach ready without a thumbnail, so either supply this or upload your own image to the thumbnailUploadUrl returned in the response. Either way the image is processed asynchronously.
The items that make up the content. Optional, but content with no items can never reach ready and so can never be published.
At most one upload item (e-learning, file, video, audio, image) plus one non-upload item (rich text, url) per request. Add further items later with PATCH /contents/{id}.
One item within a content record. The type decides which meta fields apply.
Upload items — elearning, file, video, audio and image — are two-phase: you declare the item here with an uploadId you generate, then PUT the file to the matching URL returned in signedPutUrls. The item stays at processing until the platform has handled the file.
Non-upload items — rich_text is ready immediately; url is scraped asynchronously for its title, description and image.
The item's position within the content, lowest first. Required, and every item in a content record must have a different rank.
A short label for the item, shown to learners. Optional on upload items; required on rich text and link items.
The file name, including its extension. The extension must match the item type you declared — a .pdf sent as a video is rejected.
A UUID you generate for this upload. It is echoed back in signedPutUrls so you can tell which URL belongs to which item, and must be unique within the content.
Whether learners may download the original file
The package format. Normally detected while the package is unpacked, so you rarely need to send it. A web package cannot be used with a completionType of on_elearning_completion.
The item's position within the content, lowest first. Required, and every item in a content record must have a different rank.
A short label for the item, shown to learners. Optional on upload items; required on rich text and link items.
The file name, including its extension. The extension must match the item type you declared — a .pdf sent as a video is rejected.
A UUID you generate for this upload. It is echoed back in signedPutUrls so you can tell which URL belongs to which item, and must be unique within the content.
Whether learners may download the original file
The document's page count, used to estimate its duration.
This field is under review. It is currently required, but the page count cannot be known until after the file has been uploaded. Document items are therefore not yet usable end to end, and this requirement is expected to be relaxed before release.
The item's position within the content, lowest first. Required, and every item in a content record must have a different rank.
A short label for the item, shown to learners. Optional on upload items; required on rich text and link items.
The file name, including its extension. The extension must match the item type you declared — a .pdf sent as a video is rejected.
A UUID you generate for this upload. It is echoed back in signedPutUrls so you can tell which URL belongs to which item, and must be unique within the content.
Whether learners may download the original file
The spoken language of the video
The item's position within the content, lowest first. Required, and every item in a content record must have a different rank.
A short label for the item, shown to learners. Optional on upload items; required on rich text and link items.
The file name, including its extension. The extension must match the item type you declared — a .pdf sent as a video is rejected.
A UUID you generate for this upload. It is echoed back in signedPutUrls so you can tell which URL belongs to which item, and must be unique within the content.
Whether learners may download the original file
The audio duration in milliseconds.
This field is under review. It is currently required, but the duration cannot be known until after the file has been uploaded. Audio items are therefore not yet usable end to end, and this requirement is expected to be relaxed before release.
The item's position within the content, lowest first. Required, and every item in a content record must have a different rank.
A short label for the item, shown to learners. Optional on upload items; required on rich text and link items.
The file name, including its extension. The extension must match the item type you declared — a .pdf sent as a video is rejected.
A UUID you generate for this upload. It is echoed back in signedPutUrls so you can tell which URL belongs to which item, and must be unique within the content.
Whether learners may download the original file
Alternative text, used by screen readers
A caption shown beneath the image
A link to open when the image is selected
Whether ctaUrl opens in a new tab
The item's position within the content, lowest first. Required, and every item in a content record must have a different rank.
A short label for the item, shown to learners. Optional on upload items; required on rich text and link items.
The rich text body as HTML
The item's position within the content, lowest first. Required, and every item in a content record must have a different rank.
A short label for the item, shown to learners. Optional on upload items; required on rich text and link items.
Either an external link or a reference to other content on the platform. External links must be publicly reachable — those resolving to internal or private addresses are rejected.
The created content, with presigned upload URLs for any upload items and for the content thumbnail.
Created, waiting on an upload and a thumbnail
The record exists but is still draft. The e-learning item is processing because its file has not been uploaded yet; the rich text item is already ok. Upload course.zip to the matching signedPutUrls entry and the image to thumbnailUploadUrl, then poll GET /rest/v1/contents/{id} until the status reaches ready.
{
"id": "5f9d88d6e1b2a34c56d78902",
"status": "draft",
"items": [
{
"id": "5c8936159ec2d00010cdd334",
"type": "elearning",
"rank": "0",
"summary": "Onboarding course",
"status": "processing"
},
{
"id": "5c8936159ec2d00010cdd335",
"type": "rich_text",
"rank": "1",
"summary": "Welcome",
"status": "ok"
}
],
"signedPutUrls": [
{
"uploadId": "4f1c2b7e-9a3d-4c8e-b2f1-6d0a7c5e3b91",
"url": "https://s3.example.com/uploads/4f1c2b7e?X-Amz-Signature=..."
}
],
"thumbnailUploadUrl": "https://s3.example.com/thumbnails/5f9d88d6?X-Amz-Signature=..."
}What the create and update endpoints return: the content record, plus everything you need to finish setting it up — presigned URLs for any items awaiting a file, and one for the content thumbnail.
Unique identifier for the content
Lifecycle status of a content record. Note this is a different vocabulary from the statuses filter on GET /contents, which uses the legacy values created, published, archived and deleted.
The items that make up the content, with per-item processing state
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
Presigned URLs for the upload items in this request, one per item. Empty when the request added no upload items. Use GET /contents/{id}/upload-urls if one expires before you upload.
A presigned URL to PUT one item's file to.
The uploadId you supplied for the item this URL belongs to
The presigned URL. Time-limited — upload promptly.
A presigned URL to PUT the content thumbnail to. Null when you supplied a thumbnailUrl for us to fetch instead. The content cannot reach ready until a thumbnail has been processed by one route or the other.
Unauthorized
Unauthorized
Forbidden
Forbidden
Unsupported Media Type — Content-Type must be application/json
The request could not be processed due to a validation error
Unprocessable Content
Unprocessable Content
Bad Gateway
The request could not be completed because a service it depends on failed. For write operations the content was not modified.
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