iblai-api-catalog-media
Manage an organization's catalog media resources from the API: media files
and external links (videos, images, documents, audio, other) attached to a
course, a unit, a specific resource item, or any combination of the three.
Supports listing/filtering, full CRUD, a search action, and a by-item lookup.
The item_type (which catalog level the media is associated with) is derived
automatically from which of course_id / unit_id / item_id you supply.
Use when attaching media to catalog content, browsing/searching an org's media,
or uploading media files.
Auth & conventions
- Base URL:
https://api.iblai.app/dm— these are Data Manager (DM) endpoints, so the/dmprefix is required; the/api/media/orgs/{org}/users/{user_id}/media/media-resources/...paths below are appended to it (e.g.https://api.iblai.app/dm/api/media/orgs/enterprise/users/36/media/media-resources/). - Header:
Authorization: Api-Token $IBLAI_API_KEYon every request. - Path vars:
{org}=$IBLAI_ORG(the org key — matched against the platform'sorg),{user_id}= the numeric user id (matched againstUser.id; this is not the username). Both org and user are baked into the path here (unlike most catalog endpoints, which pass them as params). - Auth classes: session, OAuth2 client-credential, and platform Api-Token.
- DELETE / destructive / outward-facing calls (delete, file upload) say "Confirm with the user first."
- Not connected yet? Run
/iblai-api-loginfirst to populateIBLAI_ORG,IBLAI_USERNAME, andIBLAI_API_KEY. (user_idis the numeric id, not the usernameIBLAI_USERNAME.)
All routes are under
/api/media/orgs/{org}/users/{user_id}/media/media-resources/.
Reads
Media resources (CRUD)
- GET
…/media-resources/— list media resources for the org's platform (paginated, newest-first). Filters (query params, mutually exclusive in this precedence):search(icontains acrosstitle,description,course_id,unit_id,item_id,file_url), elsecourse_id+unit_id, elsecourse_id, elseunit_id, elseitem_id. The id filters also pull in rows whoseitem_typespans that level (e.g. filtering bycourse_idalso returnscourse,course_unit,course_resource, andallitems). - GET
…/media-resources/{id}/— retrieve one media resource by numeric id.
Search
- GET
…/media-resources/search/— paginated search action.qrequired (icontains acrosstitle,description,course_id,unit_id,item_id,file_url). Optional result filterscourse_id,unit_id,item_id(same item_type-spanning behavior as the list endpoint, applied before theqmatch). Returns the standard paginated envelope.
By-item
- GET
…/media-resources/by_item/— fetch media for one catalog item.item_typeanditem_idboth required (missing →400).item_typevalues:course,unit,resource,course_unit,course_resource,unit_resource,all. Forcourse/unit/resource, the lookup matches the corresponding id (course_id/unit_id/item_id=item_id) or anyitem_typethat spans that level; for the combined types it matchesitem_type+item_idexactly. Returns the standard paginated envelope.
Writes
Media resources (CRUD)
- POST
…/media-resources/— create a media resource. Admin only. Accepts JSON or multipart/form-data (for thefileupload). At least one ofcourse_id/unit_id/item_idis required;item_typeis computed server-side and is read-only. Confirm with the user first (file upload / write):
Provide either{ "title": "string (required)", "media_type": "video|image|document|audio|other (required)", "description": "string", "file": "binary file (multipart only)", "file_url": "https://… (external URL)", "course_id": "course-v1:ORG+NUM+RUN", "unit_id": "block-v1:ORG+NUM+RUN+type@vertical+block@…", "item_id": "string" }file(upload) orfile_url(external link). Creating a second resource with the samefile/file_urlfor the sameitem_type+item_idis rejected as a duplicate (400).created_byis set to the path{user_id};platformis set from{org}. - PUT
…/media-resources/{id}/— full update. Admin only. Same body fields as create (multipart supported). Same duplicate-file/file_urlguard.item_type/platform/created_bystay read-only. Confirm with the user first. - PATCH
…/media-resources/{id}/— partial update (same rules as PUT). Confirm with the user first. - DELETE
…/media-resources/{id}/— delete a media resource by id. Confirm with the user first.
Example
List the first page of an org's media resources filtered to one course (note
the URL-encoded course_id):
curl -G \
"https://api.iblai.app/dm/api/media/orgs/$IBLAI_ORG/users/36/media/media-resources/" \
-H "Authorization: Api-Token $IBLAI_API_KEY" \
--data-urlencode "course_id=course-v1:main+NB101+2025-T1" \
--data-urlencode "page_size=10"
Search across an org's media for "lecture":
curl -G \
"https://api.iblai.app/dm/api/media/orgs/$IBLAI_ORG/users/36/media/media-resources/search/" \
-H "Authorization: Api-Token $IBLAI_API_KEY" \
--data-urlencode "q=lecture"
Notes
- item_type values (the catalog level a media resource is associated with):
course,unit,resource,course_unit,course_resource,unit_resource,all. It is never sent by the client — the server computes it from which ofcourse_id/unit_id/item_idare present (course+unit+item→all;course+unit→course_unit;course+item→course_resource;unit+item→unit_resource; a single id → that single type). It is exposed read-only in responses. - media_type values:
video,image,document,audio,other. - File upload. Send
fileasmultipart/form-data(binary), or instead give an externalfile_url. Uploading the same file/URL for the same item is rejected as a duplicate. Treat uploads as outward-facing — confirm with the user first. - Pagination envelope (custom; not the catalog
{count,next_page,…}shape). List/search/by-item return:
Page size is{ "status": { "success": true, "description": "Successfully retrieved media resources" }, "results": { "count": 1, "next": null, "previous": null, "data": [ … ] } }page_size(default10, max100); page viapage. Detail, create, and update responses return the bare serialized object instead. - Resource fields in
data[]:id,title,description,media_type,item_type,course_id,unit_id,item_id,platform,file_url,file,created_by,created_at,updated_at.created_by,created_at,updated_at,item_type, andplatformare read-only. - Permissions (
MediaResourcePermission): the path{user_id}must have an activeUserPlatformLinkto the{org}platform. Reads (safe methods) need only that active link; writes (POST/PUT/PATCH/DELETE) additionally require that link to be admin (is_admin). A missing user, unknown org, or no active link all fail the check. Object-level access also requires the resource'splatform.orgto equal the path{org}. - Org / user resolution.
{org}is matched againstPlatform.organd{user_id}againstUser.id; an unknown org yields an empty result set (or permission failure on writes). Unlike the rest of/iblai-api-catalog, org and user are path segments, not query/body params.