Stay organized with collections
Save and categorize content based on your preferences.
A Topic is a label for grouping CourseWork and
CourseWorkMaterial stream items within a course. A Topic is typically used
to categorize these items by similarity, such as the week the items are assigned
or their subject. Users can visually organize and filter stream items in the
Classwork view of the Classroom UI.
Each Topic is identified by a unique ID assigned by the server. The Topic
resource also contains the following:
name: The display name shown in the Classroom UI
updateTime: The time the Topic was last updated
courseId: The ID of the course that the Topic is associated with
Create a Topic
You can create a new Topic in a course using the topics.create() method,
as shown in the following sample:
Topictopic=null;try{// Create the new Topic.Topiccontent=newTopic().setName("Semester 1");topic=service.courses().topics().create(courseId,content).execute();System.out.println("Topic id: "+topic.getTopicId()+"\n"+"Course id: "+courseId);}catch(GoogleJsonResponseExceptione){// TODO (developer) - handle error appropriatelyGoogleJsonErrorerror=e.getDetails();if(error.getCode()==404){System.out.printf("The courseId does not exist: %s.\n",courseId);}else{throwe;}}catch(Exceptione){throwe;}returntopic;
Topictopic=null;try{// Get the topic.topic=service.courses().topics().get(courseId,topicId).execute();System.out.printf("Topic '%s' found.\n",topic.getName());}catch(GoogleJsonResponseExceptione){// TODO (developer) - handle error appropriatelyGoogleJsonErrorerror=e.getDetails();if(error.getCode()==404){System.out.printf("The courseId or topicId does not exist: %s, %s.\n",courseId,topicId);}throwe;}catch(Exceptione){throwe;}returntopic;
List<Topic>topics=newArrayList<>();StringpageToken=null;try{do{ListTopicResponseresponse=service.courses().topics().list(courseId).setPageSize(100).setPageToken(pageToken).execute();/* Ensure that the response is not null before retrieving data from it to avoid errors. */if(response.getTopic()!=null){topics.addAll(response.getTopic());pageToken=response.getNextPageToken();}}while(pageToken!=null);if(topics.isEmpty()){System.out.println("No topics found.");}else{for(Topictopic:topics){System.out.printf("%s (%s)\n",topic.getName(),topic.getTopicId());}}}catch(GoogleJsonResponseExceptione){// TODO (developer) - handle error appropriatelyGoogleJsonErrorerror=e.getDetails();if(error.getCode()==404){System.out.printf("The courseId does not exist: %s.\n",courseId);}else{throwe;}}catch(Exceptione){throwe;}returntopics;
Topictopic=null;try{// Retrieve the topic to update.TopictopicToUpdate=service.courses().topics().get(courseId,topicId).execute();// Update the name field for the topic retrieved.topicToUpdate.setName("Semester 2");/* Call the patch endpoint and set the updateMask query parameter to the field that needs to be updated. */topic=service.courses().topics().patch(courseId,topicId,topicToUpdate).set("updateMask","name").execute();/* Prints the updated topic. */System.out.printf("Topic '%s' updated.\n",topic.getName());}catch(GoogleJsonResponseExceptione){// TODO(developer) - handle error appropriatelyGoogleJsonErrorerror=e.getDetails();if(error.getCode()==404){System.out.printf("The courseId or topicId does not exist: %s, %s.\n",courseId,topicId);}else{throwe;}}catch(Exceptione){throwe;}returntopic;
[null,null,["Last updated 2025-08-28 UTC."],[],[],null,["# Manage Topics\n\nA [`Topic`](/workspace/classroom/reference/rest/v1/courses.topics) is a label for grouping [`CourseWork`](/workspace/classroom/reference/rest/v1/courses.courseWork) and\n[`CourseWorkMaterial`](/workspace/classroom/reference/rest/v1/courses.courseWorkMaterials) stream items within a course. A `Topic` is typically used\nto categorize these items by similarity, such as the week the items are assigned\nor their subject. Users can visually organize and filter stream items in the\n**Classwork** view of the Classroom UI.\n\nEach `Topic` is identified by a unique ID assigned by the server. The `Topic`\nresource also contains the following:\n\n- `name`: The display name shown in the Classroom UI\n- `updateTime`: The time the `Topic` was last updated\n- `courseId`: The ID of the course that the `Topic` is associated with\n\nCreate a Topic\n--------------\n\nYou can create a new `Topic` in a course using the [`topics.create()`](/workspace/classroom/reference/rest/v1/courses.topics/create) method,\nas shown in the following sample: \n\n### Java\n\nclassroom/snippets/src/main/java/CreateTopic.java \n[View on GitHub](https://github.com/googleworkspace/java-samples/blob/main/classroom/snippets/src/main/java/CreateTopic.java) \n\n```java\nTopic topic = null;\ntry {\n // Create the new Topic.\n Topic content = new Topic().setName(\"Semester 1\");\n topic = service.courses().topics().create(courseId, content).execute();\n System.out.println(\"Topic id: \" + topic.getTopicId() + \"\\n\" + \"Course id: \" + courseId);\n} catch (GoogleJsonResponseException e) {\n // TODO (developer) - handle error appropriately\n GoogleJsonError error = e.getDetails();\n if (error.getCode() == 404) {\n System.out.printf(\"The courseId does not exist: %s.\\n\", courseId);\n } else {\n throw e;\n }\n} catch (Exception e) {\n throw e;\n}\nreturn topic;\n```\n\n### Python\n\n topic = {\n \"name\": 'Example Topic'\n }\n response = service.courses().topics().create(\n courseId=\u003ccourse ID or alias\u003e,\n body=topic).execute()\n print('Topic created: ', response['name'])\n\nThe `name` field is always required and must be a non-empty string. All other\nfields are optional.\n| **Important:** There is a bug that causes a `Topic` created with a space at the end to become unusable in Classroom. Be sure to remove trailing whitespace when creating a `Topic`.\n\nRetrieve Topic details\n----------------------\n\nYou can retrieve a specific `Topic` by ID with the [`topics.get()`](/workspace/classroom/reference/rest/v1/courses.topics/get) method, as\nshown in the following sample: \n\n### Java\n\nclassroom/snippets/src/main/java/GetTopic.java \n[View on GitHub](https://github.com/googleworkspace/java-samples/blob/main/classroom/snippets/src/main/java/GetTopic.java) \n\n```java\nTopic topic = null;\ntry {\n // Get the topic.\n topic = service.courses().topics().get(courseId, topicId).execute();\n System.out.printf(\"Topic '%s' found.\\n\", topic.getName());\n} catch (GoogleJsonResponseException e) {\n // TODO (developer) - handle error appropriately\n GoogleJsonError error = e.getDetails();\n if (error.getCode() == 404) {\n System.out.printf(\"The courseId or topicId does not exist: %s, %s.\\n\", courseId, topicId);\n }\n throw e;\n} catch (Exception e) {\n throw e;\n}\nreturn topic;\n```\n\n### Python\n\n response = service.courses().topics().get(\n courseId=\u003ccourse ID or alias\u003e,\n id=\u003ctopic ID\u003e).execute()\n print('{0} ({1})'.format(response['name'], response['topicId']))\n\nUse the [`topics.list()`](/workspace/classroom/reference/rest/v1/courses.topics/list) method to retrieve all `Topic`s in a course, as shown\nin the following sample: \n\n### Java\n\nclassroom/snippets/src/main/java/ListTopics.java \n[View on GitHub](https://github.com/googleworkspace/java-samples/blob/main/classroom/snippets/src/main/java/ListTopics.java) \n\n```java\nList\u003cTopic\u003e topics = new ArrayList\u003c\u003e();\nString pageToken = null;\n\ntry {\n do {\n ListTopicResponse response =\n service\n .courses()\n .topics()\n .list(courseId)\n .setPageSize(100)\n .setPageToken(pageToken)\n .execute();\n\n /* Ensure that the response is not null before retrieving data from it to avoid errors. */\n if (response.getTopic() != null) {\n topics.addAll(response.getTopic());\n pageToken = response.getNextPageToken();\n }\n } while (pageToken != null);\n\n if (topics.isEmpty()) {\n System.out.println(\"No topics found.\");\n } else {\n for (Topic topic : topics) {\n System.out.printf(\"%s (%s)\\n\", topic.getName(), topic.getTopicId());\n }\n }\n} catch (GoogleJsonResponseException e) {\n // TODO (developer) - handle error appropriately\n GoogleJsonError error = e.getDetails();\n if (error.getCode() == 404) {\n System.out.printf(\"The courseId does not exist: %s.\\n\", courseId);\n } else {\n throw e;\n }\n} catch (Exception e) {\n throw e;\n}\nreturn topics;\n```\n\n### Python\n\n topics = []\n page_token = None\n while True:\n response = service.courses().topics().list(\n pageToken=page_token,\n pageSize=30,\n courseId=\u003ccourse ID or alias\u003e).execute()\n topics.extend(response.get('topic', []))\n page_token = response.get('nextPageToken', None)\n if not page_token:\n break\n if not topics:\n print('No topics found.')\n else:\n print('Topics:')\n for topic in topics:\n print('{0} ({1})'.format(topic['name'], topic['topicId']))\n\nUpdate a Topic\n--------------\n\nYou can update an existing `Topic` `name` with the [`topics.patch()`](/workspace/classroom/reference/rest/v1/courses.topics/patch) method, as\nshown in the following sample: \n\n### Java\n\nclassroom/snippets/src/main/java/UpdateTopic.java \n[View on GitHub](https://github.com/googleworkspace/java-samples/blob/main/classroom/snippets/src/main/java/UpdateTopic.java) \n\n```java\nTopic topic = null;\ntry {\n // Retrieve the topic to update.\n Topic topicToUpdate = service.courses().topics().get(courseId, topicId).execute();\n\n // Update the name field for the topic retrieved.\n topicToUpdate.setName(\"Semester 2\");\n\n /* Call the patch endpoint and set the updateMask query parameter to the field that needs to\n be updated. */\n topic =\n service\n .courses()\n .topics()\n .patch(courseId, topicId, topicToUpdate)\n .set(\"updateMask\", \"name\")\n .execute();\n\n /* Prints the updated topic. */\n System.out.printf(\"Topic '%s' updated.\\n\", topic.getName());\n} catch (GoogleJsonResponseException e) {\n // TODO(developer) - handle error appropriately\n GoogleJsonError error = e.getDetails();\n if (error.getCode() == 404) {\n System.out.printf(\"The courseId or topicId does not exist: %s, %s.\\n\", courseId, topicId);\n } else {\n throw e;\n }\n} catch (Exception e) {\n throw e;\n}\nreturn topic;\n```\n\n### Python\n\n topic = {\n \"name\": \"New Topic Name\"\n }\n response = service.courses().topics().patch(\n courseId=\u003ccourse ID or alias\u003e,\n id=\u003ctopic ID\u003e,\n updateMask=\"name\",\n body=topic).execute()\n print('{0} ({1})'.format(response['name'], response['topicId']))\n\nThe `Topic` `id` and `updateTime` fields are server-generated and can't be\nupdated with the API.\n| **Note:** If you patch a `Topic` without changing the `name`, an `HTTP 403\n| Forbidden` status code is returned.\n\nDelete a Topic\n--------------\n\nYou can delete an existing `Topic` with the [`topics.delete()`](/workspace/classroom/reference/rest/v1/courses.topics/delete) method, as shown\nin the following sample: \n\n### Java\n\nclassroom/snippets/src/main/java/DeleteTopic.java \n[View on GitHub](https://github.com/googleworkspace/java-samples/blob/main/classroom/snippets/src/main/java/DeleteTopic.java) \n\n```java\ntry {\n service.courses().topics().delete(courseId, topicId).execute();\n} catch (GoogleJsonResponseException e) {\n // TODO(developer) - handle error appropriately\n throw e;\n} catch (Exception e) {\n throw e;\n}\n```"]]