---
title: "Create a custom domain"
method: POST
path: "/v1/graph/domains"
tags: ["v1", "Graph Domains"]
---

# Create a custom domain

`POST /v1/graph/domains`

## Request body

- GraphDomainCreate
  - `domain_id` string, required — Custom id, e.g. 'acme:support_tickets:1.0.0'.
  - `name` string, required — Human-readable domain name.
  - `description` string, required — What this domain models.
  - `signals` SignalField[], required — Per-domain signal definitions.
    - `name` string, required — Snake_case signal identifier.
    - `description` string, required — Human prompt used by extractor.
    - `weight` number — Relative weight in the fusion.
    - `frequency_hz` number, nullable — Hz band mapping (0.1 … 70.0). Auto-assigned if omitted.
    - `type` 'enum' | 'text' | 'numeric' | 'date' | 'boolean' | 'multi_value_text' — Extraction / phase type for this signal.
    - `allowed_values` string[], nullable — For type='enum': allowed vocabulary.
    - `required` boolean — Warn when missing at extract time.
  - `signal_multipliers` object, nullable — Domain-level default signal weight multipliers. Applied automatically on every rerank/search request for this domain (unless the caller supplies their own signal_multipliers, which take priority). Keys are field names (e.g. 'key_claim') or Hz-strings (e.g. '70.0'). Values: 0.0 = disable band, 1.0 = unchanged, 2.0 = 2× boost.
  - `routing_config` GraphDomainRoutingConfig — Domain-scoped CAESAR-VIII routing overrides (stored on graph_domains).
    - `disabled_rules` string[], nullable — Global SciFact routing rule names to skip for this domain (e.g. 'DANGER_LOW_RSG_LOW_PHI').
    - `enabled_rule_packs` string[], nullable — Named domain rule packs to run after global rules (e.g. 'cosqa_caesar8_v2').
    - `threshold_overrides` object, nullable — Optional CaesarConfig field overrides keyed by threshold name (e.g. {'cmas_c4_trust_jaccard_threshold': 0.95}).
    - `enhanced_initial_source` string, nullable — CAESAR-VIII initial source for the CE-on path. Domain defaults may pin 'caesar4_5_v4a' on code_search for public enhanced; public max overrides to 'caesar7' unless this field is set.
    - `holographic_floor` boolean, nullable — When true, never return a ranking worse than max(v4a, baseline) unless CE gate (ce_gate_min_phi) passes.
    - `ce_gate_min_phi` number, nullable — Minimum phi to allow caesar7/baseline_rerank to bypass holographic floor.
    - `egr_lambda_ce` number, nullable — Stacked EGR entailment fusion weight (0–1). Lower for code domains.
    - `caesar4_source` string, nullable — Which ranking is exposed as rankings['caesar4'] to CAESAR-VIII rules (c4_c7_diverge, etc.). Accepts 'v4a' (default — alias to family-routed v4a / v3a fallback), 'v3a' (force v3a only), or 'legacy' (SKIP the alias; keep the original Jaccard / trust-score selection at rankings['caesar4'] and stash a copy at rankings['_caesar4_legacy']). Use 'legacy' to A/B C-VIII rules against the original SciFact calibration semantics. Label-free in all modes.
  - `catalog_config` DomainCatalogConfig — Catalog settings on a domain.
    - `enabled` boolean — Whether to auto-accumulate signals on transform.
    - `refresh_every_n` integer — Run LLM clustering after this many buffered entries.

## Response `201`

Successful Response

- GraphDomainSpec
  - `domain_id` string, required
  - `name` string, required
  - `description` string, required
  - `signals` SignalField[], required
    - `name` string, required — Snake_case signal identifier.
    - `description` string, required — Human prompt used by extractor.
    - `weight` number — Relative weight in the fusion.
    - `frequency_hz` number, nullable — Hz band mapping (0.1 … 70.0). Auto-assigned if omitted.
    - `type` 'enum' | 'text' | 'numeric' | 'date' | 'boolean' | 'multi_value_text' — Extraction / phase type for this signal.
    - `allowed_values` string[], nullable — For type='enum': allowed vocabulary.
    - `required` boolean — Warn when missing at extract time.
  - `signal_multipliers` object, nullable — Domain-level default signal multipliers (see GraphDomainCreate).
  - `routing_config` GraphDomainRoutingConfig — Domain-scoped CAESAR-VIII routing overrides (stored on graph_domains).
    - `disabled_rules` string[], nullable — Global SciFact routing rule names to skip for this domain (e.g. 'DANGER_LOW_RSG_LOW_PHI').
    - `enabled_rule_packs` string[], nullable — Named domain rule packs to run after global rules (e.g. 'cosqa_caesar8_v2').
    - `threshold_overrides` object, nullable — Optional CaesarConfig field overrides keyed by threshold name (e.g. {'cmas_c4_trust_jaccard_threshold': 0.95}).
    - `enhanced_initial_source` string, nullable — CAESAR-VIII initial source for the CE-on path. Domain defaults may pin 'caesar4_5_v4a' on code_search for public enhanced; public max overrides to 'caesar7' unless this field is set.
    - `holographic_floor` boolean, nullable — When true, never return a ranking worse than max(v4a, baseline) unless CE gate (ce_gate_min_phi) passes.
    - `ce_gate_min_phi` number, nullable — Minimum phi to allow caesar7/baseline_rerank to bypass holographic floor.
    - `egr_lambda_ce` number, nullable — Stacked EGR entailment fusion weight (0–1). Lower for code domains.
    - `caesar4_source` string, nullable — Which ranking is exposed as rankings['caesar4'] to CAESAR-VIII rules (c4_c7_diverge, etc.). Accepts 'v4a' (default — alias to family-routed v4a / v3a fallback), 'v3a' (force v3a only), or 'legacy' (SKIP the alias; keep the original Jaccard / trust-score selection at rankings['caesar4'] and stash a copy at rankings['_caesar4_legacy']). Use 'legacy' to A/B C-VIII rules against the original SciFact calibration semantics. Label-free in all modes.
  - `catalog_config` DomainCatalogConfig — Catalog settings on a domain.
    - `enabled` boolean — Whether to auto-accumulate signals on transform.
    - `refresh_every_n` integer — Run LLM clustering after this many buffered entries.
  - `catalog` DomainCatalog — Curated summary of what's in a domain's frequency space.
    - `entity_clusters` CatalogEntityCluster[]
      - `label` string, required — LLM-chosen canonical label for this cluster.
      - `members` string[] — Raw signal values merged into this cluster.
      - `count` integer — Total occurrences across all transforms.
    - `relationship_patterns` CatalogRelationshipPattern[]
      - `label` string, required — Canonical label (e.g. 'Causal', 'Preventive').
      - `members` string[] — Raw relationship values in this cluster.
      - `count` integer — Total occurrences.
    - `domain_distribution` object — Signal band name -> total doc count.
    - `signal_value_counts` object — Per-band raw value counts, e.g. {'domain': {'Health': 500, 'Tech': 200}}.
    - `total_documents` integer — Total transforms processed.
    - `last_refreshed` string, nullable — ISO timestamp of last LLM clustering run.
    - `last_updated` string, nullable — ISO timestamp of last buffer append.
  - `catalog_buffer` CatalogBufferEntry[] — Buffered raw signals awaiting LLM clustering (internal).
    - `signals` object, required — Band name -> extracted value.
    - `timestamp` string, required — ISO timestamp of the transform call.
  - `builtin` boolean — True for built-in domains shipped with Papr (read-only).
  - `created_at` string, nullable
  - `owner_user_id` string, nullable
  - `owner_workspace_id` string, nullable — Workspace that owns this domain. Domains are scoped to workspace when set.
  - `owner_organization_id` string, nullable — Organization that owns this domain.
  - `owner_namespace_id` string, nullable — Namespace this domain belongs to, if any.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/papr-ai/apis/papr-memory-api.md) · [All operations](https://skmtc.net/papr-ai/apis/papr-memory-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/papr-ai/papr-memory-api/versions/b553be9aad37/schema)
