---
title: "Create a new topic (or return existing on case-insensitive name match)"
method: POST
path: "/topics"
tags: ["Topics"]
---

# Create a new topic (or return existing on case-insensitive name match)

`POST /topics`

## Request

- Base URL: `https://api.production.yourmedley.com`
- URL: `https://api.production.yourmedley.com/topics`
- Auth: HTTP bearer

Adds a new topic to the global catalog. The topics.name column is case-insensitive
(citext) and unique — if a topic with the given name already exists (any case),
the existing row is returned with HTTP 200 and `meta.created = false` so the
client can show a "Topic already exists — selected" toast (MED-832 AC7).

Newly created topics return HTTP 201 with `meta.created = true`. The new topic
is is_active = true and gets display_order = MAX + 1.

## Request body

- object
  - `name` string, required: Topic name. Whitespace is trimmed. Empty string is rejected.

## Response `200`

Existing topic returned (case-insensitive name match)

- object
  - `success` boolean
  - `data` Topic
    - `id` string, uuid: Unique identifier
    - `name` string: Topic name
    - `description` string, nullable: Description of the topic
    - `display_order` integer, nullable: Optional custom sort order
    - `is_active` boolean: Whether the topic is active
    - `created_at` string, date-time
    - `updated_at` string, date-time
  - `meta` object
    - `created` boolean

## Other responses

- `201`: New topic created
- `401`: Unauthorized
- `422`: Validation failed (empty name, missing name, name too long)

---

[API](https://skmtc.dev/withmedley/apis/medley-api.md) - [All operations](https://skmtc.dev/withmedley/apis/medley-api/llms.txt) - [OpenAPI document](https://skmtc.dev/withmedley/apis/medley-api/revisions/40aaac5ca6bd?raw)
