> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ravenna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Approval templates

> Create reusable approval templates with pre-configured rounds, policies, and dynamic role-based approvers that can be imported into any ticket.

Approval templates let you define reusable multi-round approval configurations that can be imported into any ticket. Instead of manually setting up rounds and approvers each time, create a template once and apply it across tickets for consistent approval workflows.

## Mental model

Approval templates are reusable blueprints for multi-round approval configurations. When applied to a ticket, the template's rounds are copied into the ticket as concrete `TicketApprovalRound` records. The template and ticket rounds maintain a lineage link via `sourceTemplateRoundId`.

***

## Template data model

| Entity                    | Key fields                                                         | Description                 |
| ------------------------- | ------------------------------------------------------------------ | --------------------------- |
| **ApprovalTemplate**      | name, description, workspaces                                      | The template definition     |
| **ApprovalTemplateRound** | name, policy, order, approvers, approverGroups, roleBasedApprovers | A round within the template |

Templates are organization-scoped and can be assigned to specific workspaces.

***

## Template round approver types

Each template round can have three types of approvers:

| Type             | Field                            | Resolved when                              |
| ---------------- | -------------------------------- | ------------------------------------------ |
| **Static users** | `approvers` (User\[])            | Copied directly at apply time              |
| **User groups**  | `approverGroups` (UserGroup\[])  | Expanded to individual users at apply time |
| **Role-based**   | `roleBasedApprovers` (String\[]) | Resolved dynamically at apply time         |

### Role-based approver values

* `ticket_requester` - Resolves to the ticket's requester
* `requester_manager` - Resolves to the requester's manager. Ravenna cascades through the app-scoped integration, then the organization-wide HRIS, then the identity provider (ACCESS\_PROVIDER), and returns the first manager found. If **no** source produces a manager, the slot falls back to the ticket's workspace admins so the round always has at least one approver.
* `access_level_owners` - Resolves to owners from the access level (access request workflows)

Resolution happens in `resolveTemplateRoundApprovers()`. If a role other than `requester_manager` cannot be resolved, the approver slot is silently skipped. `requester_manager` is the only role with a workspace-admin safety net.

***

## Apply template process

1. Delete all existing non-reset rounds on the ticket
2. For each template round (in order):
   a. Resolve dynamic approvers (role-based + group expansion)
   b. Create `TicketApprovalRound` with `sourceTemplateRoundId` link
   c. Chain rounds via `nextRoundId`
3. Kickoff: activate first round, set ticket approval status to IN\_PROGRESS
4. Dispatch notifications to all approvers in the first round

***

## Template vs ticket rounds

| Aspect               | Template round                            | Ticket round                             |
| -------------------- | ----------------------------------------- | ---------------------------------------- |
| **Approver storage** | Users, groups, and role-based identifiers | Only concrete users                      |
| **Group handling**   | Persists group IDs                        | Groups expanded at apply time            |
| **Ordering**         | `order` integer field                     | `nextRoundId` linked list                |
| **Lifecycle**        | Static blueprint                          | Active lifecycle with status transitions |
| **Lineage**          | Source                                    | Links back via `sourceTemplateRoundId`   |

***

## Constraints and gotchas

* Applying a template replaces all existing non-reset rounds. This is destructive.
* Template changes do not propagate to tickets that already imported the template.
* Templates are organization-scoped. Workspace assignment controls visibility, not ownership.
* If all dynamic approvers in a round fail to resolve, the round is created with no approvers, which will block the approval process — **except** when the unresolved role is `requester_manager`. In that case, the ticket's workspace admins are substituted as approvers so the round can proceed. The fallback is Manager-only: it does not apply to other roles, and it does not activate on mixed rounds where another approver (static user, group, or a manager successfully resolved from a later source in the cascade) already fills the slot.
* Templates with the THRESHOLD policy are supported in the template round configuration.
