> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bodhveda.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a catalog entry

> Create a single catalog entry. **Strict**: an entry for the same `(channel, topic, event, medium)` returns `409`. Use `PATCH /preferences/{preference_id}` to change an existing entry, or `PUT /preferences` to set a whole catalog.

Add one entry to your project's preference catalog. **Strict** — creating an entry whose `(channel, topic, event, medium)` already exists returns `409`. To change an existing entry use [update](/api-reference/endpoint/preferences/update-project-preference); to declaratively set a whole catalog use [bulk upsert](/api-reference/endpoint/preferences/upsert-project-preferences).


## OpenAPI

````yaml POST /preferences
openapi: 3.0.3
info:
  title: Bodhveda Notifications API
  version: '1.0'
  description: API for sending notifications to recipients or broadcasting to all.
servers: []
security: []
paths:
  /preferences:
    post:
      tags:
        - Project Preferences
      summary: Create a catalog entry
      description: >-
        Create a single catalog entry. **Strict**: an entry for the same
        `(channel, topic, event, medium)` returns `409`. Use `PATCH
        /preferences/{preference_id}` to change an existing entry, or `PUT
        /preferences` to set a whole catalog.
      operationId: createProjectPreference
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProjectPreferencePayload'
      responses:
        '201':
          description: Catalog entry created.
          content:
            application/json:
              examples:
                Created:
                  summary: Created Response
                  value:
                    message: Project preference created
                    data:
                      id: 12
                      project_id: 1
                      target:
                        channel: digest
                        topic: none
                        event: sent
                      medium: email
                      default_enabled: true
                      label: Daily digest
                      created_at: '2025-11-07T05:31:56Z'
                      updated_at: '2025-11-07T05:31:56Z'
        '409':
          description: An entry for this `(channel, topic, event, medium)` already exists.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - BearerAuthWithAPIKeyWithFullAcessScope: []
      x-codeSamples:
        - lang: curl
          source: |-
            curl -X POST https://api.bodhveda.com/preferences \
              -H "Authorization: Bearer bv_xxxxxxxxx" \
              -H "Content-Type: application/json" \
              -d '{
                "channel": "digest",
                "topic": "none",
                "event": "sent",
                "medium": "email",
                "label": "Daily digest",
                "default_enabled": true
              }'
components:
  schemas:
    CreateProjectPreferencePayload:
      type: object
      properties:
        channel:
          type: string
          description: Broad category (e.g. "digest").
        topic:
          type: string
          description: >-
            Subcategory. `any` matches all topics under the channel/event;
            `none` is the base channel/event.
        event:
          type: string
          description: Event that triggers the notification (e.g. "sent").
        medium:
          type: string
          description: The medium this catalog entry gates. Defaults to `in_app`.
          enum:
            - in_app
            - email
          default: in_app
        label:
          type: string
          description: Human-readable label.
        default_enabled:
          type: boolean
          description: >-
            The project-level default for recipients who have set no preference
            of their own.
      required:
        - channel
        - topic
        - event
        - label
        - default_enabled
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        details:
          type: string
  securitySchemes:
    BearerAuthWithAPIKeyWithFullAcessScope:
      type: http
      scheme: bearer
      bearerFormat: APIKey
      description: >-
        Bearer authentication header of the form `Bearer bv_xxxxxxxxx`, where
        `bv_xxxxxxxxx` is your **API Key** with `Full access` scope.

````