Introduction
At Docebo, we believe integrating your learning platform with other third party systems is key to the success of your learning programs for increased business performance. The documents that you find in the API & Developer Info section of Docebo's Knowledge Base are intended to provide you with all of the information you may need to get started with Docebo APIs. This article provides information on API calls that have been deprecated or have had features changed or removed since January 2023. As processes around APIs are added or modified, Docebo will update this documentation to reflect the most current information.
Please note:
This article does not include API calls that have been introduced or released.
Future deprecations and changes
November 2026 (SB) / January 2027 (GA)
Ecommerce pricing is moving to its own API
Heads up on some upcoming changes to a set of Docebo API endpoints scheduled for:
November 2026 (Sandboxes)
January 2027 (General availability)
We are consolidating course, learning plan, and subscription plan pricing (plus currency info) into the dedicated Ecommerce API. It is a cleaner home for pricing data and it's what makes multi-currency pricing possible, but it does mean a few payloads and responses you may be relying on today are changing shape.
Tip:
Every removed field below has a clear replacement, and most of them are a single new endpoint call away. We have listed the specific endpoints, what is changing on each one, and exactly what to use instead.
Platform loading (learner)
GET /manage/v1/site/bootstrap
The response drops:
data.settings.currency_settings.currency.currency_symbol
The response adds:
data.ecommerce_settings.currency_configuration(plus theclient_configurationversion of it)
Use instead:
Retrieve domain currency and the currency symbol from:
GET
/ecommerce/v1/currencies
Course (admin)
GET /course/v1/courses
priceis no longer avalid sort_attrThe response drops:
items[x].priceitems[x].prices
Use instead:
Pull course prices from:
GET
/ecommerce/v1/admin/prices/courses
POST /course/v1/courses/{id}/duplicate
Price and affiliate price are no longer cloned.
The duplicated course comes out free, with no prices and no content partner assignment.
Use instead:
Set the on-sale status and price on the new course afterward with:
PUT
/ecommerce/v1/admin/prices/courses/{id}
GET /course/v1/courses/{id}
The response drops:
data.ecommerce_options
Use instead:
Get the course's prices from:
GET
/ecommerce/v1/admin/prices/courses/{id}
POST /learn/v1/courses
The payload no longer accepts:
sellingpriceprices
Use instead:
Set the on-sale status and price after creating the course with:
PUT
/ecommerce/v1/admin/prices/courses/{id}
PUT /course/v1/courses/{id}
The payload drops:
ecommerce_options
Use instead:
Set the on-sale status and price with:
PUT
/ecommerce/v1/admin/prices/courses/{id}
POST /learn/v1/courses/batch
The payload drops:
course_for_salecourse_priceaffiliate_pricecontent_partner_codecontent_partner_fieldsfield_XX
Use instead:
Set the on-sale status and price for each course after creation with:
PUT
/ecommerce/v1/admin/prices/courses/{id}
Course (learner)
GET /learn/v1/courses
The response adds:
currency_prices
The response drops:
priceaffiliate_price.
Use instead:
Prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
GET /learn/v1/courses/{course_id}
The response adds:
currency_prices
The response drops:
pricepricesaffiliate_priceenter_status.priceenter_status.subscription.price
Use instead:
Prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
GET /learn/v1/courses/{course_id}/by_category
The response adds:
currency_prices
The response drops:
pricepricesaffiliate_price
Use instead:
Prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan (admin)
GET /learningplan/v1/learningplans
The response drops:
items[X].priceitems[X].prices
Use instead:
Pull learning plan prices from:
GET
/ecommerce/v1/admin/prices/learning-plans
POST /learningplan/v1/learningplans
The payload drops:
ecommerce_options
Use instead:
Set the on-sale status and price after creation with:
PUT
/ecommerce/v1/admin/prices/learning-plans/{id}
GET /learningplan/v1/learningplans/{learning_plan_id}
The response drops:
data.ecommerce
Use instead:
Get learning plan prices from:
GET
/ecommerce/v1/admin/prices/learning-plans/{id}
PUT /learningplan/v1/learningplans/{learning_plan_id}
The payload drops:
ecommerce_options
Use instead:
Set the on-sale status and price with:
PUT
/ecommerce/v1/admin/prices/learning-plans/{id}
Learning plan (learner)
GET /learn/v1/lp/{lp_id}
The response adds:
currency_pricescourses[x].currency_prices
The response drops:
pricepricesenter_status.pricesubscription.pricecourses[x].pricecourses[x].prizecourses[x].ecommercecourses[x].affiliate_price
Use instead:
Prices now live in:
currency_prices:[{currency_code, price}]
Catalog (admin)
GET /catalogmanagement/v1/catalogs/{id}/courses
Values no longer valid in
sort_attr:pricetraining_credits
Removed query parameters:
price_min/price_max
The response drops:
items[x].ecommerce
Use instead:
Price-based sorting and filtering on this endpoint is retired; no replacement endpoint needed, just drop those parameters.
GET /catalogmanagement/v1/catalogs/{id}/learningplans
Values no longer valid in
sort_attr:pricetraining_credits
Removed query parameters:
price_min/price_max
The response drops:
items[x].ecommerce
Use instead:
Price-based sorting and filtering on this endpoint is retired; no replacement endpoint needed, just drop those parameters.
Catalog (learner)
GET /learn/v1/catalog_content/public
The response adds:
items[x].data.sub_items[x].currency_prices
The response drops:
item_priceaffiliate_pricepricesat that same level
Use instead:
Course prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan prices in:
[{currency_code, price}]
GET /learn/v1/catalog_content/public/{catalog_id}
The response adds:
items[x].currency_prices
The response drops:
item_priceaffiliate_priceprices
Use instead:
Course prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan prices in:
[{currency_code, price}]
GET /learn/v1/catalog_content/public/general
The response adds:
items[x].currency_prices
The response drops:
item_priceaffiliate_priceprices
Use instead:
Course prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan prices in:
[{currency_code, price}]
GET /learn/v1/catalog_content/public/preview
The response adds:
items[x].currency_prices
The response drops:
item_priceaffiliate_priceprices
Use instead:
Course prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan prices in:
[{currency_code, price}]
GET /learn/v1/catalog_content/internal
The response adds:
items[x].currency_prices
The response drops:
item_priceaffiliate_priceprices
Use instead:
Course prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan prices in:
[{currency_code, price}]
GET /learn/v1/catalog_content/internal/{catalog_id}
The response adds:
items[x].currency_prices
The response drops:
item_priceaffiliate_priceprices
Use instead:
Course prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan prices in:
[{currency_code, price}]
GET /learn/v1/catalog_content/internal/general
The response adds:
items[x].currency_prices
The response drops:
item_priceaffiliate_priceprices
Use instead:
Course prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan prices in:
[{currency_code, price}]
GET /learn/v1/catalog_content/internal/preview
The response adds:
items[x].currency_prices
The response drops:
item_priceaffiliate_priceprices
Use instead:
Course prices now live in:
currency_prices:[{currency_code, price, affiliate_price}]
Learning plan prices in:
[{currency_code, price}]
Subscription plan (admin)
POST /learn/v1/sub_plan
The payload drops:
price
The payload adds:
prices
The response adds:
data.prices
Use instead:
The prices payload/response now matches:
PUT
/ecommerce/v1/admin/prices/subscription-plans/{id}
PUT /learn/v1/sub_plan/{plan_id}
The payload drops:
price
The payload adds:
prices
The response adds:
data.prices
Use instead:
The prices payload/response now matches:
PUT
/ecommerce/v1/admin/prices/subscription-plans/{id}
GET /learn/v1/sub_plan
The response drops:
items[X].plan_price
The response adds:
items[X].prices
Use instead:
The prices response now matches:
PUT
/ecommerce/v1/admin/prices/subscription-plans/{id}
GET /learn/v1/sub_plan/{plan_id}
The response drops:
pricesubscription_records[X].price
The response adds:
pricessubscription_records[X].renewal_price
Use instead:
The prices response now matches:
PUT
/ecommerce/v1/admin/prices/subscription-plans/{id}
POST /learn/v1/sub_plan/batch
The payload drops:
items[x].price
The payload adds:
items[x].prices
Use instead:
The prices response now matches:
PUT
/ecommerce/v1/admin/prices/subscription-plans/{id}
Subscription Record (admin)
POST /learn/v1/sub_record
The payload changes:
priceis now an object withprice.currencyandprice.value(instead of a single numeric value)
PUT /learn/v1/sub_record/{id_record}
The payload changes:
priceis now an object withprice.currencyandprice.value
GET /learn/v1/sub_record
The response changes:
data.items[n].priceis now an object withdata.items[n].price.currencyanddata.items[n].price.value
GET /learn/v1/sub_record/{id_record}
The response changes:
data.subscription_record.priceis now an object withdata.subscription_record.price.currencyanddata.subscription_record.price.value
List of deprecated and changed API calls
2026
August 2026
Changed
GET /report/v1/report/{report_id}/data
The user.idUser field in the response is now returned as an integer instead of a string. This is a side effect of the platform's PHP 8 upgrade, which changed how response values are serialized. The user.userid field in the same response is unaffected and continues to be returned as a string.
July 2026
Removed
GET /manage/v1/trails
Replaced by:
POST
audittrail/v1/audittrailGET
audittrail/v1/audittrail/{queryExecutionId}
GET /manage/v1/opengraph
Removed for security reasons. This endpoint has no replacement.
Changed
GET /manage/v1/user/{user_id}
Language field now returns human-readable value instead of internal code
PUT /learningplan/v1/learningplans/{learning_plan_id}
lang_code becomes mandatory; lang_behaviour resets to default if omitted
April 2026
Removed
GET
ecommerce/v1/walletsGET
ecommerce/v1/wallets/{user_id}PUT
ecommerce/v1/wallets/{user_id}GET
ecommerce/v1/wallets/{user_id}/transactionsPOST
ecommerce/v1/wallets/{user_id}/purchases
Removed/replaced by new admin/personal-wallet endpoints (training credit API migration)
Changed
GET
/learn/v1/catalog/filtersGET
/learn/v1/catalog/advanced_filtersGET
/learn/v1/catalog/internal_filters
user_is_not_enrolled filter removed, replaced by enrolment_status parameter
PUT /course/v1/courses/{id}
Change for multi-language course metadata (course_information_translations)
March 2026
Removed
GET
/learn/v1/courses/{course_id}/sessions/enrollments
February 2026
Removed
GET
ecommerce/v1/walletsreplaced by GETecommerce/v1/admin/personal-walletsGET
ecommerce/v1/wallets/{user_id}replaced by GETecommerce/v1/admin/personal-wallets/{user_id}GET
ecommerce/v1/wallets/{user_id}/transactionsreplaced by GETecommerce/v1/admin/personal-wallets/{user_id}/transactionsPUT
ecommerce/v1/wallets/{user_id}replaced by PUTecommerce/v1/admin/personal-wallets/{user_id}POST
ecommerce/v1/wallets/{user_id}/purchasesreplaced by POSTecommerce/v1/training-credits/purchases
January 2026
Removed
The following no-longer-used API endpoints relating to webinars have been removed:
GET
/learn/v1/courses/session/{id_session}/date/{yyyy-mm-dd}GET
/learn/v1/courses/{course_id}/webinar/sessions/{session_id}PUT
/learn/v1/webinar/attendance/batchGET
/learn/v1/webconference/getWebconferenceDataPOST
/learn/v1/webinars/session/batchGET
/learn/v1/webinar/{id_session}/{date_day}/recording_statusGET
/learn/v1/webinars/importer_fieldsPOST
/learn/v1/webinar/{id_session}/{date_day}/recordingDELETE
/learn/v1/webinar/{id_session}/{date_day}/recordingGET
/course/v1/courses/webinarmigration/mapping/{course_id}
Changed
In the following endpoint, the email attribute has been removed from the objects in the data.items array of the response payload.
GET
/share/v1/channels/{id}/users
The migrated_webinar_session_id response parameter has been removed from the following APIs and the related webhooks:
GET
/course/v1/sessions/{session_id}GET
/course/v1/courses/{course_id}/sessionsGET
/learn/v1/courses/{id}/sessionsGET
/learn/v1/courses/{id}
2025
November 2025
Removed
PUT
/learn/v1/sub_record/{record_id}/renew
October 2025
Removed
GET
/ecommerce/v1/ecommerce/settingsPOST
/ecommerce/v1/ecommerce/settingsPUT
/ecommerce/v1/ecommerce/settings/code
September 2025
Removed
GET
/loki/share/v1/assets/{asset_id}GET
/loki/share/v1/playlists/{playlist_id}/searchPUT
/ecommerce/v1/transaction/batch
July 2025
Removed
With the transition to the new notification service, the following endpoints have been removed:
GET
/notifications/v1/notification/notificationsGET
/notifications/v1/notification/listPATCH
/notifications/v1/notification/readGET
/notifications/v1/notifications_logPUT
/manage/v1/enrollment_rules/{enrollment_rule_id}/notificationsDELETE
/manage/v1/enrollment_rules/{enrollment_rule_id}/notificationsGET
/manage/v1/enrollment_rules/{enrollment_rule_id}/notifications
Changed
For the following endpoints, the notification_ids property has been changed to an array of strings :
GET
/manage/v1/enrollment_rules/{enrollment_rule_id}GET
/manage/v1/enrollment_rulesPOST
/learn/v1/enrollments
February 2025
Changed
GET
/manage/v1/user/{user_id}The returned Country value now returns the country ID regardless of whether the user referenced by {user ID} is in pending users, or already approved. (Previously the country name was returned for pending users, and the country ID only for confirmed users.)
The provisioned_user_fields array in the response now returns the list of provisioned fields as a key : value set, where key is the platform field name (string) and value is always true (Boolean).
2024
December 2024
Removed
POST
/learn/v1/lp/compact_listGET
/learn/v1/course/compact_listPUT
/manage/v1/cookie_policy/policies/{id}GET
/manage/v1/cookie_policy/policies/{id}PUT
/manage/v1/cookie_policy/{id}GET
/manage/v1/cookie_policy/{id}
Changed
The values for the following endpoints that can be passed to set a Yes/No user additional field are now:
For Yes:
1“1“true“true“"yes""on"
For No:
2“2“false“false“"no""off"
For None:
0“0”null“”All other values not specified for
YESorNO
This implies some breaking changes, for example if with POST /manage/v1/user/batch you previously relied upon 0, "0", null, or “” (empty string) to set NO.
Changed endpoints:
POST
/manage/v1/user/POST
/manage/v1/user/batchPUT
/manage/v1/user/{id}PUT
/manage/v1/user/mass_edit
September 2024
Changed
For the values of the following endpoints, it is now possible to set a custom enrollment date for learners in learning plans thanks to the optional parameter enrolment_at and to propagate the date to the courses composing the learning plans using the propagate_at parameter. The new parameters are tracked by the Audit trail (opens in a new tab). Affected endpoints:
PATCH
/learningplan/v1/learningplans/{learning_plan_id}/enrollments/{user_id}POST
/learningplan/v1/learningplans/{learning_plan_id}/enrollments/bulkPATCH
/learningplan/v1/learningplans/{learning_plan_id}/enrollments/bulk
For the following endpoints, the endpoint now returns a 400 error in the following cases:
When normal users attempt to enroll other users (self-enrollment only is allowed).
When managers attempt to enroll users who are different from themselves, users they do not manage, or users with invalid IDs.
Affected endpoints:
GET
/learn/v1/catalog_content/internal/{catalog_id}GET
/learn/v1/catalog_content/internalGET
/learn/v1/catalog_content/internal/general
For the following endpoint, the user_is_not_enrolled parameter must have a boolean value and no longer accepts arrays:
POST
/learn/v1/enrollments
August 2024
Changes
For the following endpoints, the last_edit_by field has been removed from the response, for security reasons:
GET
/pages/v1/pagesGET
/pages/v1/pages/{id}
For the following endpoints, the response body now includes the UUID parameter:
POST
/manage/v1/user/batchPUT
/manage/v1/user/{id}
July 2024
Removed
GET /ecommerce/v1/transaction/{id}/cancel
June 2024
Removed
PUT /learn/v1/courses/{id}
April 2024
Removed
GET /learn/v1/catalog
February 2024
Changed
GET /manage/v1/user/{user_id}
The response no longer includes a
countryparameter among the user fields. The country can still be obtained by setting it up as an additional field.
GET /manage/v1/user/search
The country names set as user additional fields returned are now localized according to the language of the user using the API call.
GET /manage/v1/user
The country names set as user additional fields returned are now localized according to the language of the user using the API call.
January 2024
Removed
GET
/manage/v1/group/{id_group}PUT
/manage/v1/group/{id}DELETE
/manage/v1/group/{id_group}/members/{id_user}GET
/manage/v1/group/{id_group}/membersGET
/manage/v1/groupGET
/manage/v1/group/importer_fieldsDELETE
/manage/v1/group/{id}POST
/manage/v1/groupPOST
/manage/v1/group/members/batchDELETE
/manage/v1/group/members/batchPOST
/manage/v1/group/batchPOST
/manage/v1/group/{id_group}/membersGET
/manage/v1/group/GET
/manage/v1/group/{id_group}/members/all
POST
/audiences/v1/audience/recalculator/batch
Removed for security reasons
Changed
GET /ecommerce/v1/transaction
The date_from and date_to input parameters now only accept dates with the following format: UTC YYYY-MM-DD HH:MM:SS
GET /manage/v1/user/{user_id}
The response now includes a new last_update parameter, indicating the date and time when this user was last modified.
GET /manage/v1/multidomain
Access restricted to Superadmin usage only, returned payload has no visibility over the root branch, the returned domain_url value has the trailing lms/ removed
For the following endpoints, the catalogsIds and the mobile parameters are no longer available:
GET
/learn/v1/catalog_content/internalGET
/learn/v1/catalog_content/internal/previewGET
/learn/v1/catalog_content/public/previewGET
/learn/v1/catalog_content/publicGET
/learn/v1/catalog_content/internal/calendarGET
/learn/v1/catalog_content/public/calendar
2023
December 2023
Changed
GET /learn/v1/courses/{id}/by_category
The
disable_catalog_filterparameter is no longer available; the returned courses will always be subject to the caller’s visibility. When the ID on an unpublished course is passed, the call will return a403error instead of a success message
POST /share/v1/admin/channels/channel_id/duplicate
A new boolean parameter called
copy_visibilityis available to manage the porting of the visibility settings of the source channel for the duplicated channel. If thecopy_visibilityparameter is set tofalse, the visibility will be set to “All groups and branches” by default. In addition, the duplicated channel will have the same content and the same experts as the source channel only if theassign_same_contentand theassign_same_expertsparameters are set totrue.
November 2023
Changed
GET /learn/v1/instructor/getInstructorData
The values passed for the parameters
course_id,user_idandsession_idare now strictly validated, accepting only integer values. The status1003error message (Cannot find course with the passed ID) is removed
GET /manage/v1/managers/candidates
It is no longer possible to use this API call unless the Automatic Notification for Team Members and the Auto Suggestion in Automatic Notification options are selected in the platform’s advanced settings for teams and managers (opens in a new tab). This is a security fix, implemented to ensure greater confidentiality of data.
October 2023
Removed
/api/webapp/connect/api/webapp/forgot_password/api/webapp/language/api/webapp/logout/api/webapp/get_app_version/api/webapp/check_version/api/webapp/google_auth/api/webapp/data/api/webapp/get_user_info/api/webapp/course/api/webapp/get_courses_by_lp_id/api/webapp/can_enter_course/api/webapp/get_learning_object/api/webapp/play/api/webapp/skip_walktrough/api/webapp/asset_tags/api/webapp/asset_channels/api/webapp/get_upload/api/webapp/new_upload/api/webapp/update_upload/api/webapp/asset_thumb/api/webapp/delete_asset/api/webapp/get_assets/api/webapp/get_video_urls/api/webapp/track_user_lo_status/api/webapp/lo_download_status/api/webapp/materials_size_data/api/webapp/getOfflineMetadata/api/webapp/trackMaterial/api/webapp/sco_track_sync/api/webapp/get_lo_by_course_id/api/webapp/new_password
Changed
The catalog_ids parameter is now accepted as an alternative to the catalogIds parameter for the following endpoints:
GET
/learn/v1/catalog_content/internalGET
/learn/v1/catalog_content/internal/previewGET
/learn/v1/catalog_content/public/previewGET
/learn/v1/catalog_content/publicGET
/learn/v1/catalog_content/internal/calendarGET
/learn/v1/catalog_content/public/calendar
September 2023
Changed
GET learn/v1/courses/{course_id}
When used for an ILT session including at least one onsite event, the API now returns the value null instead of undefined for the
webinar_toolattribute
GET /learn/v1/courses/{course_id}/by_category
The
statusparameter is no longer available and the API response only includes the courses in Published status
August 2023
Changed
GET /learn/v1/external_training
The
filtersparameter has been removed for security reasons
GET /learn/v1/forum/getForumData
The
current_session_idparameter has been removed
July 2023
Changed
POST /skill/v1/skillgroup
The
typeparameter has been deprecated
PUT /learn/v1/courses/switch_sessions
The endpoint now returns a 400 error when trying to switch a session to a fully-booked session of a course with a disabled waiting list (opens in a new tab).
June 2023
Removed
PUT
/share/v1/gamification/assigned_badge/{uuid}/social_imagePOST
/learn/v1/lo/tincanReplaced by POST
/learn/v1/lo/batch
April 2023
Removed
POST
/ecommerce/v1/cart/checkout
Changed
POST /course/v1/instructors/add
This endpoint now offers the possibility to replace the instructors already assigned thanks to the new
replaceparameter. The default value for the new parameter isfalse.
GET /learn/v1/lp/lp_id
The response now includes the
codeparameter indicating the codes of the courses included in the learning plan.
March 2023
Removed
GET
/course/v1/courses/importer_fields
February 2023
Changed
GET /learn/v1/instructor/getInstructorData
The value of the
useridproperty is now returned without the leading slash. This means that “/username” is returned as “username”.
January 2023
Changed
GET /learningplan/v1/learningplans/enrollments
If the user's enrollment status is Suspended in all of the courses of the learning plan they enrolled in, the returned enrollment status will be
Not Started,In ProgressorCompleted(depending on the enrollment status) instead ofnull.
GET /learn/v1/enrollments
If the user's enrollment status is Suspended in all of the courses of the learning plan they enrolled in, the returned enrollment status will be
Not Started,In ProgressorCompleted(depending on the enrollment status) instead ofnull.
GET /report/v1/privacy_policy/users/{id}/version/{version_id}
The returned information from the API call, when called with an invalid user or version ID, now returns a
404 Not Foundresponse along with an error message stating which ID is invalid.