Skip to content

Consolidate duplicate new categories

POST
/v1/categories/{id}/merge

The composing agent judges semantic equivalence. Both categories must be active, agent-authored, shared and supervised, created within 24 hours, with matching policy and exclusive use inside the caller’s project. The server checks eligibility transactionally. Human curation and broader merges use the console. Preserves rules and reviews, invalidates composition stamps, and durably asks affected composers to recheck; never approves or sends. On conflict reread both categories and follow merged_into before retrying.

id
required
string
object
into_category_id
required

Surviving category ID.

string
rationale
required

Why the descriptions describe the same reusable message purpose; maximum 2000 UTF-8 bytes.

string
>= 1 characters <= 2000 characters

Categories consolidated and pending rechecks scheduled.

The survivor category plus how many references were repointed by the merge.

object
category
required

A category (cat_…) in the registry (Review Loop, D9/D10). name + description are the skill-style metadata an agent fuzzy-matches against (NO LLM on our side; the agent does the matching). Categories are CUSTOMER-scoped and agent-attributed; nothing keys on the name (renames never break a reference).

object
message_count_7d

Logical accepted messages created in the last 7 days in the authorized project.

integer
message_count_30d

Logical accepted messages created in the last 30 days in the authorized project.

integer
message_count_90d

Logical accepted messages created in the last 90 days in the authorized project.

integer
last_used_at

Most recent accepted message creation time; absent when unused.

string format: date-time
pending_review_count

Current nonterminal reviews across composers in the authorized project.

integer
active_rule_count

Active category rules visible in the authorized project; excludes retired and superseded versions.

integer
id
required

Opaque category id (cat_…).

string
name
required
string
description
required
string
scope
required
string
Allowed values: org_shared agent_private
state
required
string
Allowed values: supervised auto_notify auto_silent
merged_into

Survivor category id when this one was merged/soft-deleted (cat_…).

string
created_by_agent_id
string
author_kind
required
string
Allowed values: agent human connection
rule_high_water
required
integer
rules_version
required
integer
never_graduate

Human lock pinning the category at supervised (no live auto-send; D16).

boolean
clean_approval_count

Clean human-approve-as-is count toward the maturity gate (D16).

integer
drift_count

Human edit/reject count in a graduated category toward drift auto-demote (K; §7).

integer
graduated_at

When the category was last graduated (omitted if never).

string format: date-time
graduated_by

Who last graduated it (‘human:’); empty if never/demoted.

string
created_at
string format: date-time
updated_at
string format: date-time
review_requests_repointed
required
integer
writing_rules_repointed
required
integer

Invalid request.

The canonical error envelope. error is a stable machine code.

object
error
required

Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).

string
Example
forbidden
message

Human-readable detail (never leaks internals).

string
Example
missing required scope
reason

Machine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.

string
used

Consumed plus reserved units.

integer format: int64
delta

Requested additional units.

integer format: int64
limit
integer format: int64
remaining
integer format: int64
consumed
integer format: int64
reserved
integer format: int64
next_reset_at

Next UTC usage-period boundary; pending reservations survive this boundary.

string format: date-time
upgrade_required
boolean

Missing or invalid credential.

The canonical error envelope. error is a stable machine code.

object
error
required

Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).

string
Example
forbidden
message

Human-readable detail (never leaks internals).

string
Example
missing required scope
reason

Machine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.

string
used

Consumed plus reserved units.

integer format: int64
delta

Requested additional units.

integer format: int64
limit
integer format: int64
remaining
integer format: int64
consumed
integer format: int64
reserved
integer format: int64
next_reset_at

Next UTC usage-period boundary; pending reservations survive this boundary.

string format: date-time
upgrade_required
boolean

Authenticated but lacking the required scope, or out of quota.

The canonical error envelope. error is a stable machine code.

object
error
required

Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).

string
Example
forbidden
message

Human-readable detail (never leaks internals).

string
Example
missing required scope
reason

Machine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.

string
used

Consumed plus reserved units.

integer format: int64
delta

Requested additional units.

integer format: int64
limit
integer format: int64
remaining
integer format: int64
consumed
integer format: int64
reserved
integer format: int64
next_reset_at

Next UTC usage-period boundary; pending reservations survive this boundary.

string format: date-time
upgrade_required
boolean

Resource not found.

The canonical error envelope. error is a stable machine code.

object
error
required

Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).

string
Example
forbidden
message

Human-readable detail (never leaks internals).

string
Example
missing required scope
reason

Machine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.

string
used

Consumed plus reserved units.

integer format: int64
delta

Requested additional units.

integer format: int64
limit
integer format: int64
remaining
integer format: int64
consumed
integer format: int64
reserved
integer format: int64
next_reset_at

Next UTC usage-period boundary; pending reservations survive this boundary.

string format: date-time
upgrade_required
boolean

Resource conflict (e.g. a duplicate entry).

The canonical error envelope. error is a stable machine code.

object
error
required

Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).

string
Example
forbidden
message

Human-readable detail (never leaks internals).

string
Example
missing required scope
reason

Machine-readable quota reason. inbox_limit_exceeded means billing account inbox capacity across all organizations and projects sharing that account; enrollment_token_mailbox_budget_exhausted means the enrollment key lifetime creation allowance. Read message for recovery; inbox counts are separate from sending quotas.

string
used

Consumed plus reserved units.

integer format: int64
delta

Requested additional units.

integer format: int64
limit
integer format: int64
remaining
integer format: int64
consumed
integer format: int64
reserved
integer format: int64
next_reset_at

Next UTC usage-period boundary; pending reservations survive this boundary.

string format: date-time
upgrade_required
boolean