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

# Create group

> Register a new group on the org. Returns the persisted row
including the server-generated `id`.



## OpenAPI

````yaml https://api.staging.xtrace.ai/openapi.public.json post /v1/groups
openapi: 3.1.0
info:
  title: XTrace Vec DB
  description: XTrace API
  version: 1.0.0
servers:
  - url: https://api.production.xtrace.ai
    description: Production
security:
  - ApiKeyHeader: []
  - BearerToken: []
paths:
  /v1/groups:
    post:
      tags:
        - groups
      summary: Create group
      description: |-
        Register a new group on the org. Returns the persisted row
        including the server-generated `id`.
      operationId: create_group_v1_groups_post
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupCreateRequest'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
        '422':
          description: >-
            `detail.code = "groups_quota_exceeded"` — org is at
            `MAX_GROUPS_PER_ORG` active groups.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      x-codeSamples:
        - lang: typescript
          label: TypeScript SDK
          source: |
            import { MemoryClient } from '@xtraceai/memory';

            const client = new MemoryClient({
              apiKey: process.env.XTRACE_API_KEY!,
              orgId:  process.env.XTRACE_ORG_ID!,
            });

            const group = await client.groups.create({
              name: 'Tokyo trip 2026',
              prompt: 'Facts about the Tokyo trip: flights, hotels, restaurants, dietary needs.',
            });
            console.log(group.id); // grp_…  — pass this in ingest `group_ids`
components:
  schemas:
    GroupCreateRequest:
      properties:
        name:
          type: string
          maxLength: 120
          minLength: 1
          title: Name
          description: Human-readable label, shown in UI. Not used by the classifier.
          examples:
            - Tokyo trip 2026
        prompt:
          anyOf:
            - type: string
              maxLength: 2000
              minLength: 1
            - type: 'null'
          title: Prompt
          description: >-
            Free-text criterion the ingest classifier reads to decide whether an
            extracted memory belongs in this group. Describe what belongs, not
            how the classifier should behave. Omit (or send null) to make the
            group a catch-all: every extracted memory judged shareable (not
            personal) is tagged with it, with no per-group matching.
          examples:
            - >-
              Facts about the Tokyo trip in May 2026: dates, flights, hotels,
              restaurants, dietary preferences for this trip.
      type: object
      required:
        - name
      title: GroupCreateRequest
      description: |-
        POST /v1/groups — register a new group.

        The ``prompt`` is the instruction the ingest classifier reads on
        every ingest to decide whether an extracted memory belongs in this
        group. Write it as a description of *what* belongs, not a chat
        instruction — e.g. "Facts about the Tokyo trip: dates, flights,
        hotels, dietary preferences for Tokyo", not "tag this if you think
        it should be tagged".

        Omit ``prompt`` (or send ``null``) to create a catch-all group:
        every extracted memory the classifier judges shareable (not
        personal) is tagged with it — no per-group matching. Sending an
        empty string is still a 422; only omission/null means catch-all,
        so a blank field from a buggy client can't silently create one.
    Group:
      properties:
        object:
          type: string
          const: group
          title: Object
          description: Constant discriminator for the resource type.
          default: group
        id:
          type: string
          title: Id
          description: Stable group id of the form `grp_<32-hex-chars>`.
          examples:
            - grp_a1b2c3d4e5f6071829304a5b6c7d8e9f
        name:
          type: string
          title: Name
          description: Human-readable label.
        prompt:
          anyOf:
            - type: string
            - type: 'null'
          title: Prompt
          description: >-
            Classifier criterion. Read by the ingest pipeline on every request
            that includes this group's id in `group_ids`. `null` marks a
            catch-all group: every extracted memory judged shareable (not
            personal) is tagged with it.
        status:
          type: string
          enum:
            - active
            - archived
          title: Status
          description: >-
            `active` groups are tagged on new ingests. `archived` groups still
            surface on search (rows tagged with the id stay reachable) but the
            ingest classifier rejects them.
        created_at:
          type: string
          format: date-time
          title: Created At
          description: ISO-8601 timestamp the group was registered.
        updated_at:
          anyOf:
            - type: string
            - type: 'null'
          format: date-time
          title: Updated At
          description: ISO-8601 timestamp of the most recent edit.
      type: object
      required:
        - id
        - name
        - status
        - created_at
      title: Group
      description: |-
        Wire shape of a group. ``id`` is the opaque handle that goes
        into ``IngestRequest.group_ids`` and into search ``filters``.
    ErrorEnvelope:
      properties:
        detail:
          $ref: '#/components/schemas/ErrorDetail'
      type: object
      required:
        - detail
      title: ErrorEnvelope
      description: |-
        Standard error body for non-2xx responses raised by the memory
        API. Pydantic field-validation failures (422) use the FastAPI-
        default ``HTTPValidationError`` shape instead, where ``detail`` is
        an array of per-field error entries — switch on the response
        status code to pick the right shape.
    ErrorDetail:
      properties:
        code:
          type: string
          title: Code
          description: >-
            Stable error identifier. Switch on this rather than parsing the
            message. Common values: `invalid_request`, `invalid_messages`,
            `memory_not_found`, `job_not_found`, `immutable_field`,
            `reserved_field`, `empty_text_field`, `missing_user_id`,
            `missing_conv_id`, `unsupported_include_option`, `cursor_mismatch`,
            `unauthorized`, `forbidden`, `rate_limited`, `delete_failed`,
            `search_failed`, `ingest_failed`, `server_error`.
          examples:
            - memory_not_found
        message:
          type: string
          title: Message
          description: Human-readable summary; safe to log but not safe to switch on.
          examples:
            - Memory 0fa1c0e6-... not found
      type: object
      required:
        - code
        - message
      title: ErrorDetail
      description: |-
        Inner ``detail`` block on every non-2xx response raised by a
        memory-API route handler. ``code`` is the stable identifier
        clients should switch on; ``message`` is a sanitized human-
        readable summary.
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
      description: 'Long-lived org API key. Alternative: `Authorization: Bearer <key>`.'
    BearerToken:
      type: http
      scheme: bearer
      bearerFormat: Token
      description: 'Long-lived API key sent as `Authorization: Bearer <api-key>`.'

````