Iblai api catalog
Agent skills + a chat MCP server to operate the ibl.ai platform via its REST API. Install: npx skills add iblai/api
npx -y skills add iblai/api --skill iblai-api-catalogAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Manage an ibl.ai organization's learning catalog via the platform API — courses, programs, pathways, resources, skills, roles, course/program metadata, plus enrollment, eligibility checks, catalog search, and course reviews. Org-wide content and enrollment operations. Use when wiring up the catalog, enrolling users, checking eligibility, or curating skills/roles/pathways.
SKILL.md
20.0 KB, as published. Nobody here has run it
iblai-api-catalog
Manage an organization's learning catalog from the API: courses, programs, pathways, and resources; the skills and roles taxonomy (including each user's desired/reported skills and roles); course and program metadata; plus enrollment (course / program / pathway, admin and self), eligibility checks, catalog search, and course reviews. Use when populating the catalog, enrolling users, checking who can take what, or curating the skills/roles graph.
Auth & conventions
- Base URL:
https://api.iblai.app/dm— these are Data Manager (DM) endpoints, so the/dmprefix is required; the/api/catalog/...paths below are appended to it (e.g.https://api.iblai.app/dm/api/catalog/courses/). - Header:
Authorization: Api-Token $IBLAI_API_KEYon every request. - Path vars:
{org}=$IBLAI_ORG(a.k.a.org/platform_key/platform_orgon the wire),{username}=$IBLAI_USERNAME. Org/user are passed as query params or body fields, not baked into the path. - DELETE / destructive / outward-facing calls say "Confirm with the user first."
course_idvalues must be URL-encoded in query strings.- Not connected yet? Run
/iblai-api-loginfirst to populateIBLAI_ORG,IBLAI_USERNAME, andIBLAI_API_KEY.
Reads
Courses
- GET
/api/catalog/courses/— retrieve courses; filter bycourse_id,slug(case-insensitive),org(query params). Returns[{course_id, name, slug, org}].
Programs
- GET
/api/catalog/programs/— retrieve programs; filter byprogram_id,course_id,name,slug,enabled,org(query params). Returns[{program_id, org, slug, name, program_type, platform_key, enabled, course_list}].
Pathways
- GET
/api/catalog/pathways/— retrieve pathway(s); filter (query params) bypathway_id,pathway_uuid,user_id/username,platform_key,item_id,name,slug(case-insensitive),visible. Returns a (non-paginated) list of pathways, each with apath[]of items.
Resources
- GET
/api/catalog/resources/— retrieve resources; filter (query params) byid,user_id/username,platform_key/key,org/platform_org,resource_type,name,query(matchesnamevia icontains),item_id. Returns a non-paginated list. - GET
/api/catalog/resources/search/— paginated resource search; same filters,page(default1),page_size(default50). Results newest-first. Prefer this for large result sets.
Metadata
Course
- GET
/api/catalog/metadata/course/— read a course's metadata bycourse_id(query param; the response keys are dynamic, e.g.{subject, tags, level, topics, promotion, slug, ...}).GET /api/catalog/metadata/course/{field}/reads one metadata field. - GET
/api/catalog/metadata/course-public/— read a course's public metadata bycourse_id(no auth/permission required; ignores course visibility).course-public/{field}/reads one field. Read-only.
Program
- GET
/api/catalog/metadata/program/— read a program's metadata;program_idrequired, optionalorg(query params).program/{field}/reads one field. - GET
/api/catalog/metadata/program-public/— read a program's public metadata (program_idrequired, optionalorg; no auth required).program-public/{field}/reads one field. Read-only.
Choices
- GET
/api/catalog/metadata/choices/— query allowed metadata choices; requiresfield_keyorscope(query params), optionalorg. Returns the choice dict (404if none).
Skills
- GET
/api/catalog/skills/— retrieve skills (paginated); filter byid,name,name__iexact,slug,platform_key;sort(defaultid). - GET
/api/catalog/skills/desired/— a user's desired skills byuser_id/username(400if the user has none). - GET
/api/catalog/skills/reported/— a user's reported skills byuser_id/username(200with an empty record{"user_id":null,"username":null,"skills":[],"data":null}when there are none).
Roles
- GET
/api/catalog/roles/— retrieve roles (paginated); filter byid,name,name__iexact,slug,platform_key;sort(defaultid). Each role embeds itsskills[]. - GET
/api/catalog/roles/desired/— a user's desired roles byuser_id/username. - GET
/api/catalog/roles/reported/— a user's reported roles byuser_id/username.
Eligibility
- GET
/api/catalog/eligibility/courses/— list courses a user is eligible for; paramsuser_id/username,org,query. - GET
/api/catalog/eligibility/courses/check/— check eligibility for one course;course_idrequired plususer_idorusername(course_idURL-encoded), plusorg,local_only(skip the remote edX enroll-status call). Always returns{is_eligible}; unlesslocal_onlyis set, the response is merged with the edX enroll-status fields (e.g.is_enrolled, etc.).
Enrollment
Courses
- GET
/api/catalog/enrollment/courses/search/— paginated enrollment search; query params (at least one ofuser_id,username,email,course_id,slug,org,platform_keyrequired) pluscourse_name(substring),sort(default-id),include_default_platform,include_archived_courses(default false),page,page_size. Returns{count, next_page, previous_page, results[]}of active enrollments.
Programs
- GET
/api/catalog/enrollment/programs/— query program enrollments; a user identifier (user_id/username) is required (the call400s on an unresolvable user), and you may also filter byprogram_id/slug,org/platform_key,program_type(standard|platform|custom),include_metadata(defaulttrue),include_default_platform. - GET
/api/catalog/enrollment/programs/search/— paginated program-enrollment search; same params as the GET above plussort,page,page_size. Active enrollments only.
Pathways
- GET
/api/catalog/enrollment/pathways/— query pathway enrollments; a user identifier (user_id/username) is required, plus optionalpathway_id/pathway_uuid/slug,org/platform_key,include_metadata(defaulttrue),include_default_platform. - GET
/api/catalog/enrollment/pathways/search/— paginated pathway-enrollment search; user identifier required, pluspathway_id/slug,org/platform_key,sort,page,page_size,include_default_platform. Active enrollments only.
Recommendation
- GET
/api/catalog/recommendation/courses/— get the recommended "next" course relative to a current course.course_idrequired (query param), plus optionaluser_idandorg. Returns a single serialized course, ornull(with200) when there is no next course.
Reviews
Course reviews
- GET
/api/catalog/reviews/course/— paginated list of (visible) course reviews; filter (query params) bycourse_id,user_id,platform_key,platform_org/org,sort(default-id),page,page_size. Returns{count, next_page, previous_page, results[]}where each result is{user_id, username, content, rating, title, visible, created, modified, course_id, metadata}. - GET
/api/catalog/reviews/course/info/— aggregate review stats for a course;course_idrequired (query param). Returns{course_id, avg_rating, count}.
Program reviews
- GET
/api/catalog/reviews/program/— paginated list of (visible) program reviews; filter byprogram_id,user_id,platform_key,platform_org/org,sort,page,page_size. Each result includesprogram_key. - GET
/api/catalog/reviews/program/info/— aggregate review stats;program_keyrequired (query param). Returns{program_key, avg_rating, count}.
Writes
Courses
- POST
/api/catalog/courses/— create/update a course (200updated,201created):
Newly created courses are assigned to the org's platform (default platform if{ "course_id": "string (required)", "org": "string (required)", "name": "string (optional)" }orgis unknown). On update the org is only changed if you also sendoverwrite_existing_org: true. (The handler ignoresslug/dataon write.) - DELETE
/api/catalog/courses/— delete a course bycourse_id(query param). Confirm with the user first.
Programs
- POST
/api/catalog/programs/— create/update a program (200updated,201created). Identify the platform byprogram_id+ (org/platform_key) or byprogram_key.program_id,name, andcourse_listare required:{ "program_id": "string (required)", "name": "string (required)", "course_list": [{ "course_id": "course-v1:A+B+C" }], "org": "string", "platform_key": "string", "program_key": "string", "slug": "string", "enabled": "boolean (default true)", "program_type": "number (1=standard, 2=platform, 3=custom)", "data": "object" } - DELETE
/api/catalog/programs/— delete a program byprogram_id+org(query params, both required). Returns{count, type}. Confirm with the user first.
Pathways
- POST
/api/catalog/pathways/— create/update a pathway.user_id(required),name(required), andpath(required). Use (user_id/usernameorplatform_key) +pathway_idto create; do not sendpathway_uuidon create (generated). For an existing pathway, identify bypathway_uuid. Eachpath[]item is keyed byitem_type:resource(resource fields below; created on the fly when noid),course(course_id),program(program_key), orpathway(pathway_id).{ "user_id": "number (required)", "name": "string (required)", "username": "string", "platform_key": "string", "pathway_id": "string", "pathway_uuid": "uuid (update only)", "slug": "string", "visible": "boolean (default true)", "path": [ { "item_type": "resource", "id": "number (omit to create)", "resource_type": "string", "url": "string", "name": "string", "description": "string", "data": "object" }, { "item_type": "course", "course_id": "course-v1:A+B+C" }, { "item_type": "program", "program_key": "program-v1:org+id" } ], "data": "object" }
Resources
- POST
/api/catalog/resources/— create/update a resource (omitidto create). Accepts JSON or multipart (forimage):{ "id": "number (update only)", "username": "string", "user_id": "number", "platform_key": "string", "platform_org": "string", "name": "string", "url": "string", "resource_type": "string", "description": "string", "skills": ["string"], "image": "file (multipart)", "data": "object" } - DELETE
/api/catalog/resources/— delete a resource; requiresidplususer_idorplatform_key(query params). Returns{count, type}. Confirm with the user first.
Metadata
Course
- POST
/api/catalog/metadata/course/— create/update course metadata.course_idandmetadatarequired. Withupdate: true(default) the supplied keys are merged;update: falseoverwrites. Special keys insidemetadata:slug,skills(list of existing skill names). Field-path POSTs (course/{field}/) are not supported (404).{ "course_id": "string", "update": "boolean (default true)", "metadata": { "subject": "string", "tags": ["string"], "level": "string", "topics": ["string"], "promotion": "string|null", "slug": "string", "skills": ["string"] } } - POST
/api/catalog/metadata/course-search/— return course info (to_json()) for courses matching metadata filters in the body, e.g.{ "data__contains": {...}, "slug": "string", "course_id": "string" }. Body must be non-empty; invalid filter keys return400.
Program
- POST
/api/catalog/metadata/program/— create/update program metadata;program_idrequired, optionalorg, plusmetadataandupdate(default true) in the body. Field-path POSTs not supported (404).
Skills
- POST
/api/catalog/skills/— create/update a skill (omitidto create;platform_key: nullfor global):{ "id": "number (update only)", "name": "string", "slug": "string", "platform_key": "string|null", "data": "object" } - POST
/api/catalog/skills/public/— create a skill, open to any user (config-gated; names lowercased/trimmed):{ "name": "string", "slug": "string", "data": "object" }. - POST
/api/catalog/skills/desired/— set a user's desired skills (refer to skills byid):{ "user_id": "number", "username": "string", "skills": [{ "id": "number" }], "data": "object" } - POST
/api/catalog/skills/reported/— set a user's reported skills (same shape as desired).
Roles
- POST
/api/catalog/roles/— create/update a role (omitidto create):{ "id": "number (update only)", "name": "string", "slug": "string", "platform_key": "string", "data": "object" } - POST
/api/catalog/roles/public/— create a role, open to any user (config-gated; names lowercased/trimmed):{ "name": "string", "slug": "string", "data": "object" }. - POST
/api/catalog/roles/desired/— set a user's desired roles:{ "user_id": "number", "roles": ["string"|{ "id": "number" }], "data": "object" }. - POST
/api/catalog/roles/reported/— set a user's reported roles (same shape as desired).
Enrollment
Programs
- POST
/api/catalog/enrollment/programs/— create/update an enrollment. Requires a user (user_id/username) and a program (program_keyorprogram_id+org/platform_key):{ "user_id": "number", "username": "string", "program_id": "string", "program_key": "string", "org": "string", "platform_key": "string", "started": "datetime", "expired": "datetime", "active": "boolean (default true)" } - DELETE
/api/catalog/enrollment/programs/— deactivate an enrollment (query params: useruser_id/username+ programprogram_id/program_key+org/platform_key, optionalignore_expirationdefaultfalse). Confirm with the user first. - POST
/api/catalog/enrollment/programs/self/— self-enrollment (the program must be in a platform the target user belongs to;403otherwise). Same body as the admin POST, includinguser_id/username:{ "user_id": "number", "username": "string", "program_id": "string", "program_key": "string", "org": "string", "platform_key": "string", "started": "datetime", "expired": "datetime", "active": "boolean (default true)" } - DELETE
/api/catalog/enrollment/programs/self/— self-unenroll (same identifiers as the admin DELETE; membership-checked, optionalignore_expirationdefaultfalse). Confirm with the user first.
Pathways
- POST
/api/catalog/enrollment/pathways/— create a pathway enrollment; requires a user (user_id/username) and a pathway (pathway_uuid, orpathway_id+org/platform_key):{ "username": "string", "user_id": "number", "pathway_id": "string", "pathway_uuid": "uuid", "org": "string", "platform_key": "string", "active": "boolean (default true)" } - DELETE
/api/catalog/enrollment/pathways/— deactivate a pathway enrollment (same identifiers, query params). Confirm with the user first. - POST
/api/catalog/enrollment/pathways/self/— self-enrollment (membership-checked;403if the user is not in the pathway's platform). Same body as the admin POST, includinguser_id/username. - DELETE
/api/catalog/enrollment/pathways/self/— self-unenroll (same identifiers, membership-checked). Confirm with the user first.
Search
- POST
/api/catalog/search/programs/— full-text program search acrossprogram_id,name,slug, andmetadata; returns catalog program objects withmetadata:{ "query": "string", "org": "string (optional)" }
Reviews
Course reviews
- POST
/api/catalog/reviews/course/update/— create/update a course review (201created,200updated).course_idandusernamerequired (oruser_id):{ "course_id": "string", "username": "string", "user_id": "number", "rating": "number", "title": "string", "content": "string", "visible": "boolean (default true)", "metadata": "object" } - DELETE
/api/catalog/reviews/course/update/— delete a user's course review;course_id+username/user_idrequired (query params). Confirm with the user first.
Program reviews
- POST
/api/catalog/reviews/program/update/— create/update a program review.program_keyandusernamerequired (oruser_id):{ "program_key": "program-v1:org+id", "username": "string", "user_id": "number", "rating": "number", "title": "string", "content": "string", "visible": "boolean (default true)", "metadata": "object" } - DELETE
/api/catalog/reviews/program/update/— delete a user's program review;program_key+username/user_idrequired (query params). Confirm with the user first.
Example
Check whether a user is eligible for a specific course (note the URL-encoded course_id):
curl -G \
"https://api.iblai.app/dm/api/catalog/eligibility/courses/check/" \
-H "Authorization: Api-Token $IBLAI_API_KEY" \
--data-urlencode "user_id=36" \
--data-urlencode "org=$IBLAI_ORG" \
--data-urlencode "course_id=course-v1:IBLTEST+IBL000+RUN"
Notes
- All endpoints are DM endpoints served under
https://api.iblai.app/dm(/dm+/api/catalog/...). Omitting the/dmprefix will not resolve. - Course id format is the opaque-keys form
course-v1:ORG+NUMBER+RUN(e.g.course-v1:IBLTEST+IBL000+RUN). Always URL-encode it in query strings (%3A,%2B). - Program ids are slug-like strings (e.g.
test-program-000);program_typeis a numeric code on write. Resource / skill / role ids are integers; resources also carry a UUIDitem_id; pathways carry a UUIDpathway_uuid(generated on create — never send it on a create call). - Org on the wire appears as
org,platform_key, or (resource search legacy)platform_org/key— all mean the org key. Pass it as a query param (GET) or body field (POST), not in the path. - Skills/roles by id, not name. When setting a user's desired/reported skills or roles, reference them by
{"id": …}(recommended) rather than name. Course-metadataskillsmust reference existing skill names. - Self vs admin enrollment. Both the non-self and the
…/self/enrollment endpoints take an explicituser_id/usernamein the request. The difference is permission scope:…/self/additionally checks that the target user is a member of the program/pathway's platform (returns403if not), so it is the endpoint to use for non-admin (user-token) self-service; the non-self endpoints are for admin tokens enrolling other users. - Pagination envelope is
{count, next_page, previous_page, results[]}for the search/paginated endpoints (course/program/pathway enrollment search, resource search, skills, roles, course/program review query); plainGETs likeresources/andpathways/are not paginated. public/skill and role creation endpoints are config-gated (ALLOW_PUBLIC_SKILL_CREATE/ALLOW_PUBLIC_ROLE_CREATE) and return404when disabled; created names are lowercased and trimmed.- Auto-increment utility.
GET/POST /api/catalog/increment/reads/advances per-platform auto-increment numbers (org/key, andnumber_typeonPOST). It is an internal numbering helper, not a catalog-management operation — included for completeness only. - The source repo also ships Django management commands (
convert_slugs_lower,link_item_objects,verify_course_existence); those are server-side operations, not REST endpoints, and are out of scope for this skill.