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

# Create a coaching catalogue directory

> Creates a directory (page) in the coaching portal catalogue. A directory nests other directories through `tags_sub`, lists coaching sessions through `tags_interview_set_filter`, and can replace the default grid with a custom Markdown page through `content_md`. The id you choose is the catalogue URL segment and cannot be changed afterwards.



## OpenAPI

````yaml https://cool.jobmojito.com/functions/v1/openapi post /catalogue-tag-create
openapi: 3.1.0
info:
  title: JobMojito API
  version: 1.0.0
  description: >-
    Public API for JobMojito, served by Supabase Edge Functions. Authenticate
    with a Supabase JWT access token via the Authorization header.
servers:
  - url: https://cool.jobmojito.com/functions/v1
    description: Production
security: []
tags:
  - name: Interviews
    description: >-
      Create, configure and manage interview / coaching / assessment
      definitions.
  - name: Coaching catalogue
    description: >-
      Directories (pages) of the coaching portal catalogue that group coaching
      sessions and carry custom content pages.
  - name: Results
    description: >-
      Interview results, transcripts, reports, re-attempt requests and
      analytics.
  - name: Candidates
    description: List and manage candidates.
  - name: Knowledge base
    description: Upload documents used to generate knowledge-base interviews.
  - name: Resume & Form verification
    description: Pre-screen candidates from resumes and forms.
  - name: Admin
    description: >-
      Account administration — invite team/coaching users, manage sub-merchants
      and avatar templates.
paths:
  /catalogue-tag-create:
    post:
      tags:
        - Coaching catalogue
      summary: Create a coaching catalogue directory
      description: >-
        Creates a directory (page) in the coaching portal catalogue. A directory
        nests other directories through `tags_sub`, lists coaching sessions
        through `tags_interview_set_filter`, and can replace the default grid
        with a custom Markdown page through `content_md`. The id you choose is
        the catalogue URL segment and cannot be changed afterwards.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CatalogueTagCreateRequest'
      responses:
        '200':
          description: Directory created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CatalogueTagCreateResponse'
        '401':
          description: Missing, expired or invalid access token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            A directory with this id already exists. Use catalogue-tag-update to
            change it.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: >-
            Validation error (malformed id, unknown enum value, unresolved
            parent_tag).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Server error (includes authorization failures).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []
components:
  schemas:
    CatalogueTagCreateRequest:
      type: object
      properties:
        id:
          type: string
          minLength: 1
          pattern: ^[a-z0-9]+(?:(?:-|_)+[a-z0-9]+)*$
          description: >-
            Directory id — also the catalogue URL segment (/catalogue/<id>) and
            the value other directories reference in their `tags_sub`. Lowercase
            letters, digits and single - or _ separators. Convention is to end
            language-specific directories with the language code, e.g.
            `sales-coaching-en`.
          example: sales-coaching-en
        name:
          type: string
          minLength: 1
          description: >-
            Display name of the directory, shown as the page title and on its
            card.
          example: Sales coaching
        description:
          type: string
          nullable: true
          description: Short description shown on the directory card.
          example: Practice discovery, objection handling and closing.
        mojito_language_code:
          type: string
          nullable: true
          enum:
            - ar
            - bg
            - zh
            - hr
            - cs
            - da
            - nl
            - en
            - fil
            - fi
            - fr
            - de
            - el
            - hi
            - hu
            - id
            - it
            - ja
            - ko
            - ms
            - 'no'
            - pl
            - pt
            - br
            - ro
            - ru
            - sk
            - es
            - sv
            - ta
            - th
            - tr
            - uk
            - vi
          description: >-
            Language of the directory (one of the platform-languages.json
            codes). The catalogue groups directories by language; defaults to
            `en` when omitted.
          example: en
        visibility:
          type: string
          nullable: true
          enum:
            - public
            - merchant_public
            - merchant_invite
            - merchant_unlisted
          description: >-
            Who can see the catalogue directory. Options — `public`: Shared
            across every merchant. Platform admins only — a merchant caller is
            rejected by row-level security. | `merchant_public`: Listed in the
            merchant's own catalogue — the normal choice. | `merchant_invite`:
            Owned by the merchant but not listed; reachable only for invited
            users. | `merchant_unlisted`: Owned by the merchant but not listed;
            reachable only via a direct link..
          example: merchant_public
        status:
          type: string
          nullable: true
          enum:
            - draft
            - active
            - archived
          description: >-
            Lifecycle status of the catalogue directory. Options — `draft`: Not
            published — the directory exists but is not served to visitors. |
            `active`: Published and served in the catalogue. | `archived`:
            Retired — kept for reference but no longer served..
          example: active
        cover_image_url:
          type: string
          nullable: true
          description: Cover image URL shown on the directory card.
        coach_plan:
          type: string
          nullable: true
          enum:
            - demo
            - screening
            - 2nd
            - 3rd
            - closing
            - job-specific
            - other
          description: >-
            Coaching-plan stage this item belongs to, used by the coaching-plan
            progress view. Omit/null to leave it out of any plan. Options —
            `demo`: Demo session. | `screening`: Screening-interview practice. |
            `2nd`: Second-interview practice. | `3rd`: Third-interview practice.
            | `closing`: Closing / salary-negotiation practice. |
            `job-specific`: Job-specific coaching. | `other`: Anything that does
            not fit the other buckets..
          example: screening
        tags_sub:
          type: array
          nullable: true
          items:
            type: string
          description: >-
            Ids of the directories nested under this one, in display order.
            Replaces the whole list — send the full set, not just the additions.
            A referenced directory only appears if it exists and is visible to
            the viewer.
          example:
            - sales-coaching-objections-en
            - sales-coaching-closing-en
        tags_interview_set_filter:
          type: array
          nullable: true
          items:
            type: string
          description: >-
            Tag filter selecting which coaching sessions this directory lists: a
            session appears when its own `tags` contain EVERY tag here (an AND,
            not an OR). Only `active` coaching/persona sessions with visibility
            `public` or `merchant_public` are listed. Set the matching tags on
            the session with the create-interview / job-interview-update `tags`
            field.
          example:
            - sales
            - objection-handling
        content_md:
          type: string
          nullable: true
          description: >-
            Markdown for a custom directory page. When set (even as an empty
            string) the markdown replaces the default grid and decides the
            layout itself; null renders the plain grid of sub-directories and
            sessions. Alongside normal Markdown you can place these directives,
            each ALONE on its own line: `[plan-progress]` (the learner's
            coaching-plan progress), `[directory:<tag-id>]` (a card for one
            sub-directory), `[session:<interview-id>]` (a card for one session),
            `[sessions]` (every session in this directory), `[sessions:<term>]`
            (sessions matching a term), `[sessions:filter=<term>,limit=<n>]` (a
            filtered, capped list). A directive on a line with other text is
            rendered as ordinary text.
          example: |
            ## Sales coaching

            Pick a session to practise with.

            [sessions:filter=objection-handling,limit=6]
        parent_tag:
          type: string
          nullable: true
          description: >-
            Id of an existing directory to nest this new one under: the new id
            is appended to that directory's `tags_sub`. Omit to create a
            top-level directory (reachable via a direct link, or by adding it to
            another directory later).
          example: home-employee-en
        merchant_id:
          type: string
          nullable: true
          description: >-
            Merchant that owns the directory. Admin / sub-merchant callers only;
            otherwise taken from your token.
          example: 28106cba-1c27-4e53-b149-32113e5e8e31
      required:
        - id
        - name
    CatalogueTagCreateResponse:
      type: object
      properties:
        id:
          type: string
          description: Id of the created directory.
          example: sales-coaching-en
        merchant_id:
          type: string
          nullable: true
          description: Owning merchant id. Null for a platform-wide (`public`) directory.
        parent_tag:
          type: string
          nullable: true
          description: >-
            The directory this one was nested under, when `parent_tag` was
            supplied.
        catalogue_url:
          type: string
          nullable: true
          description: >-
            Public URL of the directory page, when the merchant has a
            coaching-portal domain configured. Null otherwise.
          example: https://coaching.example.com/catalogue/sales-coaching-en
      required:
        - id
        - merchant_id
        - parent_tag
        - catalogue_url
      description: The created catalogue directory.
    Error:
      type: object
      properties:
        error:
          type: string
          example: Field is required.
        name:
          type: string
          example: interview_result_id
      required:
        - error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'Supabase JWT — `Authorization: Bearer <token>`.'

````