Discussion Topics API

A discussion topic object looks like:

 {
   // The ID of this topic.
   "id":1,

   // The topic title.
   "title":"Topic 1",

   // The HTML content of the message body.
   "message":"<p>content here</p>",

   // The URL to the discussion topic in canvas.
   "html_url": "https://<canvas>/courses/1/discussion_topics/2",

   // The datetime the topic was posted. If it is null it hasn't been
   // posted yet. (see delayed_post_at)
   "posted_at":"2037-07-21T13:29:31Z",

   // The datetime for when the last reply was in the topic.
   "last_reply_at":"2037-07-28T19:38:31Z",

   // If true then a user may not respond to other replies until that user
   // has made an initial reply. Defaults to false.
   "require_initial_post":false,

   // Whether or not posts in this topic are visible to the user.
  "user_can_see_posts":true,

   // The count of entries in the topic.
   "discussion_subentry_count":0,

   // The read_state of the topic for the current user, "read" or "unread".
   "read_state":"read",

   // The count of unread entries of this topic for the current user.
   "unread_count":0,

   // Whether or not the current user is subscribed to this topic.
   "subscribed":true,

   // (Optional) Why the user cannot subscribe to this topic. Only one reason
   // will be returned even if multiple apply. Can be one of:
   // 'initial_post_required': The user must post a reply first
   // 'not_in_group_set': The user is not in the group set for this graded group discussion
   // 'not_in_group': The user is not in this topic's group
   // 'topic_is_announcement': This topic is an announcement
   "subscription_hold":"not_in_group_set",

   // The unique identifier of the assignment if the topic is for grading, otherwise null.
   "assignment_id":null,

   // The datetime to publish the topic (if not right away).
   "delayed_post_at":null,

   // Whether this discussion topic is published (true) or draft state (false)
   "published":true,

   // The datetime to lock the topic (if ever).
   "lock_at":null,

   // whether or not this is locked for students to see.
   "locked":false,

   // whether or not the discussion has been "pinned" by an instructor
   "pinned":false,

   // Whether or not this is locked for the user.
   "locked_for_user":true,

   // (Optional) Information for the user about the lock. Present when locked_for_user is true.
   "lock_info": {
     // Asset string for the object causing the lock
     "asset_string":"discussion_topic_1",

     // (Optional) Time at which this was/will be unlocked.
     "unlock_at":"2013-01-01T00:00:00-06:00",

     // (Optional) Time at which this was/will be locked.
     "lock_at":"2013-02-01T00:00:00-06:00",

     // (Optional) Context module causing the lock.
     "context_module":{ ... }
   },

   // (Optional) An explanation of why this is locked for the user. Present when locked_for_user is true.
   "lock_explanation":"This discussion is locked until September 1 at 12:00am",

   // The username of the topic creator.
   "user_name":"User Name",

   // An array of topic_ids for the group discussions the user is a part of.
   "topic_children":[5, 7, 10],

   // If the topic is for grading and a group assignment this will
   // point to the original topic in the course.
   "root_topic_id":null,

   // If the topic is a podcast topic this is the feed url for the current user.
   "podcast_url":"/feeds/topics/1/enrollment_1XAcepje4u228rt4mi7Z1oFbRpn3RAkTzuXIGOPe.rss",

   // The type of discussion. Values are 'side_comment', for discussions
   // that only allow one level of nested comments, and 'threaded' for
   // fully threaded discussions.
   "discussion_type":"side_comment",

   // Array of file attachments.
   "attachments":[
     {
       "content-type":"unknown/unknown",
       "url":"http://www.example.com/courses/1/files/1/download",
       "filename":"content.txt",
       "display_name":"content.txt"
     }
   ],

   // The current user's permissions on this topic.
   "permissions":
   {
     // If true, the calling user can attach files to this discussion's entries.
     "attach": true
   }
 }

API for accessing and participating in discussion topics in groups and courses.

List discussion topics DiscussionTopicsController#index

GET /api/v1/courses/:course_id/discussion_topics

GET /api/v1/groups/:group_id/discussion_topics

Returns the paginated list of discussion topics for this course or group.

Request Parameters:

  • order_by

    Determines the order of the discussion topic list. May be one of "position", or "recent_activity". Defaults to "position".

  • scope
    Optional, "locked"|"unlocked"

    Only return discussion topics in the given state. Defaults to including locked and unlocked topics. Filtering is done after pagination, so pages may be smaller than requested if topics are filtered

  • only_announcements
    Optional

    Boolean, return announcements instead of discussion topics. Defaults to false

  • search_term

    (optional) The partial title of the discussion topics to match and return.

Example Request:

curl https://<canvas>/api/v1/courses/<course_id>/discussion_topics \ 
     -H 'Authorization: Bearer <token>'

Create a new discussion topic DiscussionTopicsController#create

POST /api/v1/courses/:course_id/discussion_topics

POST /api/v1/groups/:group_id/discussion_topics

POST /api/v1/collection_items/:collection_item_id/discussion_topics

Create an new discussion topic for the course or group.

Request Parameters:

  • title
  • message
  • discussion_type
  • published
    optional
    boolean

    whether this topic is published (true) or draft state (false). Only teachers and TAs have the ability to create draft state topics.

  • delayed_post_at

    If a timestamp is given, the topic will not be published until that time.

  • lock_at

    If a timestamp is given, the topic will be scheduled to lock at the provided timestamp. If the timestamp is in the past, the topic will be locked.

  • podcast_enabled

    If true, the topic will have an associated podcast feed.

  • podcast_has_student_posts

    If true, the podcast will include posts from students as well. Implies podcast_enabled.

  • require_initial_post

    If true then a user may not respond to other replies until that user has made an initial reply. Defaults to false.

  • assignment

    To create an assignment discussion, pass the assignment parameters as a sub-object. See the Create an Assignment API for the available parameters. The name parameter will be ignored, as it's taken from the discussion title. If you want to make a discussion that was an assignment NOT an assignment, pass set_assignment = false as part of the assignment object

  • is_announcement

    If true, this topic is an announcement. It will appear in the announcements section rather than the discussions section. This requires announcment-posting permissions.

  • position_after

    By default, discussions are sorted chronologically by creation date, you can pass the id of another topic to have this one show up after the other when they are listed.

Example Request:

curl https://<canvas>/api/v1/courses/<course_id>/discussion_topics \ 
    -F title='my topic' \ 
    -F message='initial message' \ 
    -F podcast_enabled=1 \ 
    -H 'Authorization: Bearer <token>'

curl https://<canvas>/api/v1/courses/<course_id>/discussion_topics \ 
    -F title='my assignment topic' \ 
    -F message='initial message' \ 
    -F assignment[points_possible]=15 \ 
    -H 'Authorization: Bearer <token>'

Update a topic DiscussionTopicsController#update

PUT /api/v1/courses/:course_id/discussion_topics/:topic_id

PUT /api/v1/groups/:group_id/discussion_topics/:topic_id

PUT /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id

Accepts the same parameters as create

Example Request:

curl https://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id> \ 
    -F title='This will be positioned after Topic #1234' \ 
    -F position_after=1234 \ 
    -H 'Authorization: Bearer <token>'

Delete a topic DiscussionTopicsController#destroy

DELETE /api/v1/courses/:course_id/discussion_topics/:topic_id

DELETE /api/v1/groups/:group_id/discussion_topics/:topic_id

DELETE /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id

Deletes the discussion topic. This will also delete the assignment, if it's an assignment discussion.

Example Request:

curl -X DELETE https://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id> \ 
     -H 'Authorization: Bearer <token>'

Update an entry DiscussionEntriesController#update

PUT /api/v1/courses/:course_id/discussion_topics/:topic_id/entries/:id

PUT /api/v1/groups/:group_id/discussion_topics/:topic_id/entries/:id

PUT /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entries/:id

Update an existing discussion entry.

The entry must have been created by the current user, or the current user must have admin rights to the discussion. If the edit is not allowed, a 401 will be returned.

Request Parameters:

  • message

    The updated body of the entry.

Example Request:

curl -X PUT 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/entries/<entry_id>' \ 
     -F 'message=<message>' \ 
     -H "Authorization: Bearer <token>"

Delete an entry DiscussionEntriesController#destroy

DELETE /api/v1/courses/:course_id/discussion_topics/:topic_id/entries/:id

DELETE /api/v1/groups/:group_id/discussion_topics/:topic_id/entries/:id

DELETE /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entries/:id

Delete a discussion entry.

The entry must have been created by the current user, or the current user must have admin rights to the discussion. If the delete is not allowed, a 401 will be returned.

The discussion will be marked deleted, and the user_id and message will be cleared out.

Example Request:

curl -X DELETE 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/entries/<entry_id>' \ 
     -H "Authorization: Bearer <token>"

Get a single topic DiscussionTopicsApiController#show

GET /api/v1/courses/:course_id/discussion_topics/:topic_id

GET /api/v1/groups/:group_id/discussion_topics/:topic_id

GET /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id

Returns data on an individual discussion topic. See the List action for the response formatting.

Example Request:

curl https://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id> \ 
    -H 'Authorization: Bearer <token>'

Get the full topic DiscussionTopicsApiController#view

GET /api/v1/courses/:course_id/discussion_topics/:topic_id/view

GET /api/v1/groups/:group_id/discussion_topics/:topic_id/view

GET /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/view

Return a cached structure of the discussion topic, containing all entries, their authors, and their message bodies.

May require (depending on the topic) that the user has posted in the topic. If it is required, and the user has not posted, will respond with a 403 Forbidden status and the body 'require_initial_post'.

In some rare situations, this cached structure may not be available yet. In that case, the server will respond with a 503 error, and the caller should try again soon.

The response is an object containing the following keys:

  • "participants": A list of summary information on users who have posted to the discussion. Each value is an object containing their id, display_name, and avatar_url.

  • "unread_entries": A list of entry ids that are unread by the current user. this implies that any entry not in this list is read.

  • "forced_entries": A list of entry ids that have forced_read_state set to true. This flag is meant to indicate the entry's read_state has been manually set to 'unread' by the user, so the entry should not be automatically marked as read.

  • "view": A threaded view of all the entries in the discussion, containing the id, user_id, and message.

  • "new_entries": Because this view is eventually consistent, it's possible that newly created or updated entries won't yet be reflected in the view. If the application wants to also get a flat list of all entries not yet reflected in the view, pass include_new_entries=1 to the request and this array of entries will be returned. These entries are returned in a flat array, in ascending created_at order.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/view' \ 
     -H "Authorization: Bearer <token>"

Example Response:

{
  "unread_entries": [1,3,4],
  "forced_entries": [1],
  "participants": [
    { "id": 10, "display_name": "user 1", "avatar_image_url": "https://...", "html_url": "https://..." },
    { "id": 11, "display_name": "user 2", "avatar_image_url": "https://...", "html_url": "https://..." }
  ],
  "view": [
    { "id": 1, "user_id": 10, "parent_id": null, "message": "...html text...", "replies": [
      { "id": 3, "user_id": 11, "parent_id": 1, "message": "...html....", "replies": [...] }
    ]},
    { "id": 2, "user_id": 11, "parent_id": null, "message": "...html..." },
    { "id": 4, "user_id": 10, "parent_id": null, "message": "...html..." }
  ]
}

Post an entry DiscussionTopicsApiController#add_entry

POST /api/v1/courses/:course_id/discussion_topics/:topic_id/entries

POST /api/v1/groups/:group_id/discussion_topics/:topic_id/entries

POST /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entries

Create a new entry in a discussion topic. Returns a json representation of the created entry (see documentation for 'entries' method) on success.

Request Parameters:

  • message

    The body of the entry.

  • attachment
    Optional

    a multipart/form-data form-field-style

    attachment. Attachments larger than 1 kilobyte are subject to quota restrictions.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/entries.json' \ 
     -F 'message=<message>' \ 
     -F 'attachment=@<filename>' \ 
     -H "Authorization: Bearer <token>"

List topic entries DiscussionTopicsApiController#entries

GET /api/v1/courses/:course_id/discussion_topics/:topic_id/entries

GET /api/v1/groups/:group_id/discussion_topics/:topic_id/entries

GET /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entries

Retrieve the (paginated) top-level entries in a discussion topic.

May require (depending on the topic) that the user has posted in the topic. If it is required, and the user has not posted, will respond with a 403 Forbidden status and the body 'require_initial_post'.

Will include the 10 most recent replies, if any, for each entry returned.

If the topic is a root topic with children corresponding to groups of a group assignment, entries from those subtopics for which the user belongs to the corresponding group will be returned.

Ordering of returned entries is newest-first by posting timestamp (reply activity is ignored).

API response field:

  • id

    The unique identifier for the entry.

  • user_id

    The unique identifier for the author of the entry.

  • editor_id

    The unique user id of the person to last edit the entry, if different than user_id.

  • user_name

    The name of the author of the entry.

  • message

    The content of the entry.

  • read_state

    The read state of the entry, "read" or "unread".

  • forced_read_state

    Whether the read_state was forced (was set manually)

  • created_at

    The creation time of the entry, in ISO8601 format.

  • updated_at

    The updated time of the entry, in ISO8601 format.

  • attachment

    JSON representation of the attachment for the entry, if any. Present only if there is an attachment.

  • attachments

    Deprecated. Same as attachment, but returned as a one-element array. Present only if there is an attachment.

  • recent_replies

    The 10 most recent replies for the entry, newest first. Present only if there is at least one reply.

  • has_more_replies

    True if there are more than 10 replies for the entry (i.e., not all were included in this response). Present only if there is at least one reply.

Example Response:

[ {
    "id": 1019,
    "user_id": 7086,
    "user_name": "nobody@example.com",
    "message": "Newer entry",
    "read_state": "read",
    "forced_read_state": false,
    "created_at": "2011-11-03T21:33:29Z",
    "attachment": {
      "content-type": "unknown/unknown",
      "url": "http://www.example.com/files/681/download?verifier=JDG10Ruitv8o6LjGXWlxgOb5Sl3ElzVYm9cBKUT3",
      "filename": "content.txt",
      "display_name": "content.txt" } },
  {
    "id": 1016,
    "user_id": 7086,
    "user_name": "nobody@example.com",
    "message": "first top-level entry",
    "read_state": "unread",
    "forced_read_state": false,
    "created_at": "2011-11-03T21:32:29Z",
    "recent_replies": [
      {
        "id": 1017,
        "user_id": 7086,
        "user_name": "nobody@example.com",
        "message": "Reply message",
        "created_at": "2011-11-03T21:32:29Z"
      } ],
    "has_more_replies": false } ]

Post a reply DiscussionTopicsApiController#add_reply

POST /api/v1/courses/:course_id/discussion_topics/:topic_id/entries/:entry_id/replies

POST /api/v1/groups/:group_id/discussion_topics/:topic_id/entries/:entry_id/replies

POST /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entries/:entry_id/replies

Add a reply to an entry in a discussion topic. Returns a json representation of the created reply (see documentation for 'replies' method) on success.

May require (depending on the topic) that the user has posted in the topic. If it is required, and the user has not posted, will respond with a 403 Forbidden status and the body 'require_initial_post'.

Request Parameters:

  • message

    The body of the entry.

  • attachment
    Optional

    a multipart/form-data form-field-style

    attachment. Attachments larger than 1 kilobyte are subject to quota restrictions.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/entries/<entry_id>/replies.json' \ 
     -F 'message=<message>' \ 
     -F 'attachment=@<filename>' \ 
     -H "Authorization: Bearer <token>"

List entry replies DiscussionTopicsApiController#replies

GET /api/v1/courses/:course_id/discussion_topics/:topic_id/entries/:entry_id/replies

GET /api/v1/groups/:group_id/discussion_topics/:topic_id/entries/:entry_id/replies

GET /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entries/:entry_id/replies

Retrieve the (paginated) replies to a top-level entry in a discussion topic.

May require (depending on the topic) that the user has posted in the topic. If it is required, and the user has not posted, will respond with a 403 Forbidden status and the body 'require_initial_post'.

Ordering of returned entries is newest-first by creation timestamp.

API response field:

  • id

    The unique identifier for the reply.

  • user_id

    The unique identifier for the author of the reply.

  • editor_id

    The unique user id of the person to last edit the entry, if different than user_id.

  • user_name

    The name of the author of the reply.

  • message

    The content of the reply.

  • read_state

    The read state of the entry, "read" or "unread".

  • forced_read_state

    Whether the read_state was forced (was set manually)

  • created_at

    The creation time of the reply, in ISO8601 format.

Example Response:

[ {
    "id": 1015,
    "user_id": 7084,
    "user_name": "nobody@example.com",
    "message": "Newer message",
    "read_state": "read",
    "forced_read_state": false,
    "created_at": "2011-11-03T21:27:44Z" },
  {
    "id": 1014,
    "user_id": 7084,
    "user_name": "nobody@example.com",
    "message": "Older message",
    "read_state": "unread",
    "forced_read_state": false,
    "created_at": "2011-11-03T21:26:44Z" } ]

List entries DiscussionTopicsApiController#entry_list

GET /api/v1/courses/:course_id/discussion_topics/:topic_id/entry_list

GET /api/v1/groups/:group_id/discussion_topics/:topic_id/entry_list

GET /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entry_list

Retrieve a paginated list of discussion entries, given a list of ids.

May require (depending on the topic) that the user has posted in the topic. If it is required, and the user has not posted, will respond with a 403 Forbidden status and the body 'require_initial_post'.

Request Parameters:

  • ids[]

    A list of entry ids to retrieve. Entries will be returned in id order, smallest id first.

API response field:

  • id

    The unique identifier for the reply.

  • user_id

    The unique identifier for the author of the reply.

  • user_name

    The name of the author of the reply.

  • message

    The content of the reply.

  • read_state

    The read state of the entry, "read" or "unread".

  • forced_read_state

    Whether the read_state was forced (was set manually)

  • created_at

    The creation time of the reply, in ISO8601 format.

  • deleted

    If the entry has been deleted, returns true. The user_id, user_name, and message will not be returned for deleted entries.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/entry_list?ids[]=1&ids[]=2&ids[]=3' \ 
     -H "Authorization: Bearer <token>"

Example Response:

[
  { ... entry 1 ... },
  { ... entry 2 ... },
  { ... entry 3 ... },
]

Mark topic as read DiscussionTopicsApiController#mark_topic_read

PUT /api/v1/courses/:course_id/discussion_topics/:topic_id/read

PUT /api/v1/groups/:group_id/discussion_topics/:topic_id/read

PUT /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/read

Mark the initial text of the discussion topic as read.

No request fields are necessary.

On success, the response will be 204 No Content with an empty body.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/read.json' \ 
     -X PUT \ 
     -H "Authorization: Bearer <token>" \ 
     -H "Content-Length: 0"

Mark topic as unread DiscussionTopicsApiController#mark_topic_unread

DELETE /api/v1/courses/:course_id/discussion_topics/:topic_id/read

DELETE /api/v1/groups/:group_id/discussion_topics/:topic_id/read

DELETE /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/read

Mark the initial text of the discussion topic as unread.

No request fields are necessary.

On success, the response will be 204 No Content with an empty body.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/read.json' \ 
     -X DELETE \ 
     -H "Authorization: Bearer <token>"

Mark all entries as read DiscussionTopicsApiController#mark_all_read

PUT /api/v1/courses/:course_id/discussion_topics/:topic_id/read_all

PUT /api/v1/groups/:group_id/discussion_topics/:topic_id/read_all

PUT /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/read_all

Mark the discussion topic and all its entries as read.

No request fields are necessary.

On success, the response will be 204 No Content with an empty body.

Request Parameters:

  • forced_read_state
    Optional

    A boolean value to set all of the entries' forced_read_state. No change is made if this argument is not specified.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/read_all.json' \ 
     -X PUT \ 
     -H "Authorization: Bearer <token>" \ 
     -H "Content-Length: 0"

Mark all entries as unread DiscussionTopicsApiController#mark_all_unread

DELETE /api/v1/courses/:course_id/discussion_topics/:topic_id/read_all

DELETE /api/v1/groups/:group_id/discussion_topics/:topic_id/read_all

DELETE /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/read_all

Mark the discussion topic and all its entries as unread.

No request fields are necessary.

On success, the response will be 204 No Content with an empty body.

Request Parameters:

  • forced_read_state
    Optional

    A boolean value to set all of the entries' forced_read_state. No change is made if this argument is not specified.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/read_all.json' \ 
     -X DELETE \ 
     -H "Authorization: Bearer <token>"

Mark entry as read DiscussionTopicsApiController#mark_entry_read

PUT /api/v1/courses/:course_id/discussion_topics/:topic_id/entries/:entry_id/read

PUT /api/v1/groups/:group_id/discussion_topics/:topic_id/entries/:entry_id/read

PUT /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entries/:entry_id/read

Mark a discussion entry as read.

No request fields are necessary.

On success, the response will be 204 No Content with an empty body.

Request Parameters:

  • forced_read_state
    Optional

    A boolean value to set the entry's forced_read_state. No change is made if this argument is not specified.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/entries/<entry_id>/read.json' \ 
     -X PUT \ 
     -H "Authorization: Bearer <token>"\ 
     -H "Content-Length: 0"

Mark entry as unread DiscussionTopicsApiController#mark_entry_unread

DELETE /api/v1/courses/:course_id/discussion_topics/:topic_id/entries/:entry_id/read

DELETE /api/v1/groups/:group_id/discussion_topics/:topic_id/entries/:entry_id/read

DELETE /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/entries/:entry_id/read

Mark a discussion entry as unread.

No request fields are necessary.

On success, the response will be 204 No Content with an empty body.

Request Parameters:

  • forced_read_state
    Optional

    A boolean value to set the entry's forced_read_state. No change is made if this argument is not specified.

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/entries/<entry_id>/read.json' \ 
     -X DELETE \ 
     -H "Authorization: Bearer <token>"

Subscribe to a topic DiscussionTopicsApiController#subscribe_topic

PUT /api/v1/courses/:course_id/discussion_topics/:topic_id/subscribed

PUT /api/v1/groups/:group_id/discussion_topics/:topic_id/subscribed

PUT /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/subscribed

Subscribe to a topic to receive notifications about new entries

On success, the response will be 204 No Content with an empty body

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/subscribed.json' \ 
     -X PUT \ 
     -H "Authorization: Bearer <token>" \ 
     -H "Content-Length: 0"

Unsubscribe from a topic DiscussionTopicsApiController#unsubscribe_topic

DELETE /api/v1/courses/:course_id/discussion_topics/:topic_id/subscribed

DELETE /api/v1/groups/:group_id/discussion_topics/:topic_id/subscribed

DELETE /api/v1/collection_items/:collection_item_id/discussion_topics/:topic_id/subscribed

Unsubscribe from a topic to stop receiving notifications about new entries

On success, the response will be 204 No Content with an empty body

Example Request:

curl 'http://<canvas>/api/v1/courses/<course_id>/discussion_topics/<topic_id>/subscribed.json' \ 
     -X DELETE \ 
     -H "Authorization: Bearer <token>"