PPactDocs
Sales

Territories

Define named, jurisdiction-pinned partitions of a tenant's records and members, auto-assign records with rules, and transfer books of business.

Territories

A territory is Pact's unit of Salesforce-style sharing: a named partition of a tenant's records and members. Each territory pins a single legal jurisdiction, which lets the cross-territory consent evaluator (core.consent_multi_territory) pick the strictest requirement across every territory a record is linked to. Territory CRUD is under /v1/territories; auto-assignment rules are under /v1/territory-rules. Both are gated by the admin module and enforce permission checks.

Live

Backed by core.territories (CRUD, membership, hierarchy, transfers) and core.territory_rules (auto-assignment). Every helper requires an explicit tenant_id derived from the auth context — never from a request body.

Jurisdictions

Each territory carries a jurisdiction from a fixed set: GDPR, UK_GDPR, CCPA, CASL, PIPEDA, LGPD, PIPL, or OTHER (the default). This is not cosmetic — territory membership feeds core.consent_multi_territory, which resolves the strictest consent requirement when a record spans territories. An unknown jurisdiction is rejected with a validation error.

Hierarchy and membership

Territories form a tree via parent_territory_id. Members are assigned with one of three territory roles: owner, member, or viewer. The engine exposes descendant resolution (descendants) and a full territory_tree so a manager's scope can expand to a territory plus everything beneath it. The visibility filter that turns membership into actual record-level filtering lives in core.visibility.scope; territories own only the partition definition.

CRUD endpoints

Method & pathPurpose
GET /v1/territoriesList territories
POST /v1/territoriesCreate (name, jurisdiction, optional parent, slug)
GET /v1/territories/{id}Fetch one
PATCH /v1/territories/{id}Update
DELETE /v1/territories/{id}Soft-delete
GET /v1/territories/{id}/membersList members
POST /v1/territories/{id}/membersAssign a user
DELETE /v1/territories/{id}/members/{user_id}Unassign
GET /v1/territories/meTerritories the caller belongs to

Auto-assignment rules

/v1/territory-rules defines rules that link an incoming record to a territory automatically. You can dry-run a record against the ruleset before committing:

Method & pathPurpose
GET /v1/territory-rulesList rules
POST /v1/territory-rulesCreate a rule
PATCH /v1/territory-rules/{rule_id}Update
DELETE /v1/territory-rules/{rule_id}Soft-delete
POST /v1/territory-rules/previewDry-run a record against the rules
POST /v1/territory-rules/{record_type}/{record_id}/applyLink the record now

Transferring a book of business

When a rep changes territory, core.territories provides preview_transfer to show what would move and transfer_records to reassign records in bulk, plus territory_performance for per-territory rollups. Transfers are tenant-scoped and permission-gated like every other mutation here.