> ## 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.

<View title="Human" icon="user">
  ***

  ## Create a template

  <Steps>
    <Step title="Navigate to settings">
      Go to **Settings** > **Approval Templates** in your workspace.
    </Step>

    <Step title="Create a new template">
      Click **New Template** to open the template form.
    </Step>

    <Step title="Configure template details">
      Fill in the template information:

      * **Name**: A clear, descriptive name (for example, "Finance team approval" or "Security access review")
      * **Description**: Explain when this template should be used
      * **Workspaces**: Select which workspaces can use this template. Leave empty to make it available in all workspaces.
    </Step>

    <Step title="Add approval rounds">
      Configure one or more approval rounds. For each round, set:

      * **Policy**: Select **Any can approve** or **All must approve**
      * **Approvers**: Select users or <Tooltip headline="User groups" tip="Collections of users for collaboration and access management" cta="Learn about user groups" href="/documentation/platform/groups">user groups</Tooltip> who should approve this round
    </Step>

    <Step title="Save the template">
      Click **Save** to create the template. It becomes available for import on tickets in the selected workspaces.
    </Step>
  </Steps>

  ***

  ## Apply a template to a ticket

  <Steps>
    <Step title="Open the ticket">
      Navigate to the ticket that needs approval.
    </Step>

    <Step title="Import the template">
      In the **Approvals** section, click the import button and select a template from the list.
    </Step>

    <Step title="Confirm import">
      The template's rounds and approvers are applied to the ticket. The first round activates immediately and approvers are notified.
    </Step>
  </Steps>

  <Warning>
    Importing a template replaces any existing approval rounds on the ticket. Make sure you want to overwrite the current approval configuration before importing.
  </Warning>

  ***

  ## Dynamic approvers

  Templates support role-based approvers that are resolved dynamically when the template is applied to a ticket. Instead of hard-coding specific users, you can assign approval responsibilities based on the ticket's context.

  <AccordionGroup>
    <Accordion title="Ticket requester" icon="user" defaultOpen>
      Resolves to the person who submitted the ticket. Useful for self-approval steps or acknowledgment rounds.
    </Accordion>

    <Accordion title="Requester's manager" icon="users">
      Resolves to the requester's manager. When the template is applied, Ravenna cascades through every configured source in order and uses the first one that returns a manager for the requester:

      1. **App-scoped integration** — if the ticket targets an application linked to a specific integration, that integration's manager hierarchy is checked first.
      2. **Organization-wide HRIS** — if the app source has no manager link (or there is no app-scoped integration), Ravenna falls back to the workspace's HRIS.
      3. **Identity provider** — if HRIS has no manager either, Ravenna falls back to the workspace's identity provider (access provider).

      Every source is tried before the role is considered unresolved, so a missing link in one source does not leave the round empty when another source knows the manager. Common for manager-approval workflows where the requester's direct manager must sign off.
    </Accordion>
  </AccordionGroup>

  <Info>
    Dynamic approvers are resolved at the moment the template is applied. If a role cannot be resolved from any of its sources, the approver slot is normally skipped — with one exception: when the **Requester's manager** role resolves to nobody across all sources, Ravenna substitutes the ticket's workspace admins as the approvers for that slot so the round is never left without an approver. This fallback only applies to the Manager role, and only when it would otherwise resolve to no one — other dynamic roles (and mixed rounds where another source already fills the slot) are unaffected.
  </Info>

  ***

  ## Manage templates

  ### Edit a template

  Open a template from **Settings** > **Approval Templates** and modify its name, description, workspaces, or rounds. Changes only affect future imports. Tickets that already used the template keep their existing rounds.

  ### Delete a template

  Delete templates you no longer need from the template list. Deleting a template does not affect tickets that previously imported it.

  ***

  ## Template examples

  <AccordionGroup>
    <Accordion title="Manager approval" icon="user-check" defaultOpen>
      A single-round template for basic manager sign-off.

      | Round          | Policy          | Approvers           |
      | -------------- | --------------- | ------------------- |
      | Manager review | Any can approve | Requester's manager |
    </Accordion>

    <Accordion title="Finance approval chain" icon="landmark">
      A two-round template for purchase or budget requests.

      | Round            | Policy           | Approvers            |
      | ---------------- | ---------------- | -------------------- |
      | Manager approval | Any can approve  | Requester's manager  |
      | Finance review   | All must approve | Finance team members |
    </Accordion>

    <Accordion title="Security access review" icon="shield">
      A three-round template for sensitive access requests.

      | Round            | Policy           | Approvers           |
      | ---------------- | ---------------- | ------------------- |
      | Manager approval | Any can approve  | Requester's manager |
      | Security review  | All must approve | Security team       |
      | IT sign-off      | Any can approve  | IT administrators   |
    </Accordion>
  </AccordionGroup>
</View>

<View title="Agent" icon="bot">
  ## 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.
</View>
