Get All Collections
URL: https://api.gradual-api.com/public-api/v1/collections
HTTP Method: GET
Content type: application/json
Tier: Medium
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200
Note: The collections are returned in order of creation date, with the most recently created collections appearing first.
Response Example:
{"size": 1,"pageNumber": 1,"pageSize": 50,"results": [{"collectionId": "63e293d17efa0788a97273fe","collectionName": "Collection Name","collectionVisibility": "Visible","collectionUrl": "https://elc.gradual/home/collections/collection-name","collectionCoverUrl": "https://abc.cloudfront.net/uploads/test/Collection-Name-fd0ffeb0-195e-491e-9eea-ae351f9914d8-1676390983173.png","collectionSlug": "collection-name","collectionUpdatedAt": "2025-08-14T12:39:31.259Z","collectionContent": [{"type": "video","id": "63d40ad685f10b97ffa7feae","title": "Video Title"},{"type": "blog","id": "6266772cfffad41e5be35862","title": "Article Title"}]}]}
Get All Videos
URL: https://api.gradual-api.com/public-api/v1/videos
HTTP Method: GET
Content type: application/json
Tier: Medium
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200fromDate, string, optional, format:YYYY-MM-DD, date will be padded to the start of the day. If afromDateis specified, the response will include videos with a created time later than 00:00 of the providedfromDate.toDate, string, optional, format:YYYY-MM-DD, date will be padded to the end of the day. Similarly, if atoDateis specified, the response will include videos with a created time earlier than 23:59 of the providedtoDate.
Note: The videos are returned in order of creation date, with the most recently created videos appearing first.
Response Example:
{"size": 2,"pageNumber": 1,"pageSize": 50,"results": [{"videoId": "654180e3566f8d5a7fb49e86","videoTitle": "Video Title","videoDescription": "Video Description","videoCreatedAt": "2023-10-31T22:34:11.099Z","videoSlug": "video-title","videoUrl": "https://www.youtube.com/watch?v=_Z1mwUosYU","videoThumbnailUrl": "https://abc.cloudfront.net/uploads/test/Video-Title-fd0ffeb0-195e-491e-9eea-ae351f9914d8-1676390983173.png","videoDuration": 120,"videoTags": ["tag1","tag2"],"spaces": ["Space 1","Space 2"],"access": "Public","ownership": "Community"},{"videoId": "64adee61dc5dfe85abf9ae3e","videoTitle": "Video Title","videoDescription": "Video Description","videoCreatedAt": "2023-10-31T22:34:11.099Z","videoSlug": "video-title","videoUrl": "https://www.youtube.com/watch?v=_Z1mwUYgwU","videoThumbnailUrl": "https://abc.cloudfront.net/uploads/test/Video-Title-fd0ffeb0-195e-491e-9eea-ae351f9914d8-1676390983173.png","videoDuration": 120,"videoTags": [],"spaces": [],"access": "Public","ownership": "VIP Club"}]}
Get All Blogs
URL: https://api.gradual-api.com/public-api/v1/blogs
HTTP Method: GET
Content type: application/json
Tier: Medium
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200fromDate, string, optional, format:YYYY-MM-DD, date will be padded to the start of the day. If afromDateis specified, the response will include blogs with a created time later than 00:00 of the providedfromDate.toDate, string, optional, format:YYYY-MM-DD, date will be padded to the end of the day. Similarly, if atoDateis specified, the response will include blogs with a created time earlier than 23:59 of the providedtoDate.
Note: The blogs are returned in order of creation date, with the most recently created blogs appearing first.
Response Example:
{"size": 1,"pageNumber": 1,"pageSize": 50,"results": [{"blogId": "654180e3566f8d5a7fb49e86","blogTitle": "Blog Title","blogSubTitle": "Blog Sub Title","blogAuthor": "Blog Author1, Blog Author2","blogSummary": "Blog Summary","blogContent": "Blog Content","blogCategory": "Blog Category","blogCreatedAt": "2023-10-31T22:34:11.099Z","blogSlug": "blog-title","blogCoverUrl": "https://abc.cloudfront.net/uploads/test/Video-Title-fd0ffeb0-195e-491e-9eea-ae351f9914d8-1676390983173.png","blogTags": ["tag1"],"spaces": ["Space 1"],"access": "Public","ownership": "Community"}]}
Get All Podcasts
URL: https://api.gradual-api.com/public-api/v1/podcasts
HTTP Method: GET
Content type: application/json
Tier: Medium
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200fromDate, string, optional, format:YYYY-MM-DD, date will be padded to the start of the day. If afromDateis specified, the response will include podcasts with a created time later than 00:00 of the providedfromDate.toDate, string, optional, format:YYYY-MM-DD, date will be padded to the end of the day. Similarly, if atoDateis specified, the response will include podcasts with a created time earlier than 23:59 of the providedtoDate.
Note: The podcasts are returned in order of creation date, with the most recently created podcasts appearing first.
Response Example:
{"size": 1,"pageNumber": 1,"pageSize": 50,"results": [{"podcastId": "654180e3566f8d5a7fb49e86","podcastTitle": "Podcast Title","podcastSubTitle": "Podcast Sub Title","podcastAuthor": "Podcast Author1, Podcast Author2","podcastSummary": "Podcast Summary","podcastContent": "Podcast Content","podcastCategory": "Podcast Category","podcastCreatedAt": "2023-10-31T22:34:11.099Z","podcastSlug": "podcast-title","podcastCoverUrl": "https://abc.cloudfront.net/uploads/test/Video-Title-fd0ffeb0-195e-491e-9eea-ae351f9914d8-1676390983173.png","podcastTags": ["tag1"],"spaces": ["Space 1"],"access": "Public","ownership": "Community"}]}
Get All Resources
URL: https://api.gradual-api.com/public-api/v1/resources
HTTP Method: GET
Content type: application/json
Tier: Medium
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200fromDate, string, optional, format:YYYY-MM-DD, date will be padded to the start of the day. If afromDateis specified, the response will include resources with a created time later than 00:00 of the providedfromDate.toDate, string, optional, format:YYYY-MM-DD, date will be padded to the end of the day. Similarly, if atoDateis specified, the response will include resources with a created time earlier than 23:59 of the providedtoDate.
Note: The resources are returned in order of creation date, with the most recently created resources appearing first.
Response Example:
{"size": 1,"pageNumber": 1,"pageSize": 50,"results": [{"resourceId": "654180e3566f8d5a7fb49e86","resourceTitle": "Resource Title","resourceSubTitle": "Resource Sub Title","resourceAuthor": "Resource Author1, Resource Author2","resourceSummary": "Resource Summary","resourceContent": "Resource Content","resourceCategory": "Resource Category","resourceCreatedAt": "2023-10-31T22:34:11.099Z","resourceSlug": "resource-title","resourceCoverUrl": "https://abc.cloudfront.net/uploads/test/Video-Title-fd0ffeb0-195e-491e-9eea-ae351f9914d8-1676390983173.png","resourceTags": ["tag1"],"spaces": ["Space 1"],"access": "Public","ownership": "VIP Club"}]}
Get All External Contents
URL: https://api.gradual-api.com/public-api/v1/external-contents
HTTP Method: GET
Content type: application/json
Tier: Medium
Query Parameters:
pageNum, number, optional, default 1pageSize, number, optional, default 50, max 200fromDate, string, optional, format:YYYY-MM-DD, date will be padded to the start of the day. If afromDateis specified, the response will include external-contents with a created time later than 00:00 of the providedfromDate.toDate, string, optional, format:YYYY-MM-DD, date will be padded to the end of the day. Similarly, if atoDateis specified, the response will include external-contents with a created time earlier than 23:59 of the providedtoDate.
Note: The external-contents are returned in order of creation date, with the most recently created external-contents appearing first.
Response Example:
{"size": 1,"pageNumber": 1,"pageSize": 50,"results": [{"externalContentId": "654180e3566f8d5a7fb49e86","externalContentTitle": "External Content Title","externalContentSummary": "External Content Summary","externalContentContent": "External Content Content","externalContentCategory": "External Content Category","externalContentCreatedAt": "2023-10-31T22:34:11.099Z","externalContentSlug": "external-content-title","externalContentCoverUrl": "https://abc.cloudfront.net/uploads/test/Video-Title-fd0ffeb0-195e-491e-9eea-ae351f9914d8-1676390983173.png","externalContentLink": "https://www.google.com","externalContentTags": ["tag1"],"spaces": ["Space 1"],"access": "Public","ownership": "Community"}]}
Add a New Video
URL: https://api.gradual-api.com/public-api/v1/videos
HTTP Method: POST
Content type: application/json
Tier: Medium
Request Body Parameters:
title, string, required, video title (1–300 characters), must be uniquevideoUrl, string, required, must be a valid URL pointing to the video fileposterUrl, string, required, must be a valid URL pointing to a thumbnail image (must be 16:9 aspect ratio)duration, string, required, video length inHH:MM:SS,MM:SS, or total seconds formatauthorEmail, string, optional, email of an existing user to attribute as the video authortags, string, optional, semicolon-separated list of tag names, maximum 20 (tags will be created if they don't exist). See Tags to manage tags directly.publish, boolean, optional, whether to publish the video immediately (defaults tofalse)collection, string, optional, name of an existing collection to add the video tosummary, string, optional, video descriptiontranscript, string, optional, video transcript text
Request Body Example:
{"title": "Getting Started with Gradual","videoUrl": "https://example.com/videos/getting-started.mp4","posterUrl": "https://example.com/thumbnails/getting-started.jpg","duration": "12:34","tags": "Tutorial;Getting Started","publish": true,"collection": "Onboarding","summary": "A walkthrough of the Gradual platform for new users.","transcript": "Welcome to Gradual..."}
Response Example:
{"videoId": "6553ce608b3f645e79d95034","videoTitle": "Getting Started with Gradual","videoDescription": "A walkthrough of the Gradual platform for new users.","videoDuration": 754,"videoThumbnailUrl": "https://s3.amazonaws.com/uploads/tenant/thumbnail.jpg","videoUrl": "https://example.com/videos/getting-started.mp4","videoCreatedAt": "2024-11-14T10:30:00.000Z","videoSlug": "getting-started-with-gradual","videoTags": ["Tutorial", "Getting Started"],"videoTranscript": "Welcome to Gradual..."}
Notes:
- The
posterUrlimage must have a 16:9 aspect ratio, otherwise the request will be rejected. The image is downloaded and re-hosted on our servers. - The
durationfield accepts multiple formats:HH:MM:SS(e.g.1:12:34),MM:SS(e.g.12:34), or total seconds as a plain number (e.g.754). - If
authorEmailis provided but no matching user is found, the video will still be created without an author. - A video with a duplicate title will be rejected with a
400error. tagsare separated by semicolons (;), not commas — a comma is treated as part of the tag name. Tag names are case-sensitive, soTutorialandtutorialcreate two distinct tags.- If
collectionis provided but does not match an existing collection name, the request will be rejected with a400error.
Content Comments
Content comments are comments left on blog posts and videos. They have their own approval flow: when comment approval is enabled, new comments are held in pendingApproval until an admin approves them.
Content comments cannot be reported by members — there is no reported queue for them. The only queue is pendingApproval.
Every action endpoint (POST) requires operatorEmail in the request body — the email of the community member the action is attributed to. That member must be an admin or moderator: a missing or unresolvable email returns 400, and a member without permission returns 403.
The Content Comment object
id, string, the unique identifier of the commentcontent, string, the comment bodystatus, string, one ofinitialCheck,pendingApproval(awaiting admin approval),published,deleted,selfDeletedrootType, string, one ofBlog,LVTenantVideorootId, string, the identifier of the blog or video the comment belongs torootTitle, string, the title of the blog or videoparentCommentId, string, the identifier of the comment this one replies to,nullfor top-level commentsdeleteReason, array of strings, moderation categories recorded on removalcreatedAt, string, ISO 8601 timestamp of creationupdatedAt, string, ISO 8601 timestamp of the last change of any kindlastEditAt, string, ISO 8601 timestamp of the author's last editcommenter, object, the author —{ email, firstName, lastName, pictureUrl, headline }
Moderation categories accepted by deleteReason: Spam, Profane, Offensive, Sexual, Gibberish. Values are case-sensitive; any other value returns 400.
List Content Comments
URL: https://api.gradual-api.com/public-api/v1/content/comments
HTTP Method: GET
Content type: application/json
Tier: Medium
Returns comments on blogs and videos. Filter by status=pendingApproval to get the approval queue.
Query Parameters:
pageNum, integer, optional, page number (minimum 1, defaults to 1)pageSize, integer, optional, number of results per page (1–200, defaults to 50)status, string, optional, comma-separated list ofinitialCheck,pendingApproval,published,deleted,selfDeleted. Defaults to all statusesrootType, string, optional, one ofBlog,LVTenantVideorootId, string, optional, restrict to comments on one specific blog or videoauthorEmail, string, optional, restrict to comments by one memberdeleteReason, string, optional, comma-separated moderation categories, restrict to comments removed for those reasonssortBy, string, optional, the literalcreatedAt(the default, and currently the only supported value)sortOrder, string, optional, sort direction:ascordesc(defaults todesc)
Response Example:
{"size": 1,"pageNumber": 1,"pageSize": 50,"results": [{"id": "665f1c2a9b3e4a0012abdd01","content": "Great write-up, thanks!","status": "pendingApproval","rootType": "Blog","rootId": "665f1c2a9b3e4a0012ab7777","rootTitle": "How we scaled our community","parentCommentId": null,"deleteReason": [],"createdAt": "2026-07-28T06:14:55.000Z","updatedAt": "2026-07-28T06:14:55.000Z","lastEditAt": "2026-07-28T06:14:55.000Z","commenter": {"firstName": "Dana","lastName": "Park","pictureUrl": null,"headline": null}}]}
Notes:
- Pass
status=pendingApprovalto get the approval queue — those are exactly the comments thatPOST /content/comments/{commentId}/approveaccepts.
Approve a Content Comment
URL: https://api.gradual-api.com/public-api/v1/content/comments/{commentId}/approve
HTTP Method: POST
Content type: application/json
Tier: Medium
Approves a comment awaiting approval and publishes it.
Path Parameters:
commentId, string, required, the unique identifier of the comment
Request Body Parameters:
operatorEmail, string, required, the email of the member to attribute this action to
Response Example (200 OK): the updated Content Comment object, with status now published.
Notes:
- Only comments in
pendingApprovalcan be approved. Returns200and the current comment if it is already published, so retries are safe. - Approving a deleted comment returns
404, not409— this is where content comments differ from forum posts and comments, which return409for a wrong-state action. A comment in any state other thanpendingApprovalorpublishedis reported as not found. UsePOST …/recoverto bring a deleted comment back. - Returns
404if no comment with the givencommentIdexists in your community.
Delete a Content Comment
URL: https://api.gradual-api.com/public-api/v1/content/comments/{commentId}/delete
HTTP Method: POST
Content type: application/json
Tier: Medium
Removes a comment from the blog or video it was left on. Works on published comments and comments awaiting approval — use it to deny a comment in the approval queue.
Path Parameters:
commentId, string, required, the unique identifier of the comment
Request Body Parameters:
operatorEmail, string, required, the email of the member to attribute this action todeleteReason, array of strings, optional, one or more moderation categories. Include"Spam"to mark the comment as spam
Request Body Example:
{"deleteReason": ["Spam"]}
Response Example (200 OK): the updated Content Comment object, with status now deleted.
Notes:
- Returns
409if the comment is already deleted. - Returns
409with"message": "Comment is locked"when the content the comment sits on is not publicly visible — an unpublished blog, or a video that is not public. Publish the blog or make the video public, then retry. Approve and recover are not subject to this check; only delete is. - Returns
400ifdeleteReasoncontains an unsupported value.
Restore a Deleted Content Comment
URL: https://api.gradual-api.com/public-api/v1/content/comments/{commentId}/recover
HTTP Method: POST
Content type: application/json
Tier: Medium
Republishes a comment that was previously removed.
Path Parameters:
commentId, string, required, the unique identifier of the comment
Request Body Parameters:
operatorEmail, string, required, the email of the member to attribute this action to
Response Example (200 OK): the updated Content Comment object, with status now published and deleteReason cleared.
Notes:
- Returns
404if the comment does not exist or is not currently deleted. A comment the author removed themselves hasstatus: "selfDeleted"and is not recoverable through this API.