Approval Matrix
The approval matrix governs who can approve what across the platform. It combines authority profiles (what a user is allowed to do), referral rules (when to escalate), and approval records (the decision trail). The system is implemented across two API route groups: apps/api/src/routes/authority.ts for profile and rule management, and apps/api/src/routes/approvals.ts for the approval workflow.
Authority Profiles
An authority profile defines the underwriting limits for a group of users. Profiles are scoped to an organization and ordered by level (1 = most junior, 10 = most senior).
Profile Fields
| Field | Type | Description |
|---|---|---|
name | string | Profile name (e.g., "Junior Underwriter", "VP Underwriting") |
level | 1--10 | Authority tier -- higher levels can approve larger risks |
maxTiv | number | Maximum total insured value this profile can bind |
maxLimit | number | Maximum policy limit this profile can bind |
maxPremium | number | Maximum premium this profile can bind |
authorizedLobs | string[] | Lines of business the profile can underwrite |
prohibitedStates | string[] | States where this profile cannot write |
canOverride | boolean | Whether violations can be overridden (senior authority) |
constraints | JSON | Additional org-specific constraints |
CRUD Operations
# List all active profiles for an org
GET /v1/authority/profiles?orgId={orgId}
# Include inactive profiles
GET /v1/authority/profiles?orgId={orgId}&includeInactive=true
# Create a new profile
POST /v1/authority/profiles
{
"orgId": "uuid",
"name": "Senior Underwriter",
"level": 3,
"maxTiv": 5000000,
"maxLimit": 2000000,
"maxPremium": 100000,
"authorizedLobs": ["commercial_auto", "general_liability"],
"prohibitedStates": []
}
# Update a profile
PATCH /v1/authority/profiles/:id
{
"maxPremium": 150000,
"canOverride": true
}
User Assignment
Each user is assigned to exactly one active authority profile at a time. Assigning a user to a new profile automatically deactivates their previous assignment.
POST /v1/authority/profiles/:id/assign
{
"userId": "uuid",
"effectiveFrom": "2026-03-24T00:00:00Z",
"effectiveTo": "2026-12-31T23:59:59Z",
"notes": "Promoted to senior tier"
}
Assignments have optional effectiveFrom and effectiveTo dates. Expired assignments are automatically excluded from authority checks.
Profile Detail
The GET /v1/authority/profiles/:id endpoint returns the profile with its currently assigned users (userId, name, email, assignedAt, assignedBy).
Authority Check
The POST /v1/authority/check endpoint evaluates whether a specific user can perform a given action in context. This is called during submission processing to determine whether the underwriter can bind directly or must refer.
Request
{
"userId": "uuid",
"action": "bind",
"context": {
"tiv": 3500000,
"premium": 75000,
"limit": 1000000,
"lob": "commercial_auto",
"state": "FL"
}
}
Evaluation Logic
The check evaluates five dimensions against the user's assigned authority profile:
| Check | Condition | Violation Message |
|---|---|---|
| TIV | context.tiv > profile.maxTiv | "TIV $X exceeds limit of $Y" |
| Premium | context.premium > profile.maxPremium | "Premium $X exceeds limit of $Y" |
| Limit | context.limit > profile.maxLimit | "Limit $X exceeds authority of $Y" |
| LOB | context.lob not in profile.authorizedLobs | "LOB 'X' not authorized" |
| State | context.state in profile.prohibitedStates | "State 'X' is prohibited" |
Decision Rules
- Allowed: No violations found.
- Allowed (override): Violations exist, but the profile has
canOverride: true. - Allowed (refer): The action is
refer-- referrals are always permitted regardless of violations. - Denied: Violations exist and the profile cannot override.
Response
{
"data": {
"allowed": false,
"violations": ["TIV $3,500,000 exceeds limit of $2,000,000"],
"authority": {
"level": 2,
"name": "Junior Underwriter",
"canOverride": false,
"maxTiv": 2000000,
"maxPremium": 50000,
"maxLimit": 1000000
}
}
}
Authority Matrix View
The GET /v1/authority/matrix?orgId={orgId} endpoint returns the complete authority grid for an organization -- all active profiles with their assigned users and the full set of lines of business in use. This powers the matrix view in the admin UI.
{
"data": {
"profiles": [
{ "level": 1, "name": "Assistant UW", "maxTiv": 1000000, "assigned_users": [...] },
{ "level": 2, "name": "Underwriter", "maxTiv": 3000000, "assigned_users": [...] },
{ "level": 3, "name": "Senior UW", "maxTiv": 10000000, "assigned_users": [...] }
],
"lineOfBusinesses": ["commercial_auto", "general_liability", "cargo"]
}
}
Referral Rules
Referral rules define the conditions under which a submission is automatically escalated. Rules are evaluated in priority order (lower number = higher priority) and can trigger referral, auto-approval, or auto-rejection.
Rule Fields
| Field | Type | Description |
|---|---|---|
name | string | Rule name |
priority | number | Evaluation order (lower = first) |
conditions | JSON | Condition object evaluated against submission data |
action | enum | refer, auto_approve, or auto_reject |
targetAuthorityLevel | number | Minimum authority level required to handle the referral |
targetProfileId | uuid | Specific profile to route to (optional) |
notifyChannels | array | Notification channels: slack, email, in_app |
slackChannel | string | Slack channel for notifications |
notifyEmails | array | Email addresses to notify |
escalationEnabled | boolean | Whether to auto-escalate after timeout |
escalationHours | number | Hours before escalation (default: 24) |
escalationLevel | number | Authority level to escalate to |
Example: High-TIV Referral Rule
POST /v1/authority/rules
{
"orgId": "uuid",
"name": "High TIV Referral",
"priority": 10,
"conditions": { "tiv": { "$gt": 5000000 } },
"action": "refer",
"targetAuthorityLevel": 4,
"notifyChannels": ["slack", "email"],
"slackChannel": "#uw-referrals",
"notifyEmails": ["senior-uw@mga.com"],
"escalationEnabled": true,
"escalationHours": 12,
"escalationLevel": 5
}
Rules are soft-deleted -- DELETE /v1/authority/rules/:id sets is_active to false.
Approval Workflow
When a submission exceeds an underwriter's authority or a referral rule triggers, an approval record is created in the approvals table.
Approval Types
| Type | Entity Type | Trigger |
|---|---|---|
bind | submission | Bind request exceeds underwriter's authority limits |
siu_referral | claim | Special Investigations Unit referral |
reserve_change | claim | Reserve change exceeds adjuster's authority |
bordereaux_submit | bordereaux | Bordereaux submission requires sign-off |
Creating an Approval
Approvals are created programmatically by the system (role: system or org_admin) when an action requires escalation:
{
"orgId": "uuid",
"type": "bind",
"entityType": "submission",
"entityId": "uuid",
"workflowId": "workflow-instance-id",
"requestedBy": "uuid",
"metadata": { "submissionId": "uuid", "premium": 120000 },
"expiresAt": "2026-04-01T00:00:00Z"
}
Decision Endpoint
POST /v1/approvals/:id/decide
{
"decision": "approved",
"decidedBy": "uuid",
"notes": "Reviewed loss history, acceptable risk"
}
The endpoint enforces:
- Idempotency: Already-decided approvals return
409. - Expiry: Expired approvals return
409.
Side Effects
Bind rejection: When a bind approval is rejected, the system reverts both the policy and the linked submission to declined status.
Workflow resumption: If the approval is tied to a Cloudflare Workflow instance (workflowId), the decision event is sent to the workflow to resume processing:
bindapprovals send toBIND_WORKFLOWwith event typeunderwriter-bind-approval.reserve_changeapprovals send toCLAIM_WORKFLOWwith event typeclaim.reserve_approved.
API Reference
Authority Endpoints
| Method | Path | Description |
|---|---|---|
GET | /v1/authority/profiles | List authority profiles |
POST | /v1/authority/profiles | Create authority profile |
GET | /v1/authority/profiles/:id | Get profile with assigned users |
PATCH | /v1/authority/profiles/:id | Update profile limits |
POST | /v1/authority/profiles/:id/assign | Assign user to profile |
GET | /v1/authority/rules | List referral rules |
POST | /v1/authority/rules | Create referral rule |
PATCH | /v1/authority/rules/:id | Update referral rule |
DELETE | /v1/authority/rules/:id | Soft-delete referral rule |
GET | /v1/authority/matrix | Full authority matrix grid |
POST | /v1/authority/check | Check user authority for action |
Approval Endpoints
| Method | Path | Description |
|---|---|---|
GET | /v1/approvals | List approvals (paginated, filtered by status) |
POST | /v1/approvals | Create approval record |
POST | /v1/approvals/:id/decide | Approve or reject |
Related
- Submission Work Queue -- Triage scoring and swimlane routing
- Underwriting -- Rules engine and risk evaluation
- Claims -- Reserve change approvals