Docebo
The Docebo source ingests the course catalog of a Docebo LMS instance through the Learn REST API. Each course becomes an HTML document and carries the course description together with a curriculum outline of the course's training materials. Questions such as "which training covers this topic?" are answerable from the course record alone. Category, language, and skills become filterable metadata.
What is ingested
The source ingests courses, not the training materials inside them.
A course's materials — SCORM and xAPI packages, videos, quizzes, and HTML pages — are not downloaded; Docebo does not serve their contents to a server-to-server integration. Each material's title, type, and description are rendered into the course document as a Course contents outline.
Docebo's catalogs are not ingested, and catalog membership is not available as document metadata.
Authentication
auth is required. Before you create the pipeline, create an OAuth 2.0
application in the Docebo administration interface under Settings → API and
SSO, and make sure the application is permitted to read courses. An
application without that permission receives 401 Unauthorized from the course
endpoints even though its token is valid.
Supply the credential as a RemoteAuth credential.
auth.type | Fields | Resulting header |
|---|---|---|
oauth_client_credentials | client_id, client_secret, token_endpoint, and optionally scopes | A fetched Authorization: Bearer <token> |
bearer | token | Authorization: Bearer <token> |
header | header, value | The value sent verbatim under the named header |
Docebo issues OAuth 2.0 client credentials for server-to-server access, so
oauth_client_credentials is the usual choice. Set token_endpoint to
{base_url}/oauth2/token and scopes to ["api"]. Use bearer for an
instance that issues a standing API token instead. Access tokens are short-lived
(Docebo's expire after an hour); the platform acquires and refreshes them for
you. Credential secrets are encrypted at rest and never returned in responses.
Configuration
SOURCE FIELD (DOCEBO)
Code example with json syntax.1
Fields
| Field | Required | Description |
|---|---|---|
type | Yes | docebo. |
base_url | Yes | Base URL of the Docebo instance, for example https://example.docebosaas.com. The Learn API paths are appended automatically and must not be included. |
auth | Yes | Authentication for the instance. See Authentication. |
published_only | No | Restricts ingestion to published courses, skipping any course Docebo reports as unpublished. Defaults to true. |
include_languages | No | Docebo language codes to ingest, for example english or japanese, matched case-insensitively. A catalog commonly carries the same course once per translation, so this selects which translations are ingested. When omitted, every language is ingested. |
exclude_languages | No | Docebo language codes whose courses are excluded, even when they also match include_languages. When omitted, nothing is excluded. |
include_categories | No | Docebo category names to ingest, matched case-insensitively. Use this when the catalog mixes public training with internal or partner-only branches. A course with no category is skipped whenever this is set, so an uncategorized course is never silently treated as public. When omitted, every category is ingested. |
exclude_categories | No | Docebo category names whose courses are excluded, even when they also match include_categories. When omitted, nothing is excluded. |
How records are fetched
Each run pages through /learn/v1/courses, then reads the full record for each
selected course from /learn/v1/courses/{id}. The course document contains, in
order: the course name as a heading, the short description and description
(embedded as the HTML fragments Docebo returns), the Course contents outline,
Skills, Instructors, and any course custom fields the course filled in.
The outline is built from the course's training-material folders, listing each material's title, type, and description. A course with no training materials — an instructor-led classroom course, for example — gets no outline section.
Source metadata
Each record carries source metadata that the connector resolves at fetch time.
system_metadata:
| Key | Description |
|---|---|
title | The course name. |
url | The learner-facing course page, {base_url}/learn/courses/{id}/{slug}. |
code | The course code. |
uid_course | Docebo's unique course identifier. |
updated_time | The course's modified time, from Docebo's date_last_updated. Only the course listing reports this field, so it is absent on a record fetched by id, such as one reprocessed from a dead letter. |
user_metadata:
| Key | Description |
|---|---|
course_id | The numeric course id. |
category | The course's category name. |
course_type | The Docebo course type, for example elearning or classroom. |
language, language_label | The course's language code and display name. |
credits | The course's credit value. |
duration_seconds | The course's duration. |
is_published | Whether Docebo reports the course as published. |
skills | Comma-separated skill names associated with the course. |
training_material_tags | Comma-separated distinct tags across the course's training materials. |
The connector marks every record org-wide readable and applies no access policy
of its own. Docebo enrollment is a learner-facing concept rather than a document
grant, so it is not translated into record ACLs; narrow what is ingested with
published_only and the include/exclude filters instead.
Incremental sync
The Docebo course listing exposes no server-side modified-since bound and no
sort control, so every run re-enumerates the whole catalog and applies the
change window client-side against each course's date_last_updated. Records
therefore do not arrive in modified-time order, and per-record deduplication
absorbs the courses that are re-listed but unchanged.
Docebo's timestamps carry no timezone, so both ends of the change window are widened by the widest possible timezone offset before they are applied. This is what causes the re-listing described above.
A course whose date_last_updated is missing or unparseable is ingested on every
run rather than skipped, since without a timestamp its change state is
unknowable.
A course's date_last_updated reflects edits to the course record. If your
instance does not update it when a training material inside the course changes,
schedule a periodic full refresh so curriculum edits are picked up.