Merge a category into another (console plane, human authority)
POST /v1/admin/orgs/{org_id}/projects/{project_id}/categories/{id}/merge
Merge the path category (the loser) into into_category_id (the survivor), repointing all rr_/rule_ references BY cat_ id and setting merged_into on the loser in ONE transaction (D9/D10), plus a merge transition + audit/undo row. A cross-tenant or unknown into_category_id is 404 (never a cross-customer merge); merging into itself is 400. Console-only.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Request Body required
Section titled “Request Body required ”Merge the path category (the loser) into into_category_id (the survivor), repointing all rr_/rule_ references by cat_ id in one transaction (D9/D10). A cross-tenant or unknown into_category_id is 404 (never a cross-customer merge).
object
The survivor category id (cat_…).
Responses
Section titled “ Responses ”Merged.
The survivor category plus how many references were repointed by the merge.
object
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
Logical accepted messages created in the last 7 days in the authorized project.
Logical accepted messages created in the last 30 days in the authorized project.
Logical accepted messages created in the last 90 days in the authorized project.
Most recent accepted message creation time; absent when unused.
Current nonterminal reviews across composers in the authorized project.
Active category rules visible in the authorized project; excludes retired and superseded versions.
Opaque category id (cat_…).
Survivor category id when this one was merged/soft-deleted (cat_…).
Human lock pinning the category at supervised (no live auto-send; D16).
Clean human-approve-as-is count toward the maturity gate (D16).
Human edit/reject count in a graduated category toward drift auto-demote (K; §7).
When the category was last graduated (omitted if never).
Who last graduated it (‘human:’); empty if never/demoted.
Invalid request.
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-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.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.
Missing or invalid credential.
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-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.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.
Authenticated but lacking the required scope, or out of quota.
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-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.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.
Resource not found.
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-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.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.
Resource conflict (e.g. a duplicate entry).
The canonical error envelope. error is a stable machine code.
object
Stable error code (e.g. unauthorized, forbidden, not_found, invalid, quota_exceeded, rate_limited).
Example
forbiddenHuman-readable detail (never leaks internals).
Example
missing required scopeMachine-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.
Consumed plus reserved units.
Requested additional units.
Next UTC usage-period boundary; pending reservations survive this boundary.