---
title: "Create a segment"
method: POST
path: "/api/v1/ackdb/observe/segments"
tags: ["ackDB"]
---

# Create a segment

`POST /api/v1/ackdb/observe/segments`

## Request

- Base URL: `http://localhost:3009`
- URL: `http://localhost:3009/api/v1/ackdb/observe/segments`
- Auth: HTTP bearer

Creates a saved Segment from a name plus optional description, entityKind, filter, sort, and columns. The owner is stamped server-side from the caller's JWT (a client-supplied owner is ignored) and the segment is private to the owner by default (#284).

## Request body

- object
  - `name` string, required
  - `description` string
  - `entityKind` 'company' | 'contact' | 'person'
  - `filter` AckdbObserveFilterGroup: A boolean group combining child nodes with AND/OR.
    - `type` 'group', required
    - `op` 'and' | 'or', required: How children are combined.
    - `children` AckdbObserveFilter[], required
      - union: Recursive Observe filter DSL. A node is either a boolean `group` (with `op` and a `children` array of further nodes) or a leaf condition (`trait`, `attribute`, `event`, or `event_field`). The root node is always a group. Empty groups compile to TRUE (match all).
        - object: A boolean group combining child nodes with AND/OR.
          - `type` 'group', required
          - `op` 'and' | 'or', required: How children are combined.
          - `children` AckdbObserveFilter[], required
        - object: A condition on a registered entity trait. `traitKey` is whitelisted against the field catalog; the operator must be legal for the trait's valueType.
          - `type` 'trait', required
          - `traitKey` string, required
          - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'not_contains' | 'in' | 'is_null' | 'is_not_null' | 'in_last_days' | 'more_than_days_ago' | 'in_next_days', required
          - `value` union: Scalar or array depending on the operator. Omitted for is_null/is_not_null. For in_last_days, more_than_days_ago and in_next_days, a positive integer day count on a date field, at most 36500 days.
            - string
            - number
            - boolean
            - union[]
              - …
        - object: A condition on a fixed entity attribute (name, domain, status, timestamps, event counts, sources, last activity, or source presence).
          - `type` 'attribute', required
          - `field` 'name' | 'created_at' | 'updated_at' | 'domain' | 'status' | 'event_count' | 'last_active' | 'sources' | 'source_present', required
          - `operator` 'eq' | 'neq' | 'contains' | 'not_contains' | 'in' | 'gt' | 'gte' | 'lt' | 'lte' | 'within_days' | 'is_null' | 'is_not_null' | 'in_last_days' | 'more_than_days_ago' | 'in_next_days', required
          - `value` union: Scalar or array depending on the operator. Omitted for is_null/is_not_null. For in_last_days, more_than_days_ago and in_next_days, a positive integer day count on a date field, at most 36500 days.
            - string
            - number
            - union[]
              - …
        - object: A condition on the entity's event timeline. `eventType` is source-prefixed and whitelisted against the catalog. `withinDays` bounds the lookback; `count` is used by count_gte/count_lte.
          - `type` 'event', required
          - `eventType` string, required
          - `source` string
          - `predicate` 'exists' | 'not_exists' | 'count_gte' | 'count_lte', required
          - `count` integer
          - `withinDays` integer
        - object: A condition on a promoted event-metadata field's reduced scalar value (#212). `columnKey` is the synthetic field-catalog key (`emf__<source>__<field>` for the latest value, or `…__sum` for a numeric running total) and is whitelisted against the catalog; the operator must be legal for the field's valueType (same legality as a trait of that type).
          - `type` 'event_field', required
          - `columnKey` string, required
          - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'not_contains' | 'in' | 'is_null' | 'is_not_null' | 'in_last_days' | 'more_than_days_ago' | 'in_next_days', required
          - `value` union: Scalar or array depending on the operator. Omitted for is_null/is_not_null. For in_last_days, more_than_days_ago and in_next_days, a positive integer day count on a date field, at most 36500 days.
            - string
            - number
            - boolean
            - union[]
              - …
  - `sort` AckdbSegmentSort[]
    - `field` string, required
    - `dir` 'asc' | 'desc', required
  - `columns` AckdbSegmentColumn[]
    - `field` string, required
    - `frozen` boolean
    - `width` number: Persisted column width in px (per-segment; presentation only).
  - `isDefault` boolean: Create as the default for its kind (clears any prior default). When true, name defaults to 'Default view' if omitted.
  - `baseSegmentId` string: Make this a DERIVED segment built on the given base segment: `filter` is the render-grain filter layered on top of the base's pivoted set. The base must exist and be a ROOT segment (no chains) - else 400. The render grain is an explicit `entityKind` when passed (must differ from the base's grain - else 400), otherwise the legacy company<->contact derivation. A base on the PERSON grain REQUIRES an explicit `entityKind` ('company' or 'contact') since either render grain is possible.

## Response `201`

Segment created.

- object
  - `data` AckdbSegment, required: A saved Observe Segment - config only (no data snapshot). Owned + per-user shared (#284); soft-deleted via deleted_at.
    - `id` string, required: ULID.
    - `name` string, required
    - `description` string
    - `entityKind` 'company' | 'contact' | 'person', required: Home (authoring) grain - the vocabulary the filter/sort/columns are written in. Every segment is also projectable to the other grains at read time via GET /observe/segments/{id}/results?grain=…, so this is where the filter was authored, not the only grain it can render.
    - `filter` AckdbObserveFilterGroup, required: A boolean group combining child nodes with AND/OR.
      - `type` 'group', required
      - `op` 'and' | 'or', required: How children are combined.
      - `children` AckdbObserveFilter[], required
        - union: Recursive Observe filter DSL. A node is either a boolean `group` (with `op` and a `children` array of further nodes) or a leaf condition (`trait`, `attribute`, `event`, or `event_field`). The root node is always a group. Empty groups compile to TRUE (match all).
          - object: A boolean group combining child nodes with AND/OR.
            - `type` 'group', required
            - `op` 'and' | 'or', required: How children are combined.
            - `children` AckdbObserveFilter[], required
          - object: A condition on a registered entity trait. `traitKey` is whitelisted against the field catalog; the operator must be legal for the trait's valueType.
            - `type` 'trait', required
            - `traitKey` string, required
            - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'not_contains' | 'in' | 'is_null' | 'is_not_null' | 'in_last_days' | 'more_than_days_ago' | 'in_next_days', required
            - `value` union: Scalar or array depending on the operator. Omitted for is_null/is_not_null. For in_last_days, more_than_days_ago and in_next_days, a positive integer day count on a date field, at most 36500 days.
              - …
          - object: A condition on a fixed entity attribute (name, domain, status, timestamps, event counts, sources, last activity, or source presence).
            - `type` 'attribute', required
            - `field` 'name' | 'created_at' | 'updated_at' | 'domain' | 'status' | 'event_count' | 'last_active' | 'sources' | 'source_present', required
            - `operator` 'eq' | 'neq' | 'contains' | 'not_contains' | 'in' | 'gt' | 'gte' | 'lt' | 'lte' | 'within_days' | 'is_null' | 'is_not_null' | 'in_last_days' | 'more_than_days_ago' | 'in_next_days', required
            - `value` union: Scalar or array depending on the operator. Omitted for is_null/is_not_null. For in_last_days, more_than_days_ago and in_next_days, a positive integer day count on a date field, at most 36500 days.
              - …
          - object: A condition on the entity's event timeline. `eventType` is source-prefixed and whitelisted against the catalog. `withinDays` bounds the lookback; `count` is used by count_gte/count_lte.
            - `type` 'event', required
            - `eventType` string, required
            - `source` string
            - `predicate` 'exists' | 'not_exists' | 'count_gte' | 'count_lte', required
            - `count` integer
            - `withinDays` integer
          - object: A condition on a promoted event-metadata field's reduced scalar value (#212). `columnKey` is the synthetic field-catalog key (`emf__<source>__<field>` for the latest value, or `…__sum` for a numeric running total) and is whitelisted against the catalog; the operator must be legal for the field's valueType (same legality as a trait of that type).
            - `type` 'event_field', required
            - `columnKey` string, required
            - `operator` 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'not_contains' | 'in' | 'is_null' | 'is_not_null' | 'in_last_days' | 'more_than_days_ago' | 'in_next_days', required
            - `value` union: Scalar or array depending on the operator. Omitted for is_null/is_not_null. For in_last_days, more_than_days_ago and in_next_days, a positive integer day count on a date field, at most 36500 days.
              - …
    - `sort` AckdbSegmentSort[], required
      - `field` string, required
      - `dir` 'asc' | 'desc', required
    - `columns` AckdbSegmentColumn[], required
      - `field` string, required
      - `frozen` boolean
      - `width` number: Persisted column width in px (per-segment; presentation only).
    - `isDefault` boolean, required: True when this Segment is the default view for its entity_kind (one per kind).
    - `baseSegmentId` unknown, required
    - `ownerEmail` string, required: The segment's OWNER (#284) - the creator's JWT email. null = legacy / service-created = grandfathered org-visible + editable. Stamped server-side on create (never accepted from the client) and immutable thereafter; sharing with teammates is per-member via /shares.
    - `access` 'owner' | 'edit' | 'view': The CALLER's effective role on this segment (#284). Present on single reads; drives client action gating (owner/edit may save; owner only may delete / manage shares / set default).
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required

## Other responses

- `400`: Validation error - missing name.

---

[API](https://skmtc.dev/floqer/apis/floqer-public-api.md) - [All operations](https://skmtc.dev/floqer/apis/floqer-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/floqer/apis/floqer-public-api/revisions/fce50dc07b20?raw)
