Approval component schema
The approval component turns part of a form into an approval step. It identifies authorised approvers, stores the decision and audit details, can contain fields completed by the approver, and can send action-specific email notifications.
Do not add an approvalStatus component yourself. Team Forms derives the status value for each approval and the overall workflow metadata at runtime.
Basic schema
Section titled “Basic schema”{ "type": "approval", "key": "managerApproval", "label": "Manager approval", "hideLabel": true, "components": [], "approvers": [ { "id": "existing-directory-object-id", "displayName": "Alex Manager", "mail": "alex.manager@example.com" } ], "chooseApprover": false, "revokers": [], "requestEmailTemplate": { "enabled": false }, "approvalEmailTemplate": { "enabled": false }, "rejectionEmailTemplate": { "enabled": false }, "revokeEmailTemplate": { "enabled": false }}approvers must contain exact existing directory user objects with id, displayName, and mail. Never invent IDs or use names as IDs. The AI assistant does not currently have a directory-search tool, so it may only reuse approvers already present in the form or values explicitly supplied by the user. Otherwise the approvers must be selected in the component editor.
Properties
Section titled “Properties”| Property | Type | Behaviour |
|---|---|---|
key | string | Unique response-data key for this approval step. |
label | string | Heading displayed for the approval block. |
components | component array | Optional fields completed as part of the approval step. Their answers are nested under the approval key. |
approvers | user object array | Users allowed to approve or reject this step. Each object needs id, displayName, and mail. |
chooseApprover | boolean | When more than one approver exists, lets the requester select one. When false, all configured approvers are notified and any one may act. |
revokers | user object array | Additional users allowed to revoke a decision. Uses the same user-object shape as approvers. |
dependsOn | string | Full response-data path of an earlier approval that must be approved first. |
customConditional | JavaScript string | Makes the approval conditional by assigning a boolean to show. |
collapsible | boolean | Makes the approval block collapsible. |
collapsedIfEmpty | boolean | Starts an empty collapsible block collapsed. |
expandForApprover | boolean | Expands a collapsible block for its approver. |
showApprovers | boolean | Shows configured approvers in the block header before a request is made. |
requestLabel | string | Replaces the Request Approval button label. |
approveLabel | string | Replaces the Approve button label. |
rejectLabel | string | Replaces the Reject button label. |
revokeLabel | string | Replaces the Revoke button label. |
The stored decision is available at data.<approvalKey>.approval. For example, data.managerApproval.approval.status is requested, approved, or rejected while that state is active. Team Forms also records the timestamp, requester, notified approvers, reviewer, and last actor as appropriate.
Sequential and parallel approvals
Section titled “Sequential and parallel approvals”Approvals without dependsOn can be requested in parallel. To make a second top-level approval wait for the first, set its dependency to the first component’s key:
{ "type": "approval", "key": "financeApproval", "label": "Finance approval", "components": [], "approvers": [ { "id": "existing-finance-user-id", "displayName": "Finance Approver", "mail": "finance.approver@example.com" } ], "dependsOn": "managerApproval"}dependsOn is the full data path, not a component ID or label. If an approval is inside an input container, include the container key, for example review.managerApproval. Layout-only parents such as panels do not add a path segment. Dependencies must refer to an earlier approval and must not form a cycle.
Conditional approvals and submit actions
Section titled “Conditional approvals and submit actions”Use the standard executable conditional property:
{ "customConditional": "show = Number(data.totalExpense) > 1000"}Keep the normal submit button in a standard form. When an approval is visible, Team Forms automatically hides the submit button and shows the applicable Request, Approve/Reject, or Revoke actions. If every conditional approval is hidden, the normal submit button remains available. Wizards similarly hide their generated final submit action while an approval is visible.
Original creator as a revoker
Section titled “Original creator as a revoker”The special managed revoker below resolves to the response’s original creator at runtime:
{ "id": "creator", "userPrincipalName": "Original Creator", "displayName": "Original Creator", "mail": "The original creator of this response", "givenName": "Original", "surname": "Creator", "jobTitle": "", "userLookupId": "creator"}Approval emails
Section titled “Approval emails”Each action has an independent wrapper: requestEmailTemplate, approvalEmailTemplate, rejectionEmailTemplate, and revokeEmailTemplate.
While authoring, an enabled wrapper contains an email template in value:
{ "requestEmailTemplate": { "enabled": true, "value": { "to": "{{ notifiedApprovers }}", "cc": "{{ requester.mail }}", "subject": "Approval requested - {{ title }}", "body": "{{ requester.displayName }} requested your approval.\n\n{{{ editUrl }}}", "saveToSentItems": true, "attachments": [ { "name": "{{ title }}.pdf", "contentType": "application/pdf", "contentBytes": "{{{ pdf }}}" } ] } }}Published schemas may replace value with a stored template hash; preserve an existing hash unless replacing that notification template intentionally. All dynamic email values use Handlebars, not JavaScript. See Email template syntax for the available helpers and common response fields.
Approval templates additionally receive:
| Value | Available for |
|---|---|
requester.displayName, requester.mail | All approval actions |
notifiedApprovers | Request notifications; renders the selected or notified email addresses |
reviewer.displayName, reviewer.mail | Approval and rejection notifications |
revoker.displayName, revoker.mail | Revoke notifications |
revokers | Configured revoker objects; iterate with #each when needed |