# Extend access entitlements Source: https://docs.ravenna.ai/api/access-entitlement/extend-access-entitlements https://core.api.ravenna.ai/openapi.json post /access-entitlements/extend # Get user access overview Source: https://docs.ravenna.ai/api/access-entitlement/get-user-access-overview https://core.api.ravenna.ai/openapi.json get /access-entitlements/user-access-overview # List access entitlements Source: https://docs.ravenna.ai/api/access-entitlement/list-access-entitlements https://core.api.ravenna.ai/openapi.json get /access-entitlements # List manual provisioning actions for a ticket Source: https://docs.ravenna.ai/api/access-entitlement/list-manual-provisioning-actions-for-a-ticket https://core.api.ravenna.ai/openapi.json get /access-entitlements/ticket-provisioning-actions # Manually provision entitlements Source: https://docs.ravenna.ai/api/access-entitlement/manually-provision-entitlements https://core.api.ravenna.ai/openapi.json post /access-entitlements/manual-provision # Revoke access entitlements Source: https://docs.ravenna.ai/api/access-entitlement/revoke-access-entitlements https://core.api.ravenna.ai/openapi.json post /access-entitlements/revoke # Bulk archive access levels by id Source: https://docs.ravenna.ai/api/access-level/bulk-archive-access-levels-by-id https://core.api.ravenna.ai/openapi.json post /access-levels/bulk-archive # Bulk delete access levels by id Source: https://docs.ravenna.ai/api/access-level/bulk-delete-access-levels-by-id https://core.api.ravenna.ai/openapi.json post /access-levels/bulk-delete # Bulk unarchive access levels by id Source: https://docs.ravenna.ai/api/access-level/bulk-unarchive-access-levels-by-id https://core.api.ravenna.ai/openapi.json post /access-levels/bulk-unarchive # Bulk update access levels (provisioning method or access policy) Source: https://docs.ravenna.ai/api/access-level/bulk-update-access-levels-provisioning-method-or-access-policy https://core.api.ravenna.ai/openapi.json post /access-levels/bulk-update # Create an access level for an application Source: https://docs.ravenna.ai/api/access-level/create-an-access-level-for-an-application https://core.api.ravenna.ai/openapi.json post /access-levels # Delete an access level Source: https://docs.ravenna.ai/api/access-level/delete-an-access-level https://core.api.ravenna.ai/openapi.json delete /access-levels # List access levels Source: https://docs.ravenna.ai/api/access-level/list-access-levels https://core.api.ravenna.ai/openapi.json get /access-levels # Update a single access level by id Source: https://docs.ravenna.ai/api/access-level/update-a-single-access-level-by-id https://core.api.ravenna.ai/openapi.json patch /access-levels/{id} # Update orders of access levels Source: https://docs.ravenna.ai/api/access-level/update-orders-of-access-levels https://core.api.ravenna.ai/openapi.json put /access-levels/orders # Bulk archive access policies Source: https://docs.ravenna.ai/api/access-policy/bulk-archive-access-policies https://core.api.ravenna.ai/openapi.json post /access-policies/bulk-archive # Bulk delete access policies Source: https://docs.ravenna.ai/api/access-policy/bulk-delete-access-policies https://core.api.ravenna.ai/openapi.json delete /access-policies/bulk # Bulk unarchive access policies Source: https://docs.ravenna.ai/api/access-policy/bulk-unarchive-access-policies https://core.api.ravenna.ai/openapi.json post /access-policies/bulk-unarchive # Create an access policy Source: https://docs.ravenna.ai/api/access-policy/create-an-access-policy https://core.api.ravenna.ai/openapi.json post /access-policies # Delete an access policy Source: https://docs.ravenna.ai/api/access-policy/delete-an-access-policy https://core.api.ravenna.ai/openapi.json delete /access-policies/{id} # Get an access policy Source: https://docs.ravenna.ai/api/access-policy/get-an-access-policy https://core.api.ravenna.ai/openapi.json get /access-policies/{id} # List access policies Source: https://docs.ravenna.ai/api/access-policy/list-access-policies https://core.api.ravenna.ai/openapi.json get /access-policies # List eligible access levels for a user Source: https://docs.ravenna.ai/api/access-policy/list-eligible-access-levels-for-a-user https://core.api.ravenna.ai/openapi.json get /access-policies/eligible-access-levels # List eligible applications for a user Source: https://docs.ravenna.ai/api/access-policy/list-eligible-applications-for-a-user https://core.api.ravenna.ai/openapi.json get /access-policies/eligible-applications # Update an access policy Source: https://docs.ravenna.ai/api/access-policy/update-an-access-policy https://core.api.ravenna.ai/openapi.json put /access-policies/{id} # Validate user eligibility for an access level Source: https://docs.ravenna.ai/api/access-policy/validate-user-eligibility-for-an-access-level https://core.api.ravenna.ai/openapi.json post /access-policies/validate # Create an access request Source: https://docs.ravenna.ai/api/access-request/create-an-access-request https://core.api.ravenna.ai/openapi.json post /access-request # Export admin audit events to CSV Source: https://docs.ravenna.ai/api/admin-audit-events/export-admin-audit-events-to-csv https://core.api.ravenna.ai/openapi.json post /admin-audit-events/export # Get a single admin audit event by ID Source: https://docs.ravenna.ai/api/admin-audit-events/get-a-single-admin-audit-event-by-id https://core.api.ravenna.ai/openapi.json get /admin-audit-events/{id} # Get audit events for a specific message Source: https://docs.ravenna.ai/api/agent-tool-audit-event/get-audit-events-for-a-specific-message https://core.api.ravenna.ai/openapi.json get /agent-tool-audit-events/by-message/{messageId} # Get audit events for a specific ticket Source: https://docs.ravenna.ai/api/agent-tool-audit-event/get-audit-events-for-a-specific-ticket https://core.api.ravenna.ai/openapi.json get /agent-tool-audit-events/by-ticket/{ticketId} # Get audit events for a specific trace Source: https://docs.ravenna.ai/api/agent-tool-audit-event/get-audit-events-for-a-specific-trace https://core.api.ravenna.ai/openapi.json get /agent-tool-audit-events/by-trace/{traceId} # Bulk delete agents Source: https://docs.ravenna.ai/api/agents/bulk-delete-agents https://core.api.ravenna.ai/openapi.json delete /agents/bulk # Create a new Agent Source: https://docs.ravenna.ai/api/agents/create-a-new-agent https://core.api.ravenna.ai/openapi.json post /agents # Delete an Agent Source: https://docs.ravenna.ai/api/agents/delete-an-agent https://core.api.ravenna.ai/openapi.json delete /agents/{id} # Execute a tool for an agent Source: https://docs.ravenna.ai/api/agents/execute-a-tool-for-an-agent https://core.api.ravenna.ai/openapi.json post /agents/{agentId}/tools/execute # Get Agent by ID Source: https://docs.ravenna.ai/api/agents/get-agent-by-id https://core.api.ravenna.ai/openapi.json get /agents/{id} # Get the latest agent version available to the caller Source: https://docs.ravenna.ai/api/agents/get-the-latest-agent-version-available-to-the-caller https://core.api.ravenna.ai/openapi.json get /agents/latest-version # List agents Source: https://docs.ravenna.ai/api/agents/list-agents https://core.api.ravenna.ai/openapi.json get /agents # Preview upgrading an agent to the latest version Source: https://docs.ravenna.ai/api/agents/preview-upgrading-an-agent-to-the-latest-version https://core.api.ravenna.ai/openapi.json post /agents/{agentId}/upgrade/preview # Update an Agent's Personality (per-agent copy) Source: https://docs.ravenna.ai/api/agents/update-an-agents-personality-per-agent-copy https://core.api.ravenna.ai/openapi.json put /agents/{id}/personality # Update an existing Agent Source: https://docs.ravenna.ai/api/agents/update-an-existing-agent https://core.api.ravenna.ai/openapi.json put /agents/{id} # Upgrade an agent to the latest version (creates a disabled copy) Source: https://docs.ravenna.ai/api/agents/upgrade-an-agent-to-the-latest-version-creates-a-disabled-copy https://core.api.ravenna.ai/openapi.json post /agents/{agentId}/upgrade # Create AI brief schedule Source: https://docs.ravenna.ai/api/ai-brief-schedule/create-ai-brief-schedule https://core.api.ravenna.ai/openapi.json post /ai-brief-schedules # Delete AI brief schedule Source: https://docs.ravenna.ai/api/ai-brief-schedule/delete-ai-brief-schedule https://core.api.ravenna.ai/openapi.json delete /ai-brief-schedules/{id} # Get AI brief schedule by dashboard ID Source: https://docs.ravenna.ai/api/ai-brief-schedule/get-ai-brief-schedule-by-dashboard-id https://core.api.ravenna.ai/openapi.json get /ai-brief-schedules/dashboard/{dashboardId} # Get AI brief schedule by ID Source: https://docs.ravenna.ai/api/ai-brief-schedule/get-ai-brief-schedule-by-id https://core.api.ravenna.ai/openapi.json get /ai-brief-schedules/{id} # List AI brief schedules Source: https://docs.ravenna.ai/api/ai-brief-schedule/list-ai-brief-schedules https://core.api.ravenna.ai/openapi.json get /ai-brief-schedules # Send AI brief immediately Source: https://docs.ravenna.ai/api/ai-brief-schedule/send-ai-brief-immediately https://core.api.ravenna.ai/openapi.json post /ai-brief-schedules/send-now # Update AI brief schedule Source: https://docs.ravenna.ai/api/ai-brief-schedule/update-ai-brief-schedule https://core.api.ravenna.ai/openapi.json patch /ai-brief-schedules/{id} # Execute grouped value widget query Source: https://docs.ravenna.ai/api/analytics/execute-grouped-value-widget-query https://core.api.ravenna.ai/openapi.json post /analytics/execute-grouped # Execute single value widget query Source: https://docs.ravenna.ai/api/analytics/execute-single-value-widget-query https://core.api.ravenna.ai/openapi.json post /analytics/execute-single # Execute trend/time series widget query Source: https://docs.ravenna.ai/api/analytics/execute-trendtime-series-widget-query https://core.api.ravenna.ai/openapi.json post /analytics/execute-trend # Preview metric query widget Source: https://docs.ravenna.ai/api/analytics/preview-metric-query-widget https://core.api.ravenna.ai/openapi.json post /analytics/preview-metric # Preview trend query widget Source: https://docs.ravenna.ai/api/analytics/preview-trend-query-widget https://core.api.ravenna.ai/openapi.json post /analytics/preview-trend # Bulk archive applications by id Source: https://docs.ravenna.ai/api/application/bulk-archive-applications-by-id https://core.api.ravenna.ai/openapi.json post /applications/bulk-archive # Bulk delete applications Source: https://docs.ravenna.ai/api/application/bulk-delete-applications https://core.api.ravenna.ai/openapi.json post /applications/bulk-delete # Bulk unarchive applications by id Source: https://docs.ravenna.ai/api/application/bulk-unarchive-applications-by-id https://core.api.ravenna.ai/openapi.json post /applications/bulk-unarchive # Bulk update applications to add or remove workspaces Source: https://docs.ravenna.ai/api/application/bulk-update-applications-to-add-or-remove-workspaces https://core.api.ravenna.ai/openapi.json post /applications/bulk-update # Create a new application Source: https://docs.ravenna.ai/api/application/create-a-new-application https://core.api.ravenna.ai/openapi.json post /applications # Delete an application Source: https://docs.ravenna.ai/api/application/delete-an-application https://core.api.ravenna.ai/openapi.json delete /applications/{id} # Export applications to CSV Source: https://docs.ravenna.ai/api/application/export-applications-to-csv https://core.api.ravenna.ai/openapi.json post /applications/export # Get application by ID Source: https://docs.ravenna.ai/api/application/get-application-by-id https://core.api.ravenna.ai/openapi.json get /applications/{id} # List applications Source: https://docs.ravenna.ai/api/application/list-applications https://core.api.ravenna.ai/openapi.json get /applications # Update an application Source: https://docs.ravenna.ai/api/application/update-an-application https://core.api.ravenna.ai/openapi.json put /applications/{id} # Bulk delete approval templates Source: https://docs.ravenna.ai/api/approval-templates/bulk-delete-approval-templates https://core.api.ravenna.ai/openapi.json delete /approval-templates/bulk # Bulk update approval templates to add workspaces Source: https://docs.ravenna.ai/api/approval-templates/bulk-update-approval-templates-to-add-workspaces https://core.api.ravenna.ai/openapi.json post /approval-templates/bulk-update # Create an approval template Source: https://docs.ravenna.ai/api/approval-templates/create-an-approval-template https://core.api.ravenna.ai/openapi.json post /approval-templates # Delete an approval template Source: https://docs.ravenna.ai/api/approval-templates/delete-an-approval-template https://core.api.ravenna.ai/openapi.json delete /approval-templates/{id} # Get an approval template Source: https://docs.ravenna.ai/api/approval-templates/get-an-approval-template https://core.api.ravenna.ai/openapi.json get /approval-templates/{id} # List approval templates Source: https://docs.ravenna.ai/api/approval-templates/list-approval-templates https://core.api.ravenna.ai/openapi.json get /approval-templates # Update an approval template Source: https://docs.ravenna.ai/api/approval-templates/update-an-approval-template https://core.api.ravenna.ai/openapi.json put /approval-templates/{id} # Create an asset type Source: https://docs.ravenna.ai/api/asset-types/create-an-asset-type https://core.api.ravenna.ai/openapi.json post /asset-types # Delete an asset type Source: https://docs.ravenna.ai/api/asset-types/delete-an-asset-type https://core.api.ravenna.ai/openapi.json delete /asset-types/{id} # Get an asset type by ID Source: https://docs.ravenna.ai/api/asset-types/get-an-asset-type-by-id https://core.api.ravenna.ai/openapi.json get /asset-types/{id} # List asset types Source: https://docs.ravenna.ai/api/asset-types/list-asset-types https://core.api.ravenna.ai/openapi.json get /asset-types # Update an asset type Source: https://docs.ravenna.ai/api/asset-types/update-an-asset-type https://core.api.ravenna.ai/openapi.json patch /asset-types/{id} # Asset totals and per-type counts Source: https://docs.ravenna.ai/api/assets/asset-totals-and-per-type-counts https://core.api.ravenna.ai/openapi.json get /assets/stats # Assign users to assets Source: https://docs.ravenna.ai/api/assets/assign-users-to-assets https://core.api.ravenna.ai/openapi.json post /assets/bulk-assign # Confirm CSV upload and start import Source: https://docs.ravenna.ai/api/assets/confirm-csv-upload-and-start-import https://core.api.ravenna.ai/openapi.json post /assets/import/confirm # Create an asset Source: https://docs.ravenna.ai/api/assets/create-an-asset https://core.api.ravenna.ai/openapi.json post /assets # Delete an asset Source: https://docs.ravenna.ai/api/assets/delete-an-asset https://core.api.ravenna.ai/openapi.json delete /assets/{id} # Get a presigned URL for CSV import Source: https://docs.ravenna.ai/api/assets/get-a-presigned-url-for-csv-import https://core.api.ravenna.ai/openapi.json post /assets/import/presign # Get an asset by ID Source: https://docs.ravenna.ai/api/assets/get-an-asset-by-id https://core.api.ravenna.ai/openapi.json get /assets/{id} # List activity for an asset Source: https://docs.ravenna.ai/api/assets/list-activity-for-an-asset https://core.api.ravenna.ai/openapi.json get /assets/{id}/activities # List assets Source: https://docs.ravenna.ai/api/assets/list-assets https://core.api.ravenna.ai/openapi.json get /assets # Unassign users from assets Source: https://docs.ravenna.ai/api/assets/unassign-users-from-assets https://core.api.ravenna.ai/openapi.json post /assets/bulk-unassign # Update an asset Source: https://docs.ravenna.ai/api/assets/update-an-asset https://core.api.ravenna.ai/openapi.json patch /assets/{id} # Archive business schedule Source: https://docs.ravenna.ai/api/business-schedule/archive-business-schedule https://core.api.ravenna.ai/openapi.json post /business-schedules/{id}/archive # Create business schedule Source: https://docs.ravenna.ai/api/business-schedule/create-business-schedule https://core.api.ravenna.ai/openapi.json post /business-schedules # Delete business schedule Source: https://docs.ravenna.ai/api/business-schedule/delete-business-schedule https://core.api.ravenna.ai/openapi.json delete /business-schedules/{id} # Get business schedule by ID Source: https://docs.ravenna.ai/api/business-schedule/get-business-schedule-by-id https://core.api.ravenna.ai/openapi.json get /business-schedules/{id} # List business schedules Source: https://docs.ravenna.ai/api/business-schedule/list-business-schedules https://core.api.ravenna.ai/openapi.json get /business-schedules # Unarchive business schedule Source: https://docs.ravenna.ai/api/business-schedule/unarchive-business-schedule https://core.api.ravenna.ai/openapi.json post /business-schedules/{id}/unarchive # Update business schedule Source: https://docs.ravenna.ai/api/business-schedule/update-business-schedule https://core.api.ravenna.ai/openapi.json patch /business-schedules/{id} # Bulk create categories Source: https://docs.ravenna.ai/api/categories/bulk-create-categories https://core.api.ravenna.ai/openapi.json post /categories/bulk # Create a new category Source: https://docs.ravenna.ai/api/categories/create-a-new-category https://core.api.ravenna.ai/openapi.json post /categories # Delete a category Source: https://docs.ravenna.ai/api/categories/delete-a-category https://core.api.ravenna.ai/openapi.json delete /categories/{id} # Get category by ID Source: https://docs.ravenna.ai/api/categories/get-category-by-id https://core.api.ravenna.ai/openapi.json get /categories/{id} # List categories Source: https://docs.ravenna.ai/api/categories/list-categories https://core.api.ravenna.ai/openapi.json get /categories # List category templates Source: https://docs.ravenna.ai/api/categories/list-category-templates https://core.api.ravenna.ai/openapi.json get /categories/templates # Update a category Source: https://docs.ravenna.ai/api/categories/update-a-category https://core.api.ravenna.ai/openapi.json put /categories/{id} # Create a new Channel. Source: https://docs.ravenna.ai/api/channels/create-a-new-channel https://core.api.ravenna.ai/openapi.json post /queues # Deletes an existing Channel. Source: https://docs.ravenna.ai/api/channels/deletes-an-existing-channel https://core.api.ravenna.ai/openapi.json delete /queues/{id} # Get Channel by ID. Source: https://docs.ravenna.ai/api/channels/get-channel-by-id https://core.api.ravenna.ai/openapi.json get /queues/{id} # List channels Source: https://docs.ravenna.ai/api/channels/list-channels https://core.api.ravenna.ai/openapi.json get /queues # Updates an existing Channel. Source: https://docs.ravenna.ai/api/channels/updates-an-existing-channel https://core.api.ravenna.ai/openapi.json put /queues/{id} # Activate code action Source: https://docs.ravenna.ai/api/codeaction/activate-code-action https://core.api.ravenna.ai/openapi.json post /foundry/code-actions/activate # Analyze code action Source: https://docs.ravenna.ai/api/codeaction/analyze-code-action https://core.api.ravenna.ai/openapi.json post /foundry/code-actions/analyze # Create code action Source: https://docs.ravenna.ai/api/codeaction/create-code-action https://core.api.ravenna.ai/openapi.json post /foundry/code-actions # Delete code action Source: https://docs.ravenna.ai/api/codeaction/delete-code-action https://core.api.ravenna.ai/openapi.json delete /foundry/code-actions/{id} # Get code action by ID Source: https://docs.ravenna.ai/api/codeaction/get-code-action-by-id https://core.api.ravenna.ai/openapi.json get /foundry/code-actions/{id} # List code actions Source: https://docs.ravenna.ai/api/codeaction/list-code-actions https://core.api.ravenna.ai/openapi.json get /foundry/code-actions # Update code action Source: https://docs.ravenna.ai/api/codeaction/update-code-action https://core.api.ravenna.ai/openapi.json put /foundry/code-actions/{id} # Create a comment on an entity Source: https://docs.ravenna.ai/api/comments/create-a-comment-on-an-entity https://core.api.ravenna.ai/openapi.json post /comments # Delete a comment Source: https://docs.ravenna.ai/api/comments/delete-a-comment https://core.api.ravenna.ai/openapi.json delete /comments/{id} # List comments for an entity Source: https://docs.ravenna.ai/api/comments/list-comments-for-an-entity https://core.api.ravenna.ai/openapi.json get /comments # Update a comment Source: https://docs.ravenna.ai/api/comments/update-a-comment https://core.api.ravenna.ai/openapi.json patch /comments/{id} # Create credential Source: https://docs.ravenna.ai/api/credential/create-credential https://core.api.ravenna.ai/openapi.json post /credentials # Delete credential Source: https://docs.ravenna.ai/api/credential/delete-credential https://core.api.ravenna.ai/openapi.json delete /credentials/{id} # List credentials Source: https://docs.ravenna.ai/api/credential/list-credentials https://core.api.ravenna.ai/openapi.json get /credentials # Update credential value Source: https://docs.ravenna.ai/api/credential/update-credential-value https://core.api.ravenna.ai/openapi.json put /credentials/{id} # Create a new custom field Source: https://docs.ravenna.ai/api/custom-fields/create-a-new-custom-field https://core.api.ravenna.ai/openapi.json post /custom-fields # Delete a custom field Source: https://docs.ravenna.ai/api/custom-fields/delete-a-custom-field https://core.api.ravenna.ai/openapi.json delete /custom-fields/{id} # Get custom field by ID Source: https://docs.ravenna.ai/api/custom-fields/get-custom-field-by-id https://core.api.ravenna.ai/openapi.json get /custom-fields/{id} # List custom fields Source: https://docs.ravenna.ai/api/custom-fields/list-custom-fields https://core.api.ravenna.ai/openapi.json get /custom-fields # Update a custom field Source: https://docs.ravenna.ai/api/custom-fields/update-a-custom-field https://core.api.ravenna.ai/openapi.json put /custom-fields/{id} # Submit a customer portal form Source: https://docs.ravenna.ai/api/customer-portal/submit-a-customer-portal-form https://core.api.ravenna.ai/openapi.json post /customer-portal/submit-form # Create a new dashboard Source: https://docs.ravenna.ai/api/dashboard/create-a-new-dashboard https://core.api.ravenna.ai/openapi.json post /dashboards # Create a new dashboard widget Source: https://docs.ravenna.ai/api/dashboard/create-a-new-dashboard-widget https://core.api.ravenna.ai/openapi.json post /dashboard/widgets # Delete a dashboard widget Source: https://docs.ravenna.ai/api/dashboard/delete-a-dashboard-widget https://core.api.ravenna.ai/openapi.json delete /dashboard/widgets/{id} # Duplicate a dashboard along with its widgets Source: https://docs.ravenna.ai/api/dashboard/duplicate-a-dashboard-along-with-its-widgets https://core.api.ravenna.ai/openapi.json post /dashboards/{id}/duplicate # Get a dashboard by its slug Source: https://docs.ravenna.ai/api/dashboard/get-a-dashboard-by-its-slug https://core.api.ravenna.ai/openapi.json get /dashboards/by-slug/{slug} # Get AI-generated insights for a dashboard widget Source: https://docs.ravenna.ai/api/dashboard/get-ai-generated-insights-for-a-dashboard-widget https://core.api.ravenna.ai/openapi.json post /dashboards/widgets/insights # List dashboards with pagination Source: https://docs.ravenna.ai/api/dashboard/list-dashboards-with-pagination https://core.api.ravenna.ai/openapi.json get /dashboards # Move a dashboard or collection into another collection Source: https://docs.ravenna.ai/api/dashboard/move-a-dashboard-or-collection-into-another-collection https://core.api.ravenna.ai/openapi.json post /dashboards/move # Move multiple dashboards or collections into another collection Source: https://docs.ravenna.ai/api/dashboard/move-multiple-dashboards-or-collections-into-another-collection https://core.api.ravenna.ai/openapi.json post /dashboards/bulk-move # Update a dashboard widget Source: https://docs.ravenna.ai/api/dashboard/update-a-dashboard-widget https://core.api.ravenna.ai/openapi.json patch /dashboard/widgets/{id} # Update an existing dashboard Source: https://docs.ravenna.ai/api/dashboard/update-an-existing-dashboard https://core.api.ravenna.ai/openapi.json patch /dashboards/{id} # Add email domain Source: https://docs.ravenna.ai/api/emaildomain/add-email-domain https://core.api.ravenna.ai/openapi.json post /email-domains # Check email domain verification Source: https://docs.ravenna.ai/api/emaildomain/check-email-domain-verification https://core.api.ravenna.ai/openapi.json post /email-domains/{id}/verify # Delete email domain Source: https://docs.ravenna.ai/api/emaildomain/delete-email-domain https://core.api.ravenna.ai/openapi.json delete /email-domains/{id} # Get email domain Source: https://docs.ravenna.ai/api/emaildomain/get-email-domain https://core.api.ravenna.ai/openapi.json get /email-domains/{id} # List email domains Source: https://docs.ravenna.ai/api/emaildomain/list-email-domains https://core.api.ravenna.ai/openapi.json get /email-domains # Retry DKIM verification Source: https://docs.ravenna.ai/api/emaildomain/retry-dkim-verification https://core.api.ravenna.ai/openapi.json post /email-domains/{id}/retry-dkim # Create a field definition Source: https://docs.ravenna.ai/api/fields/create-a-field-definition https://core.api.ravenna.ai/openapi.json post /field-definitions # Delete a field definition Source: https://docs.ravenna.ai/api/fields/delete-a-field-definition https://core.api.ravenna.ai/openapi.json delete /field-definitions/{id} # Delete a field value Source: https://docs.ravenna.ai/api/fields/delete-a-field-value https://core.api.ravenna.ai/openapi.json delete /field-values/{id} # Get a field definition by ID Source: https://docs.ravenna.ai/api/fields/get-a-field-definition-by-id https://core.api.ravenna.ai/openapi.json get /field-definitions/{id} # List field definitions Source: https://docs.ravenna.ai/api/fields/list-field-definitions https://core.api.ravenna.ai/openapi.json get /field-definitions # List field values for an entity Source: https://docs.ravenna.ai/api/fields/list-field-values-for-an-entity https://core.api.ravenna.ai/openapi.json get /field-values # Set a field value Source: https://docs.ravenna.ai/api/fields/set-a-field-value https://core.api.ravenna.ai/openapi.json post /field-values # Set multiple field values Source: https://docs.ravenna.ai/api/fields/set-multiple-field-values https://core.api.ravenna.ai/openapi.json post /field-values/batch # Update a field definition Source: https://docs.ravenna.ai/api/fields/update-a-field-definition https://core.api.ravenna.ai/openapi.json patch /field-definitions/{id} # Attach an integration to a Foundry action Source: https://docs.ravenna.ai/api/foundry-action-integrations/attach-an-integration-to-a-foundry-action https://core.api.ravenna.ai/openapi.json post /foundry/action-integrations # Detach an integration from a Foundry action Source: https://docs.ravenna.ai/api/foundry-action-integrations/detach-an-integration-from-a-foundry-action https://core.api.ravenna.ai/openapi.json delete /foundry/action-integrations # List integrations attached to a Foundry action Source: https://docs.ravenna.ai/api/foundry-action-integrations/list-integrations-attached-to-a-foundry-action https://core.api.ravenna.ai/openapi.json get /foundry/action-integrations # Connect a client_credentials OAuth provider and create an integration Source: https://docs.ravenna.ai/api/foundry-oauth-providers/connect-a-client_credentials-oauth-provider-and-create-an-integration https://core.api.ravenna.ai/openapi.json post /foundry/oauth-providers/connect-client-credentials # Get docs validation status for a Foundry OAuth provider Source: https://docs.ravenna.ai/api/foundry-oauth-providers/get-docs-validation-status-for-a-foundry-oauth-provider https://core.api.ravenna.ai/openapi.json get /foundry/oauth-providers/validation-status # Trigger docs validation for a Foundry OAuth provider Source: https://docs.ravenna.ai/api/foundry-oauth-providers/trigger-docs-validation-for-a-foundry-oauth-provider https://core.api.ravenna.ai/openapi.json post /foundry/oauth-providers/validate-docs # Create a Foundry action Source: https://docs.ravenna.ai/api/foundry/create-a-foundry-action https://core.api.ravenna.ai/openapi.json post /foundry/actions # Create a Foundry action hosted on a native integration credential bridge Source: https://docs.ravenna.ai/api/foundry/create-a-foundry-action-hosted-on-a-native-integration-credential-bridge https://core.api.ravenna.ai/openapi.json post /foundry/actions/with-native-bridge # Create a Foundry integration Source: https://docs.ravenna.ai/api/foundry/create-a-foundry-integration https://core.api.ravenna.ai/openapi.json post /foundry/integrations # Create a Foundry integration from an OAuth provider Source: https://docs.ravenna.ai/api/foundry/create-a-foundry-integration-from-an-oauth-provider https://core.api.ravenna.ai/openapi.json post /foundry/integrations/from-provider # Delete a Foundry action Source: https://docs.ravenna.ai/api/foundry/delete-a-foundry-action https://core.api.ravenna.ai/openapi.json delete /foundry/actions/{id} # Delete a Foundry integration Source: https://docs.ravenna.ai/api/foundry/delete-a-foundry-integration https://core.api.ravenna.ai/openapi.json delete /foundry/integrations/{id} # Generate code for a Foundry action (async via Temporal) Source: https://docs.ravenna.ai/api/foundry/generate-code-for-a-foundry-action-async-via-temporal https://core.api.ravenna.ai/openapi.json post /foundry/actions/generate # Get a Foundry action Source: https://docs.ravenna.ai/api/foundry/get-a-foundry-action https://core.api.ravenna.ai/openapi.json get /foundry/actions/{id} # Get a Foundry integration Source: https://docs.ravenna.ai/api/foundry/get-a-foundry-integration https://core.api.ravenna.ai/openapi.json get /foundry/integrations/{id} # Get a Foundry test run Source: https://docs.ravenna.ai/api/foundry/get-a-foundry-test-run https://core.api.ravenna.ai/openapi.json get /foundry/test-runs/{id} # Get iteration history for a Foundry action Source: https://docs.ravenna.ai/api/foundry/get-iteration-history-for-a-foundry-action https://core.api.ravenna.ai/openapi.json get /foundry/actions/{id}/iterations # Get or create the org-scoped code integration for Build Code mode Source: https://docs.ravenna.ai/api/foundry/get-or-create-the-org-scoped-code-integration-for-build-code-mode https://core.api.ravenna.ai/openapi.json get /foundry/code-integration # Iterate on Foundry action code with feedback Source: https://docs.ravenna.ai/api/foundry/iterate-on-foundry-action-code-with-feedback https://core.api.ravenna.ai/openapi.json post /foundry/actions/iterate # Link a native integration as a Foundry action credential source Source: https://docs.ravenna.ai/api/foundry/link-a-native-integration-as-a-foundry-action-credential-source https://core.api.ravenna.ai/openapi.json post /foundry/actions/native-bridge # List Foundry actions Source: https://docs.ravenna.ai/api/foundry/list-foundry-actions https://core.api.ravenna.ai/openapi.json get /foundry/actions # List Foundry integrations Source: https://docs.ravenna.ai/api/foundry/list-foundry-integrations https://core.api.ravenna.ai/openapi.json get /foundry/integrations # List integration IDs that have Foundry enabled Source: https://docs.ravenna.ai/api/foundry/list-integration-ids-that-have-foundry-enabled https://core.api.ravenna.ai/openapi.json get /foundry/enabled-integration-ids # List native integrations that expose a Foundry credential bridge Source: https://docs.ravenna.ai/api/foundry/list-native-integrations-that-expose-a-foundry-credential-bridge https://core.api.ravenna.ai/openapi.json get /foundry/native-bridge-integrations # List non-Foundry integrations that have Foundry enabled Source: https://docs.ravenna.ai/api/foundry/list-non-foundry-integrations-that-have-foundry-enabled https://core.api.ravenna.ai/openapi.json get /foundry/connected-integrations # List restore checkpoints for a Foundry action Source: https://docs.ravenna.ai/api/foundry/list-restore-checkpoints-for-a-foundry-action https://core.api.ravenna.ai/openapi.json get /foundry/actions/{id}/checkpoints # List test runs for a Foundry action Source: https://docs.ravenna.ai/api/foundry/list-test-runs-for-a-foundry-action https://core.api.ravenna.ai/openapi.json get /foundry/test-runs # Publish a Foundry action for use in workflows Source: https://docs.ravenna.ai/api/foundry/publish-a-foundry-action-for-use-in-workflows https://core.api.ravenna.ai/openapi.json post /foundry/actions/publish # Regenerate the agent-tool prompt for a Foundry action's target model Source: https://docs.ravenna.ai/api/foundry/regenerate-the-agent-tool-prompt-for-a-foundry-actions-target-model https://core.api.ravenna.ai/openapi.json post /foundry/actions/regenerate-ai-prompt # Regenerate the dry-run (non-mutating) variant for a Foundry action Source: https://docs.ravenna.ai/api/foundry/regenerate-the-dry-run-non-mutating-variant-for-a-foundry-action https://core.api.ravenna.ai/openapi.json post /foundry/actions/regenerate-dry-run-code # Restore a Foundry action to a checkpoint Source: https://docs.ravenna.ai/api/foundry/restore-a-foundry-action-to-a-checkpoint https://core.api.ravenna.ai/openapi.json post /foundry/actions/{id}/checkpoints/{checkpointId}/restore # Roll back a published Foundry action to a prior published version Source: https://docs.ravenna.ai/api/foundry/roll-back-a-published-foundry-action-to-a-prior-published-version https://core.api.ravenna.ai/openapi.json post /foundry/actions/{id}/checkpoints/{checkpointId}/rollback-published # Run a test execution for a Foundry action Source: https://docs.ravenna.ai/api/foundry/run-a-test-execution-for-a-foundry-action https://core.api.ravenna.ai/openapi.json post /foundry/test-runs # Unpublish a Foundry action from workflows Source: https://docs.ravenna.ai/api/foundry/unpublish-a-foundry-action-from-workflows https://core.api.ravenna.ai/openapi.json post /foundry/actions/unpublish # Update a Foundry action Source: https://docs.ravenna.ai/api/foundry/update-a-foundry-action https://core.api.ravenna.ai/openapi.json put /foundry/actions/{id} # Update a Foundry integration Source: https://docs.ravenna.ai/api/foundry/update-a-foundry-integration https://core.api.ravenna.ai/openapi.json put /foundry/integrations/{id} # Update the endpoint docs URL for a Foundry action Source: https://docs.ravenna.ai/api/foundry/update-the-endpoint-docs-url-for-a-foundry-action https://core.api.ravenna.ai/openapi.json put /foundry/actions/docs-url # Validate a Foundry action for publish (tsc + schema check) Source: https://docs.ravenna.ai/api/foundry/validate-a-foundry-action-for-publish-tsc-+-schema-check https://core.api.ravenna.ai/openapi.json post /foundry/actions/validate # Validate API documentation for an integration (async via Temporal) Source: https://docs.ravenna.ai/api/foundry/validate-api-documentation-for-an-integration-async-via-temporal https://core.api.ravenna.ai/openapi.json post /foundry/integrations/validate-docs # Verify authentication credentials against a known endpoint Source: https://docs.ravenna.ai/api/foundry/verify-authentication-credentials-against-a-known-endpoint https://core.api.ravenna.ai/openapi.json post /foundry/integrations/verify-auth # Get integration users for a user with filtered metadata Source: https://docs.ravenna.ai/api/integration-user/get-integration-users-for-a-user-with-filtered-metadata https://core.api.ravenna.ai/openapi.json get /integration-user/for-user # Get profile field definitions for an integration Source: https://docs.ravenna.ai/api/integration-user/get-profile-field-definitions-for-an-integration https://core.api.ravenna.ai/openapi.json get /integration-user/profile-fields # List integration users for an integration Source: https://docs.ravenna.ai/api/integration-user/list-integration-users-for-an-integration https://core.api.ravenna.ai/openapi.json get /integration-user/list-for-integration # Create knowledge gap cluster Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/create-knowledge-gap-cluster https://core.api.ravenna.ai/openapi.json post /knowledge-gap-clusters Create a new topic that will be used to classify messages in the next detection run # Delete all knowledge gap clusters (internal) Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/delete-all-knowledge-gap-clusters-internal https://core.api.ravenna.ai/openapi.json delete /knowledge-gap-clusters/all Ravenna-internal only. Hard-deletes all clusters and the pending pool for the workspace. # Generate KB article from cluster Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/generate-kb-article-from-cluster https://core.api.ravenna.ai/openapi.json post /knowledge-gap-clusters/{clusterId}/generate-kb-article Start a KB article generation workflow from a knowledge gap cluster. Processes all tickets in the cluster to create a comprehensive KB article. # Get cluster details Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/get-cluster-details https://core.api.ravenna.ai/openapi.json get /knowledge-gap-clusters/{clusterId} Get full cluster details: question phrasings, underlying tickets, and per-queue coverage # Get KB article generation status Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/get-kb-article-generation-status https://core.api.ravenna.ai/openapi.json get /knowledge-gap-clusters/{clusterId}/kb-article-status Check the status of a KB article generation workflow for a cluster # Get tickets for cluster Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/get-tickets-for-cluster https://core.api.ravenna.ai/openapi.json get /knowledge-gap-clusters/{clusterId}/tickets Get unique tickets associated with a cluster via its messages # List emerging (pooled) strays Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/list-emerging-pooled-strays https://core.api.ravenna.ai/openapi.json get /knowledge-gap-clusters/emerging List tickets pooled below the cluster floor, awaiting similar tickets to form a gap # List knowledge gap clusters Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/list-knowledge-gap-clusters https://core.api.ravenna.ai/openapi.json get /knowledge-gap-clusters List cluster summaries for a workspace whose active date range (firstSeenAt/lastSeenAt) overlaps the requested window # Move messages between clusters Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/move-messages-between-clusters https://core.api.ravenna.ai/openapi.json post /knowledge-gap-clusters/move-messages Move messages from source clusters to target cluster and regenerate labels using LLM # Remove messages from a cluster Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/remove-messages-from-a-cluster https://core.api.ravenna.ai/openapi.json post /knowledge-gap-clusters/remove-messages Disconnect messages from a cluster without deleting the underlying ticket messages # Set cluster lifecycle state Source: https://docs.ravenna.ai/api/knowledge-gap-clusters/set-cluster-lifecycle-state https://core.api.ravenna.ai/openapi.json post /knowledge-gap-clusters/{clusterId}/lifecycle Manually archive or restore a knowledge gap cluster # Create knowledge gaps schedule Source: https://docs.ravenna.ai/api/knowledge-gaps-schedule/create-knowledge-gaps-schedule https://core.api.ravenna.ai/openapi.json post /knowledge-gaps-schedules # Delete all clusters and regenerate with fresh 90-day lookback Source: https://docs.ravenna.ai/api/knowledge-gaps-schedule/delete-all-clusters-and-regenerate-with-fresh-90-day-lookback https://core.api.ravenna.ai/openapi.json post /knowledge-gaps-schedules/delete-and-regenerate # Delete knowledge gaps schedule Source: https://docs.ravenna.ai/api/knowledge-gaps-schedule/delete-knowledge-gaps-schedule https://core.api.ravenna.ai/openapi.json delete /knowledge-gaps-schedules/{id} # Get knowledge gaps schedule by ID Source: https://docs.ravenna.ai/api/knowledge-gaps-schedule/get-knowledge-gaps-schedule-by-id https://core.api.ravenna.ai/openapi.json get /knowledge-gaps-schedules/{id} # Get knowledge gaps schedule by workspace ID Source: https://docs.ravenna.ai/api/knowledge-gaps-schedule/get-knowledge-gaps-schedule-by-workspace-id https://core.api.ravenna.ai/openapi.json get /knowledge-gaps-schedules/workspace/{workspaceId} # Trigger knowledge gaps detection immediately Source: https://docs.ravenna.ai/api/knowledge-gaps-schedule/trigger-knowledge-gaps-detection-immediately https://core.api.ravenna.ai/openapi.json post /knowledge-gaps-schedules/trigger-now # Update knowledge gaps schedule Source: https://docs.ravenna.ai/api/knowledge-gaps-schedule/update-knowledge-gaps-schedule https://core.api.ravenna.ai/openapi.json patch /knowledge-gaps-schedules/{id} # Upload a portal header image for the organization Source: https://docs.ravenna.ai/api/organizations/upload-a-portal-header-image-for-the-organization https://core.api.ravenna.ai/openapi.json post /organizations/portal-header-image # API Overview Source: https://docs.ravenna.ai/api/overview Use the Ravenna REST API to programmatically create tickets, manage queues, sync workspace data, and authenticate requests with API keys. Use the Ravenna API to programmatically create tickets, manage queues, sync data, and automate workflows in your workspace. All requests use REST principles with JSON responses and require API key authentication. ## Getting started **Base URL:** `https://core.ravenna.ai/api` **Authentication:** Include your API key in the `x-ravenna-api-token` header with every request. **Example request:** ```bash theme={"system"} curl --request GET \ --url https://core.ravenna.ai/api/queues \ --header 'x-ravenna-api-token: ' ``` ## Authentication ### Create an API key 1. Navigate to **Settings** in your Ravenna workspace 2. Select **API Keys** from the sidebar 3. Click **Create API Key** 4. Optionally add one or more **Allowed IP ranges** in CIDR notation to restrict where the key can be used from. See [Restrict a key to specific IP ranges](#restrict-a-key-to-specific-ip-ranges). 5. Copy your key and store it securely You can view your API keys at any time from the settings page. Each key displays its creation date, last usage timestamp, and the number of IP ranges it is restricted to. Keep your API key secure. Never expose it in client-side code or public repositories. ### Use your API key Include your API key in the `x-ravenna-api-token` header with every request: ```bash theme={"system"} curl --request GET \ --url https://core.ravenna.ai/api/queues \ --header 'x-ravenna-api-token: your-api-key-here' ``` ### Authenticate via query parameter For environments where you cannot set custom HTTP headers, such as browser-based access, embedded links, or webhook receivers, pass your API key as the `apiKey` query parameter instead: ```bash theme={"system"} curl --request GET \ --url 'https://core.ravenna.ai/api/queues?apiKey=your-api-key-here' ``` The query parameter is interchangeable with the header, but if both are present the header takes precedence. Header authentication remains the recommended method whenever your client supports it, since query parameters can be logged by proxies, browser history, and server access logs. Avoid sharing or storing URLs that include API keys in query parameters. Treat them with the same care you would a password. ### Restrict a key to specific IP ranges You can pin an API key to one or more IP ranges so requests from any other address are rejected. Use this to lock a key to your office network, a NAT gateway, a bastion host, or a specific CI runner. **When to use IP restrictions:** * The key is used by a system with a stable, well-known egress IP (a CI job, a scheduled worker, a customer's on-prem integration). * You want a stolen key to be unusable outside your network even before you notice and revoke it. * Your security policy requires network-level scoping in addition to key-level authentication. **Configure allowed ranges on a new key:** 1. On the **Create API Key** dialog, add each range to **Allowed IP ranges** and press Enter. 2. Leave the list empty to make the key usable from any IP address (existing keys are unrestricted by default). **Change ranges on an existing key:** 1. Go to **Settings** > **API Keys**. 2. Open the key's menu and select **Edit IP ranges**. 3. Add or remove ranges, then save. Changes take effect immediately. **Accepted notation:** * IPv4 with a prefix length, for example `203.0.113.0/24` or `198.51.100.42/32` for a single address. * IPv6 with a prefix length, for example `2001:db8::/32` or `2001:db8::1/128`. * IPv4-mapped IPv6 addresses (`::ffff:203.0.113.50`) are compared as IPv4, so a caller arriving over a dual-stack listener matches an IPv4 range. * `/0` is rejected — it would match every address, which is what an empty list already means. Each key can hold up to 50 ranges. **How the caller IP is determined:** Ravenna reads the caller IP from the `CloudFront-Viewer-Address` header, which CloudFront sets itself and a client cannot spoof. If your traffic passes through your own proxy or egress gateway before reaching Ravenna, add that gateway's public egress IP to the allowlist, not the internal client's address. **Failure mode:** A request from an address outside the allowlist is rejected with `403 Forbidden` and no `WWW-Authenticate` header. The response body does not reveal that the key is IP-scoped — the same status is returned when the caller IP cannot be established at all — so a stolen key learns nothing about the restriction. The reason is recorded in Ravenna's server logs. Two related behaviors changed alongside IP-restricted keys and apply to every workspace, restricted or not: audit events on the API key surface record the real caller IP rather than the load balancer's, and per-key rate limits are counted per real client instead of shared across every caller behind the load balancer. ### Monitor API key usage The API Keys settings page shows a **Last used** timestamp for each key. Use this to: * Identify unused or stale keys that can be safely revoked * Verify that integrations are actively using their assigned keys ### Revoke an API key To revoke an API key: 1. Go to **Settings** > **API Keys** 2. Find the key you want to revoke 3. Click the **Revoke** button Revoked keys stop working immediately. ## Finding resource IDs Most write endpoints reference other resources by ID (for example, `assigneeId`, `queueId`, `workspaceId`, or a custom field ID). IDs are not shown in the Admin. Look them up with the matching list endpoint, then reuse the `id` value in your next request. Common lookups: * **Users** (for `assigneeId`, `requesterId`, `approverIds`): call `GET /users`. Narrow the result with the `search`, `email`, or `workspaceId` query parameters, then copy the `id` field from the user you want. * **Workspaces** (for `workspaceId`): call `GET /workspaces` to list every workspace your API key can access. * **Queues** (for `queueId`): call `GET /queues`, optionally filtered by `workspaceId`. * **Forms, statuses, tags, and custom fields**: call the matching list endpoint (for example, `GET /forms`, `GET /statuses`, `GET /tags`) and copy the `id` of the entry you need. * **Statuses** (for `statusId` on ticket create or update): status IDs are per-workspace and are not fixed enums. Call `GET /statuses` to list your workspace's statuses (both system statuses like Open, In Progress, Waiting, Done, and Closed, and any custom sub-statuses), then use the `id` of the status you want to set. If you already know a resource by name or email, use the `search` query parameter on the list endpoint instead of paginating through every record. ## Making requests ### Response format All responses return JSON with a `Content-Type: application/json` header. The response body contains the resource data directly, without a top-level `data` wrapper. Successful responses return the requested resource. The example below shows a queue response, but the fields differ by endpoint. For example, `GET /queues/{id}` returns queue fields (`id`, `name`, `status`, and so on), while `GET /users/{id}` returns user fields. Refer to the endpoint's reference page for the full field list. ```json theme={"system"} { "id": "123", "name": "Support Queue", "status": "active" } ``` List endpoints return an array of resources of the same shape: ```json theme={"system"} [ { "id": "123", "name": "Support Queue", "status": "active" }, { "id": "124", "name": "Billing Queue", "status": "active" } ] ``` Error responses always use the same envelope, regardless of endpoint. The `code` is a stable machine-readable string you can branch on, and `message` is a human-readable description that may change: ```json theme={"system"} { "error": { "code": "unauthorized", "message": "Invalid API key provided" } } ``` ### Response shape for ticket lists Ticket list endpoints (`GET /tickets`, and related list endpoints that accept a `responseType` query parameter) support a `responseType` value that controls how much detail each ticket includes. The response shape is otherwise the same. * `default` (used when `responseType` is omitted): returns each ticket with its standard fields and expanded relations, such as the ticket's queue name, status object, tags, and other embedded resources. * `thin`: returns the same set of top-level ticket fields, but embedded relations are collapsed to their IDs only. Use `thin` when you are listing many tickets and only need identifiers plus core scalar fields, for example when building a dashboard, exporting data, or feeding another system that will fetch full details on demand. If you need more than IDs for related resources when using `thin`, fetch the related record separately with its own endpoint (for example, `GET /queues/{id}` or `GET /statuses`). ### Rate limits The API enforces rate limits to ensure fair usage. If you exceed the limit, you'll receive a `429 Too Many Requests` response. Wait before retrying your request. ### Common error codes Every error response uses the JSON envelope shown in [Response format](#response-format). The HTTP status maps to the following categories: * `400 Bad Request`: Request body or query parameters are malformed or missing required fields * `401 Unauthorized`: Invalid or missing API key * `403 Forbidden`: Valid API key but insufficient permissions for the requested action * `404 Not Found`: Resource does not exist or is not visible to your API key * `409 Conflict`: Request conflicts with the current state of the resource (for example, a duplicate) * `422 Unprocessable Entity`: Request is well-formed but fails validation * `429 Too Many Requests`: Rate limit exceeded, wait before retrying * `500 Internal Server Error`: Server error, contact support if persistent # Create or update a reminder policy for the workspace Source: https://docs.ravenna.ai/api/reminder-policy/create-or-update-a-reminder-policy-for-the-workspace https://core.api.ravenna.ai/openapi.json put /reminder-policies # List reminder policies for the workspace Source: https://docs.ravenna.ai/api/reminder-policy/list-reminder-policies-for-the-workspace https://core.api.ravenna.ai/openapi.json get /reminder-policies # Bulk update relationships of request type custom fields Source: https://docs.ravenna.ai/api/request-type-custom-fields/bulk-update-relationships-of-request-type-custom-fields https://core.api.ravenna.ai/openapi.json put /request-type-custom-fields/relationships # Create a new request type custom field Source: https://docs.ravenna.ai/api/request-type-custom-fields/create-a-new-request-type-custom-field https://core.api.ravenna.ai/openapi.json post /request-type-custom-fields # Create a request type custom field and auto-create its dependent fields atomically Source: https://docs.ravenna.ai/api/request-type-custom-fields/create-a-request-type-custom-field-and-auto-create-its-dependent-fields-atomically https://core.api.ravenna.ai/openapi.json post /request-type-custom-fields/with-auto-chain # Create dependent request type custom fields Source: https://docs.ravenna.ai/api/request-type-custom-fields/create-dependent-request-type-custom-fields https://core.api.ravenna.ai/openapi.json post /request-type-custom-fields/dependent # Delete a request type custom field Source: https://docs.ravenna.ai/api/request-type-custom-fields/delete-a-request-type-custom-field https://core.api.ravenna.ai/openapi.json delete /request-type-custom-fields/{id} # Get request type custom field by ID Source: https://docs.ravenna.ai/api/request-type-custom-fields/get-request-type-custom-field-by-id https://core.api.ravenna.ai/openapi.json get /request-type-custom-fields/{id} # List request type custom fields Source: https://docs.ravenna.ai/api/request-type-custom-fields/list-request-type-custom-fields https://core.api.ravenna.ai/openapi.json get /request-type-custom-fields # Update a request type custom field Source: https://docs.ravenna.ai/api/request-type-custom-fields/update-a-request-type-custom-field https://core.api.ravenna.ai/openapi.json put /request-type-custom-fields/{id} # Update orders of request type custom fields Source: https://docs.ravenna.ai/api/request-type-custom-fields/update-orders-of-request-type-custom-fields https://core.api.ravenna.ai/openapi.json put /request-type-custom-fields/orders # Validate relationship between request type custom fields Source: https://docs.ravenna.ai/api/request-type-custom-fields/validate-relationship-between-request-type-custom-fields https://core.api.ravenna.ai/openapi.json get /request-type-custom-fields/validate-relationship # Archive request types with reparenting in a single transaction Source: https://docs.ravenna.ai/api/request-types/archive-request-types-with-reparenting-in-a-single-transaction https://core.api.ravenna.ai/openapi.json post /request-types/bulk-archive # Bulk delete request types Source: https://docs.ravenna.ai/api/request-types/bulk-delete-request-types https://core.api.ravenna.ai/openapi.json delete /request-types/bulk # Bulk move request types or collections into another collection Source: https://docs.ravenna.ai/api/request-types/bulk-move-request-types-or-collections-into-another-collection https://core.api.ravenna.ai/openapi.json post /request-types/bulk-move # Bulk update request types Source: https://docs.ravenna.ai/api/request-types/bulk-update-request-types https://core.api.ravenna.ai/openapi.json put /request-types/bulk # Create a new request type Source: https://docs.ravenna.ai/api/request-types/create-a-new-request-type https://core.api.ravenna.ai/openapi.json post /request-types # Delete a request type Source: https://docs.ravenna.ai/api/request-types/delete-a-request-type https://core.api.ravenna.ai/openapi.json delete /request-types/{id} # Disable public form access Source: https://docs.ravenna.ai/api/request-types/disable-public-form-access https://core.api.ravenna.ai/openapi.json post /request-types/{id}/public-access/disable # Duplicate a request type to another workspace within the same organization Source: https://docs.ravenna.ai/api/request-types/duplicate-a-request-type-to-another-workspace-within-the-same-organization https://core.api.ravenna.ai/openapi.json post /request-types/duplicate # Enable public form access Source: https://docs.ravenna.ai/api/request-types/enable-public-form-access https://core.api.ravenna.ai/openapi.json post /request-types/{id}/public-access/enable # Get request type by ID Source: https://docs.ravenna.ai/api/request-types/get-request-type-by-id https://core.api.ravenna.ai/openapi.json get /request-types/{id} # Get ticket count for a request type Source: https://docs.ravenna.ai/api/request-types/get-ticket-count-for-a-request-type https://core.api.ravenna.ai/openapi.json get /request-types/{id}/ticket-count # List request types Source: https://docs.ravenna.ai/api/request-types/list-request-types https://core.api.ravenna.ai/openapi.json get /request-types # Move a request type or collection into another collection Source: https://docs.ravenna.ai/api/request-types/move-a-request-type-or-collection-into-another-collection https://core.api.ravenna.ai/openapi.json post /request-types/move # Rotate public form token Source: https://docs.ravenna.ai/api/request-types/rotate-public-form-token https://core.api.ravenna.ai/openapi.json post /request-types/{id}/public-access/rotate # Update a request type Source: https://docs.ravenna.ai/api/request-types/update-a-request-type https://core.api.ravenna.ai/openapi.json put /request-types/{id} # Update a request type status Source: https://docs.ravenna.ai/api/request-types/update-a-request-type-status https://core.api.ravenna.ai/openapi.json post /request-types/{id}/status # Upload an icon image for a request type Source: https://docs.ravenna.ai/api/request-types/upload-an-icon-image-for-a-request-type https://core.api.ravenna.ai/openapi.json post /request-types/upload-icon-image # Reset a single approval round (e.g. policy change mid-flight) Source: https://docs.ravenna.ai/api/reset-a-single-approval-round-eg-policy-change-mid-flight https://core.api.ravenna.ai/openapi.json post /ticket-approval-rounds/reset-round # Attach a rule to an agent Source: https://docs.ravenna.ai/api/rules/attach-a-rule-to-an-agent https://core.api.ravenna.ai/openapi.json post /agents/{agentId}/rules/{ruleId}/attach # Bulk detach and delete rules Source: https://docs.ravenna.ai/api/rules/bulk-detach-and-delete-rules https://core.api.ravenna.ai/openapi.json delete /rules/bulk # Create a new rule Source: https://docs.ravenna.ai/api/rules/create-a-new-rule https://core.api.ravenna.ai/openapi.json post /rules # Delete a rule Source: https://docs.ravenna.ai/api/rules/delete-a-rule https://core.api.ravenna.ai/openapi.json delete /rules/{id} # Detach a rule from all agents and delete it Source: https://docs.ravenna.ai/api/rules/detach-a-rule-from-all-agents-and-delete-it https://core.api.ravenna.ai/openapi.json delete /rules/{id}/detach-and-delete # Detach a rule from an agent Source: https://docs.ravenna.ai/api/rules/detach-a-rule-from-an-agent https://core.api.ravenna.ai/openapi.json delete /agents/{agentId}/rules/{ruleId} # Duplicate an agent rule to another agent Source: https://docs.ravenna.ai/api/rules/duplicate-an-agent-rule-to-another-agent https://core.api.ravenna.ai/openapi.json post /agents/rules/{ruleId}/duplicate # Get a rule by ID Source: https://docs.ravenna.ai/api/rules/get-a-rule-by-id https://core.api.ravenna.ai/openapi.json get /rules/{id} # List all rules in a workspace Source: https://docs.ravenna.ai/api/rules/list-all-rules-in-a-workspace https://core.api.ravenna.ai/openapi.json get /rules # List rules attached to an agent Source: https://docs.ravenna.ai/api/rules/list-rules-attached-to-an-agent https://core.api.ravenna.ai/openapi.json get /agents/{agentId}/rules # Update an existing rule Source: https://docs.ravenna.ai/api/rules/update-an-existing-rule https://core.api.ravenna.ai/openapi.json put /rules/{id} # Update the rule relation on an agent (e.g., enable/disable) Source: https://docs.ravenna.ai/api/rules/update-the-rule-relation-on-an-agent-eg-enabledisable https://core.api.ravenna.ai/openapi.json put /agents/{agentId}/rules/{ruleId} # List slack channels Source: https://docs.ravenna.ai/api/slack-channel/list-slack-channels https://core.api.ravenna.ai/openapi.json get /slack-channels # Get Slack thread message and channel info by thread_ts Source: https://docs.ravenna.ai/api/slack-thread/get-slack-thread-message-and-channel-info-by-thread_ts https://core.api.ravenna.ai/openapi.json get /slack-threads/by-thread-ts # Get all Slack apps for organization Source: https://docs.ravenna.ai/api/slack/get-all-slack-apps-for-organization https://core.api.ravenna.ai/openapi.json get /slack/apps # Get Slack channels for an app Source: https://docs.ravenna.ai/api/slack/get-slack-channels-for-an-app https://core.api.ravenna.ai/openapi.json get /slack/channels # Immediately sync the current user Slack status Source: https://docs.ravenna.ai/api/slack/immediately-sync-the-current-user-slack-status https://core.api.ravenna.ai/openapi.json post /slack/sync-my-status # Create a new snippet Source: https://docs.ravenna.ai/api/snippets/create-a-new-snippet https://core.api.ravenna.ai/openapi.json post /snippets # Delete a snippet Source: https://docs.ravenna.ai/api/snippets/delete-a-snippet https://core.api.ravenna.ai/openapi.json delete /snippets/{id} # Get a single snippet by ID Source: https://docs.ravenna.ai/api/snippets/get-a-single-snippet-by-id https://core.api.ravenna.ai/openapi.json get /snippets/{id} # List snippets with optional filters Source: https://docs.ravenna.ai/api/snippets/list-snippets-with-optional-filters https://core.api.ravenna.ai/openapi.json get /snippets # Update a snippet Source: https://docs.ravenna.ai/api/snippets/update-a-snippet https://core.api.ravenna.ai/openapi.json put /snippets/{id} # Create a status Source: https://docs.ravenna.ai/api/status/create-a-status https://core.api.ravenna.ai/openapi.json post /statuses # Delete a status Source: https://docs.ravenna.ai/api/status/delete-a-status https://core.api.ravenna.ai/openapi.json delete /statuses # Get status by id Source: https://docs.ravenna.ai/api/status/get-status-by-id https://core.api.ravenna.ai/openapi.json get /statuses/{id} # Get ticket counts by status Source: https://docs.ravenna.ai/api/status/get-ticket-counts-by-status https://core.api.ravenna.ai/openapi.json get /statuses/ticket-counts # List statuses Source: https://docs.ravenna.ai/api/status/list-statuses https://core.api.ravenna.ai/openapi.json get /statuses # Update a status Source: https://docs.ravenna.ai/api/status/update-a-status https://core.api.ravenna.ai/openapi.json put /statuses # Create a tag Source: https://docs.ravenna.ai/api/tags/create-a-tag https://core.api.ravenna.ai/openapi.json post /tags # Delete a tag Source: https://docs.ravenna.ai/api/tags/delete-a-tag https://core.api.ravenna.ai/openapi.json delete /tags/{id} # Delete multiple tags Source: https://docs.ravenna.ai/api/tags/delete-multiple-tags https://core.api.ravenna.ai/openapi.json delete /tags/bulk # List ticket tags Source: https://docs.ravenna.ai/api/tags/list-ticket-tags https://core.api.ravenna.ai/openapi.json get /tags # Update a tag Source: https://docs.ravenna.ai/api/tags/update-a-tag https://core.api.ravenna.ai/openapi.json put /tags/{id} # Get Teams message and channel info by channel id + message id Source: https://docs.ravenna.ai/api/teams-conversation/get-teams-message-and-channel-info-by-channel-id-+-message-id https://core.api.ravenna.ai/openapi.json get /teams-conversations/by-message # Add an approver to a round Source: https://docs.ravenna.ai/api/ticket-approval-round-approver/add-an-approver-to-a-round https://core.api.ravenna.ai/openapi.json post /ticket-approval-round-approvers # Approve on a round Source: https://docs.ravenna.ai/api/ticket-approval-round-approver/approve-on-a-round https://core.api.ravenna.ai/openapi.json post /ticket-approval-round-approvers/{id}/approve # Decline on a round Source: https://docs.ravenna.ai/api/ticket-approval-round-approver/decline-on-a-round https://core.api.ravenna.ai/openapi.json post /ticket-approval-round-approvers/{id}/decline # Get a ticket approval round approver Source: https://docs.ravenna.ai/api/ticket-approval-round-approver/get-a-ticket-approval-round-approver https://core.api.ravenna.ai/openapi.json get /ticket-approval-round-approvers/{id} # List approvers for a round Source: https://docs.ravenna.ai/api/ticket-approval-round-approver/list-approvers-for-a-round https://core.api.ravenna.ai/openapi.json get /ticket-approval-round-approvers # Remove an approver from a round Source: https://docs.ravenna.ai/api/ticket-approval-round-approver/remove-an-approver-from-a-round https://core.api.ravenna.ai/openapi.json delete /ticket-approval-round-approvers/{id} # Create ticket approval rounds Source: https://docs.ravenna.ai/api/ticket-approval-round/create-ticket-approval-rounds https://core.api.ravenna.ai/openapi.json post /ticket-approval-rounds # Delete a ticket approval round Source: https://docs.ravenna.ai/api/ticket-approval-round/delete-a-ticket-approval-round https://core.api.ravenna.ai/openapi.json delete /ticket-approval-rounds/{id} # Force approve all approval rounds for a ticket (workspace admin only) Source: https://docs.ravenna.ai/api/ticket-approval-round/force-approve-all-approval-rounds-for-a-ticket-workspace-admin-only https://core.api.ravenna.ai/openapi.json post /ticket-approval-rounds/force-approve # Get a ticket approval round Source: https://docs.ravenna.ai/api/ticket-approval-round/get-a-ticket-approval-round https://core.api.ravenna.ai/openapi.json get /ticket-approval-rounds/{id} # Get ticket approval rounds Source: https://docs.ravenna.ai/api/ticket-approval-round/get-ticket-approval-rounds https://core.api.ravenna.ai/openapi.json get /ticket-approval-rounds # Kickoff the approval process for a ticket Source: https://docs.ravenna.ai/api/ticket-approval-round/kickoff-the-approval-process-for-a-ticket https://core.api.ravenna.ai/openapi.json post /ticket-approval-rounds/kickoff # Reset the approval process for a ticket (workspace admin only) Source: https://docs.ravenna.ai/api/ticket-approval-round/reset-the-approval-process-for-a-ticket-workspace-admin-only https://core.api.ravenna.ai/openapi.json post /ticket-approval-rounds/reset-approval # Sync (create/update/delete) all rounds for a ticket in bulk Source: https://docs.ravenna.ai/api/ticket-approval-round/sync-createupdatedelete-all-rounds-for-a-ticket-in-bulk https://core.api.ravenna.ai/openapi.json post /ticket-approval-rounds/sync # Update ticket approval rounds Source: https://docs.ravenna.ai/api/ticket-approval-round/update-ticket-approval-rounds https://core.api.ravenna.ai/openapi.json put /ticket-approval-rounds # Archive attachments from a ticket Source: https://docs.ravenna.ai/api/ticket-attachments/archive-attachments-from-a-ticket https://core.api.ravenna.ai/openapi.json post /tickets/attachments/archive # Connect uploaded attachments to a ticket or message Source: https://docs.ravenna.ai/api/ticket-attachments/connect-uploaded-attachments-to-a-ticket-or-message https://core.api.ravenna.ai/openapi.json post /tickets/attachments/connect # Create a ticket attachment with upload URL Source: https://docs.ravenna.ai/api/ticket-attachments/create-a-ticket-attachment-with-upload-url https://core.api.ravenna.ai/openapi.json post /tickets/attachments # List attachments for a ticket Source: https://docs.ravenna.ai/api/ticket-attachments/list-attachments-for-a-ticket https://core.api.ravenna.ai/openapi.json get /tickets/attachments # Check for existing ticket clusters Source: https://docs.ravenna.ai/api/ticket-clustering/check-for-existing-ticket-clusters https://core.api.ravenna.ai/openapi.json post /ticket-clustering/clusters/check Checks if clusters exist for the given filters without triggering generation # Generate or retrieve ticket clusters based on filter conditions Source: https://docs.ravenna.ai/api/ticket-clustering/generate-or-retrieve-ticket-clusters-based-on-filter-conditions https://core.api.ravenna.ai/openapi.json post /ticket-clustering/clusters/generate Generates ticket clusters from filter conditions or returns cached results if available within 24 hours # Get L1 sub-clusters for a specific L0 cluster Source: https://docs.ravenna.ai/api/ticket-clustering/get-l1-sub-clusters-for-a-specific-l0-cluster https://core.api.ravenna.ai/openapi.json get /ticket-clustering/clusters/l0/{workflowId}/l1 Fetches L1 clusters with ticket lists for a given L0 cluster ID # Get status of a ticket clustering job Source: https://docs.ravenna.ai/api/ticket-clustering/get-status-of-a-ticket-clustering-job https://core.api.ravenna.ai/openapi.json get /ticket-clustering/jobs/{workflowId}/status Retrieves the current status and results of a ticket clustering job by workflow ID # Get tickets for a specific L1 cluster Source: https://docs.ravenna.ai/api/ticket-clustering/get-tickets-for-a-specific-l1-cluster https://core.api.ravenna.ai/openapi.json get /ticket-clustering/clusters/l1/{workflowId}/tickets Fetches paginated ticket details for tickets in an L1 cluster # Create or update the workspace's ticket inactivity policy Source: https://docs.ravenna.ai/api/ticket-inactivity/create-or-update-the-workspaces-ticket-inactivity-policy https://core.api.ravenna.ai/openapi.json put /ticket-inactivity-policy # Get the workspace's ticket inactivity policy Source: https://docs.ravenna.ai/api/ticket-inactivity/get-the-workspaces-ticket-inactivity-policy https://core.api.ravenna.ai/openapi.json get /ticket-inactivity-policy # Create a ticket link Source: https://docs.ravenna.ai/api/ticket-link/create-a-ticket-link https://core.api.ravenna.ai/openapi.json post /ticket-links # Delete a ticket link Source: https://docs.ravenna.ai/api/ticket-link/delete-a-ticket-link https://core.api.ravenna.ai/openapi.json delete /ticket-links/{id} # Fetch URL metadata (title) from a given URL Source: https://docs.ravenna.ai/api/ticket-link/fetch-url-metadata-title-from-a-given-url https://core.api.ravenna.ai/openapi.json post /ticket-links/url-metadata # Get a ticket link Source: https://docs.ravenna.ai/api/ticket-link/get-a-ticket-link https://core.api.ravenna.ai/openapi.json get /ticket-links/{id} # Get ticket links Source: https://docs.ravenna.ai/api/ticket-link/get-ticket-links https://core.api.ravenna.ai/openapi.json get /ticket-links # Update a ticket link Source: https://docs.ravenna.ai/api/ticket-link/update-a-ticket-link https://core.api.ravenna.ai/openapi.json put /ticket-links/{id} # Create a ticket message Source: https://docs.ravenna.ai/api/ticket-message/create-a-ticket-message https://core.api.ravenna.ai/openapi.json post /ticket-messages # Delete a ticket message Source: https://docs.ravenna.ai/api/ticket-message/delete-a-ticket-message https://core.api.ravenna.ai/openapi.json delete /ticket-messages/{id} # Get a ticket message by ID Source: https://docs.ravenna.ai/api/ticket-message/get-a-ticket-message-by-id https://core.api.ravenna.ai/openapi.json get /ticket-messages/{id} # Get ticket messages Source: https://docs.ravenna.ai/api/ticket-message/get-ticket-messages https://core.api.ravenna.ai/openapi.json get /ticket-messages # Update a ticket message Source: https://docs.ravenna.ai/api/ticket-message/update-a-ticket-message https://core.api.ravenna.ai/openapi.json put /ticket-messages/{id} # Bulk move tickets Source: https://docs.ravenna.ai/api/ticket/bulk-move-tickets https://core.api.ravenna.ai/openapi.json post /tickets/bulk-move # Bulk share tickets Source: https://docs.ravenna.ai/api/ticket/bulk-share-tickets https://core.api.ravenna.ai/openapi.json post /tickets/bulk-share # Count tickets Source: https://docs.ravenna.ai/api/ticket/count-tickets https://core.api.ravenna.ai/openapi.json get /tickets/count Count tickets matching the given filters. By default, tickets in Done or Closed status groups are excluded. Set openFilter=false to count all tickets regardless of status group. # Create a ticket Source: https://docs.ravenna.ai/api/ticket/create-a-ticket https://core.api.ravenna.ai/openapi.json post /tickets # Create multiple tickets in bulk Source: https://docs.ravenna.ai/api/ticket/create-multiple-tickets-in-bulk https://core.api.ravenna.ai/openapi.json post /tickets/bulk # Delete a ticket Source: https://docs.ravenna.ai/api/ticket/delete-a-ticket https://core.api.ravenna.ai/openapi.json delete /tickets/{id} # Export tickets to CSV Source: https://docs.ravenna.ai/api/ticket/export-tickets-to-csv https://core.api.ravenna.ai/openapi.json post /tickets/export # Find potential duplicate tickets based on semantic similarity and filters Source: https://docs.ravenna.ai/api/ticket/find-potential-duplicate-tickets-based-on-semantic-similarity-and-filters https://core.api.ravenna.ai/openapi.json get /tickets/find-duplicates # Generate a KB article from a ticket conversation Source: https://docs.ravenna.ai/api/ticket/generate-a-kb-article-from-a-ticket-conversation https://core.api.ravenna.ai/openapi.json post /tickets/generate-kb-article # Get all descendent tickets recursively for given ticket IDs Source: https://docs.ravenna.ai/api/ticket/get-all-descendent-tickets-recursively-for-given-ticket-ids https://core.api.ravenna.ai/openapi.json post /tickets/descendent-tickets # Get formatted custom fields for a ticket Source: https://docs.ravenna.ai/api/ticket/get-formatted-custom-fields-for-a-ticket https://core.api.ravenna.ai/openapi.json get /tickets/{ticketId}/custom-fields # Get minimal ticket summary by URL identifier Source: https://docs.ravenna.ai/api/ticket/get-minimal-ticket-summary-by-url-identifier https://core.api.ravenna.ai/openapi.json get /tickets/summary/{identifier} # Get ticket by id, shortId, or PREFIX-NUMBER format Source: https://docs.ravenna.ai/api/ticket/get-ticket-by-id-shortid-or-prefix-number-format https://core.api.ravenna.ai/openapi.json get /tickets/{id} # Get ticket by URL identifier (unified endpoint for all formats) Source: https://docs.ravenna.ai/api/ticket/get-ticket-by-url-identifier-unified-endpoint-for-all-formats https://core.api.ravenna.ai/openapi.json get /tickets/by-url/{identifier} # Get unified KB article status including existing articles and job progress Source: https://docs.ravenna.ai/api/ticket/get-unified-kb-article-status-including-existing-articles-and-job-progress https://core.api.ravenna.ai/openapi.json get /tickets/kb-article-status # List an agent's scheduled rule runs Source: https://docs.ravenna.ai/api/ticket/list-an-agents-scheduled-rule-runs https://core.api.ravenna.ai/openapi.json get /tickets/scheduled-runs # List tickets Source: https://docs.ravenna.ai/api/ticket/list-tickets https://core.api.ravenna.ai/openapi.json get /tickets List and search tickets with filtering, sorting, and pagination. By default, tickets in Done or Closed status groups are excluded. Set openFilter=false to include all tickets regardless of status group. # List tickets for chatlog with computed fields Source: https://docs.ravenna.ai/api/ticket/list-tickets-for-chatlog-with-computed-fields https://core.api.ravenna.ai/openapi.json get /tickets/chatlog # List tickets whose asset custom field holds an asset Source: https://docs.ravenna.ai/api/ticket/list-tickets-whose-asset-custom-field-holds-an-asset https://core.api.ravenna.ai/openapi.json get /tickets/by-asset/{assetId} # Manually trigger auto-tagging for a ticket Source: https://docs.ravenna.ai/api/ticket/manually-trigger-auto-tagging-for-a-ticket https://core.api.ravenna.ai/openapi.json post /tickets/{id}/auto-tag # Merge one or more source tickets into a primary ticket Source: https://docs.ravenna.ai/api/ticket/merge-one-or-more-source-tickets-into-a-primary-ticket https://core.api.ravenna.ai/openapi.json post /tickets/merge # Move a ticket Source: https://docs.ravenna.ai/api/ticket/move-a-ticket https://core.api.ravenna.ai/openapi.json post /tickets/move # Reverse a ticket merge Source: https://docs.ravenna.ai/api/ticket/reverse-a-ticket-merge https://core.api.ravenna.ai/openapi.json post /tickets/unmerge # Search for semantically similar tickets Source: https://docs.ravenna.ai/api/ticket/search-for-semantically-similar-tickets https://core.api.ravenna.ai/openapi.json get /tickets/semantic-search # Share a ticket Source: https://docs.ravenna.ai/api/ticket/share-a-ticket https://core.api.ravenna.ai/openapi.json post /tickets/share/{id} # Submit a form to create or update a ticket Source: https://docs.ravenna.ai/api/ticket/submit-a-form-to-create-or-update-a-ticket https://core.api.ravenna.ai/openapi.json post /tickets/submit-form # unShare a ticket Source: https://docs.ravenna.ai/api/ticket/unshare-a-ticket https://core.api.ravenna.ai/openapi.json post /tickets/unshare/{id} # Update a ticket Source: https://docs.ravenna.ai/api/ticket/update-a-ticket https://core.api.ravenna.ai/openapi.json put /tickets/{id} # Ticket unread message counts Source: https://docs.ravenna.ai/api/tickets/ticket-unread-message-counts https://core.api.ravenna.ai/openapi.json get /tickets/unreadCounts # Create a user group Source: https://docs.ravenna.ai/api/user-group/create-a-user-group https://core.api.ravenna.ai/openapi.json post /user-groups # Delete a user group Source: https://docs.ravenna.ai/api/user-group/delete-a-user-group https://core.api.ravenna.ai/openapi.json delete /user-groups/{id} # Delete multiple user groups Source: https://docs.ravenna.ai/api/user-group/delete-multiple-user-groups https://core.api.ravenna.ai/openapi.json delete /user-groups/bulk # Get a user group Source: https://docs.ravenna.ai/api/user-group/get-a-user-group https://core.api.ravenna.ai/openapi.json get /user-groups/{id} # Get a user group with users Source: https://docs.ravenna.ai/api/user-group/get-a-user-group-with-users https://core.api.ravenna.ai/openapi.json get /user-groups/{id}/users # Get a user group with users and workspaces Source: https://docs.ravenna.ai/api/user-group/get-a-user-group-with-users-and-workspaces https://core.api.ravenna.ai/openapi.json get /user-groups/{id}/users-workspaces # Get user groups with integration source metadata Source: https://docs.ravenna.ai/api/user-group/get-user-groups-with-integration-source-metadata https://core.api.ravenna.ai/openapi.json get /user-groups # Get user groups with workspace assignments (for organization-level management) Source: https://docs.ravenna.ai/api/user-group/get-user-groups-with-workspace-assignments-for-organization-level-management https://core.api.ravenna.ai/openapi.json get /user-groups/with-workspaces # Update a user group Source: https://docs.ravenna.ai/api/user-group/update-a-user-group https://core.api.ravenna.ai/openapi.json put /user-groups/{id} # Block a user from signing in (admin only) Source: https://docs.ravenna.ai/api/user/block-a-user-from-signing-in-admin-only https://core.api.ravenna.ai/openapi.json post /users/{id}/block # Create a new user (admin only) Source: https://docs.ravenna.ai/api/user/create-a-new-user-admin-only https://core.api.ravenna.ai/openapi.json post /users # Get user by id Source: https://docs.ravenna.ai/api/user/get-user-by-id https://core.api.ravenna.ai/openapi.json get /users/{id} # List users Source: https://docs.ravenna.ai/api/user/list-users https://core.api.ravenna.ai/openapi.json get /users # Unblock a user (admin only) Source: https://docs.ravenna.ai/api/user/unblock-a-user-admin-only https://core.api.ravenna.ai/openapi.json post /users/{id}/unblock # Update a user Source: https://docs.ravenna.ai/api/user/update-a-user https://core.api.ravenna.ai/openapi.json put /users/{id} # Delete a WebAuthn credential Source: https://docs.ravenna.ai/api/webauthn/delete-a-webauthn-credential https://core.api.ravenna.ai/openapi.json delete /webauthn/credentials/{id} # Generate WebAuthn authentication options Source: https://docs.ravenna.ai/api/webauthn/generate-webauthn-authentication-options https://core.api.ravenna.ai/openapi.json post /webauthn/authentication-options # Generate WebAuthn registration options Source: https://docs.ravenna.ai/api/webauthn/generate-webauthn-registration-options https://core.api.ravenna.ai/openapi.json post /webauthn/registration-options # Get workspace biometric approval settings Source: https://docs.ravenna.ai/api/webauthn/get-workspace-biometric-approval-settings https://core.api.ravenna.ai/openapi.json get /webauthn/settings # List registered WebAuthn credentials Source: https://docs.ravenna.ai/api/webauthn/list-registered-webauthn-credentials https://core.api.ravenna.ai/openapi.json get /webauthn/credentials # Update workspace biometric approval settings Source: https://docs.ravenna.ai/api/webauthn/update-workspace-biometric-approval-settings https://core.api.ravenna.ai/openapi.json put /webauthn/settings # Verify WebAuthn authentication and get proof token Source: https://docs.ravenna.ai/api/webauthn/verify-webauthn-authentication-and-get-proof-token https://core.api.ravenna.ai/openapi.json post /webauthn/authentication-verify # Verify WebAuthn registration response Source: https://docs.ravenna.ai/api/webauthn/verify-webauthn-registration-response https://core.api.ravenna.ai/openapi.json post /webauthn/registration-verify # Create a new webhook Source: https://docs.ravenna.ai/api/webhooks/create-a-new-webhook https://core.api.ravenna.ai/openapi.json post /webhooks # Delete a webhook Source: https://docs.ravenna.ai/api/webhooks/delete-a-webhook https://core.api.ravenna.ai/openapi.json delete /webhooks/{id} # Get webhook by ID Source: https://docs.ravenna.ai/api/webhooks/get-webhook-by-id https://core.api.ravenna.ai/openapi.json get /webhooks/{id} # List webhooks Source: https://docs.ravenna.ai/api/webhooks/list-webhooks https://core.api.ravenna.ai/openapi.json get /webhooks # Update an existing webhook Source: https://docs.ravenna.ai/api/webhooks/update-an-existing-webhook https://core.api.ravenna.ai/openapi.json put /webhooks/{id} # Bulk delete workflow collections Source: https://docs.ravenna.ai/api/workflow-collections/bulk-delete-workflow-collections https://core.api.ravenna.ai/openapi.json delete /workflow-collections/bulk # Create a new workflow collection Source: https://docs.ravenna.ai/api/workflow-collections/create-a-new-workflow-collection https://core.api.ravenna.ai/openapi.json post /workflow-collections # Delete a workflow collection Source: https://docs.ravenna.ai/api/workflow-collections/delete-a-workflow-collection https://core.api.ravenna.ai/openapi.json delete /workflow-collections/{id} # Get a workflow collection Source: https://docs.ravenna.ai/api/workflow-collections/get-a-workflow-collection https://core.api.ravenna.ai/openapi.json get /workflow-collections/{id} # List all workflow collections in the workspace Source: https://docs.ravenna.ai/api/workflow-collections/list-all-workflow-collections-in-the-workspace https://core.api.ravenna.ai/openapi.json get /workflow-collections # List combined workflow collections and workflows Source: https://docs.ravenna.ai/api/workflow-collections/list-combined-workflow-collections-and-workflows https://core.api.ravenna.ai/openapi.json get /workflow-collections/list-all # Move a workflow or workflow collection into another collection Source: https://docs.ravenna.ai/api/workflow-collections/move-a-workflow-or-workflow-collection-into-another-collection https://core.api.ravenna.ai/openapi.json post /workflow-collections/move # Move multiple workflow resources into another collection Source: https://docs.ravenna.ai/api/workflow-collections/move-multiple-workflow-resources-into-another-collection https://core.api.ravenna.ai/openapi.json post /workflow-collections/move/bulk # Activate workflow Source: https://docs.ravenna.ai/api/workflow/activate-workflow https://core.api.ravenna.ai/openapi.json post /workflows/{id}/activate # Add step Source: https://docs.ravenna.ai/api/workflow/add-step https://core.api.ravenna.ai/openapi.json post /workflows/steps # Connect steps Source: https://docs.ravenna.ai/api/workflow/connect-steps https://core.api.ravenna.ai/openapi.json post /workflows/steps/connect # Create a workflow step attachment upload URL Source: https://docs.ravenna.ai/api/workflow/create-a-workflow-step-attachment-upload-url https://core.api.ravenna.ai/openapi.json post /workflows/attachments # Create workflow Source: https://docs.ravenna.ai/api/workflow/create-workflow https://core.api.ravenna.ai/openapi.json post /workflows # Deactivate workflow(s) Source: https://docs.ravenna.ai/api/workflow/deactivate-workflows https://core.api.ravenna.ai/openapi.json post /workflows/deactivate # Delete steps Source: https://docs.ravenna.ai/api/workflow/delete-steps https://core.api.ravenna.ai/openapi.json delete /workflows/steps # Delete workflow Source: https://docs.ravenna.ai/api/workflow/delete-workflow https://core.api.ravenna.ai/openapi.json delete /workflows/{id} # Delete workflows Source: https://docs.ravenna.ai/api/workflow/delete-workflows https://core.api.ravenna.ai/openapi.json delete /workflows/bulk # Disconnect steps Source: https://docs.ravenna.ai/api/workflow/disconnect-steps https://core.api.ravenna.ai/openapi.json post /workflows/steps/disconnect # Duplicate step Source: https://docs.ravenna.ai/api/workflow/duplicate-step https://core.api.ravenna.ai/openapi.json post /workflows/steps/duplicate # Duplicate workflow Source: https://docs.ravenna.ai/api/workflow/duplicate-workflow https://core.api.ravenna.ai/openapi.json post /workflows/duplicate # Duplicate workflow from template Source: https://docs.ravenna.ai/api/workflow/duplicate-workflow-from-template https://core.api.ravenna.ai/openapi.json post /workflows/templates/duplicate # Duplicate workflow to another workspace Source: https://docs.ravenna.ai/api/workflow/duplicate-workflow-to-another-workspace https://core.api.ravenna.ai/openapi.json post /workflows/duplicate-to-workspace # Fast-forward a waiting timer step Source: https://docs.ravenna.ai/api/workflow/fast-forward-a-waiting-timer-step https://core.api.ravenna.ai/openapi.json post /workflows/runs/{runId}/steps/{stepId}/fast-forward # Filter workflow runs Source: https://docs.ravenna.ai/api/workflow/filter-workflow-runs https://core.api.ravenna.ai/openapi.json post /workflows/runs # Get step Source: https://docs.ravenna.ai/api/workflow/get-step https://core.api.ravenna.ai/openapi.json get /workflow-config/{workflowId}/steps/{stepId} # Get template workflow Source: https://docs.ravenna.ai/api/workflow/get-template-workflow https://core.api.ravenna.ai/openapi.json get /workflows/templates/{id} # Get template workspace ID Source: https://docs.ravenna.ai/api/workflow/get-template-workspace-id https://core.api.ravenna.ai/openapi.json get /workflows/templates/workspace-id # Get workflow by id Source: https://docs.ravenna.ai/api/workflow/get-workflow-by-id https://core.api.ravenna.ai/openapi.json get /workflows/{id} # Get workflow config Source: https://docs.ravenna.ai/api/workflow/get-workflow-config https://core.api.ravenna.ai/openapi.json get /workflow-config/{id}/config # Get workflow run Source: https://docs.ravenna.ai/api/workflow/get-workflow-run https://core.api.ravenna.ai/openapi.json get /workflows/runs/{id} # List agent trigger workflows Source: https://docs.ravenna.ai/api/workflow/list-agent-trigger-workflows https://core.api.ravenna.ai/openapi.json get /workflows/manual # List apps with actions Source: https://docs.ravenna.ai/api/workflow/list-apps-with-actions https://core.api.ravenna.ai/openapi.json get /workflow-config/apps # List template workflows Source: https://docs.ravenna.ai/api/workflow/list-template-workflows https://core.api.ravenna.ai/openapi.json get /workflows/templates # List workflows Source: https://docs.ravenna.ai/api/workflow/list-workflows https://core.api.ravenna.ai/openapi.json get /workflows # Pause workflow(s) Source: https://docs.ravenna.ai/api/workflow/pause-workflows https://core.api.ravenna.ai/openapi.json post /workflows/pause # Reposition step Source: https://docs.ravenna.ai/api/workflow/reposition-step https://core.api.ravenna.ai/openapi.json post /workflows/steps/reposition # Resolve workflow step attachments to download URLs Source: https://docs.ravenna.ai/api/workflow/resolve-workflow-step-attachments-to-download-urls https://core.api.ravenna.ai/openapi.json post /workflows/attachments/resolve # Retry workflow run Source: https://docs.ravenna.ai/api/workflow/retry-workflow-run https://core.api.ravenna.ai/openapi.json post /workflows/runs/{runId}/retry # Revert workflow to version Source: https://docs.ravenna.ai/api/workflow/revert-workflow-to-version https://core.api.ravenna.ai/openapi.json post /workflows/revert # Run workflow Source: https://docs.ravenna.ai/api/workflow/run-workflow https://core.api.ravenna.ai/openapi.json post /workflows/{workflowId}/run # Save workflow as template Source: https://docs.ravenna.ai/api/workflow/save-workflow-as-template https://core.api.ravenna.ai/openapi.json post /workflows/templates/save # Update connection Source: https://docs.ravenna.ai/api/workflow/update-connection https://core.api.ravenna.ai/openapi.json put /workflows/steps # Update step Source: https://docs.ravenna.ai/api/workflow/update-step https://core.api.ravenna.ai/openapi.json put /workflows/steps/{id} # Update workflow Source: https://docs.ravenna.ai/api/workflow/update-workflow https://core.api.ravenna.ai/openapi.json put /workflows/{id} # Validate workflow Source: https://docs.ravenna.ai/api/workflow/validate-workflow https://core.api.ravenna.ai/openapi.json get /workflows/{id}/validate # List ticket attributes for the workspace Source: https://docs.ravenna.ai/api/workspace-custom-fields/list-ticket-attributes-for-the-workspace https://core.api.ravenna.ai/openapi.json get /workspace-custom-fields # Mark a custom field as a ticket attribute Source: https://docs.ravenna.ai/api/workspace-custom-fields/mark-a-custom-field-as-a-ticket-attribute https://core.api.ravenna.ai/openapi.json post /workspace-custom-fields # Remove a ticket attribute Source: https://docs.ravenna.ai/api/workspace-custom-fields/remove-a-ticket-attribute https://core.api.ravenna.ai/openapi.json delete /workspace-custom-fields/{id} # Update a ticket attribute (e.g. reorder) Source: https://docs.ravenna.ai/api/workspace-custom-fields/update-a-ticket-attribute-eg-reorder https://core.api.ravenna.ai/openapi.json put /workspace-custom-fields/{id} # Create a workspaces Source: https://docs.ravenna.ai/api/workspace/create-a-workspaces https://core.api.ravenna.ai/openapi.json post /workspaces # Deletes a workspaces Source: https://docs.ravenna.ai/api/workspace/deletes-a-workspaces https://core.api.ravenna.ai/openapi.json delete /workspaces/{id} # Get a workspaces Source: https://docs.ravenna.ai/api/workspace/get-a-workspaces https://core.api.ravenna.ai/openapi.json get /workspaces/{id} # List workspaces Source: https://docs.ravenna.ai/api/workspace/list-workspaces https://core.api.ravenna.ai/openapi.json get /workspaces # Updates a workspaces Source: https://docs.ravenna.ai/api/workspace/updates-a-workspaces https://core.api.ravenna.ai/openapi.json put /workspaces/{id} # Product Updates Source: https://docs.ravenna.ai/changelog/2024 Browse the 2024 archive of Ravenna product updates, including new features, platform improvements, integrations, performance work, and bug fixes. ## Secure OAuth for knowledge sources Connect knowledge bases with OAuth instead of API keys. Grant Ravenna access to specific documents in [Confluence](/integrations/confluence/knowledge), [Google Drive](/integrations/google-workspace/overview), and [Notion](/integrations/notion/knowledge) with a single click, so setup is faster and access stays scoped to what you choose to share. [Learn more →](/documentation/automate/knowledge/overview) ## Slack Home tab and automatic @-mention followers The Home tab in the Ravenna Slack app lets you view all your custom ticket lists without leaving Slack. When you @-mention a colleague in a ticket thread, they are now automatically added as a follower in Ravenna, so the right people stay in the loop. [Learn more →](/integrations/slack/app-home) ## Advanced view options and bulk actions The View Options menu lets you switch between list, table, and Kanban views and group tickets by any attribute, such as priority or status. Select multiple tickets at once to run bulk actions like changing status, priority, or assignee. [Learn more →](/documentation/tickets/organize/views) # Product Updates Source: https://docs.ravenna.ai/changelog/2025 Browse the 2025 archive of Ravenna product updates, including new features, platform improvements, integrations, performance work, and bug fixes. ## Expanded Slack actions Manage Slack user groups and channels directly from Ravenna, so workflows and agents can automate membership changes and channel requests and speed up team collaboration. [Learn more →](/integrations/slack/workflows) ## Workflow enhancements Duplicate or delete entire workflows, and send emails directly from a workflow as part of an automation. [Learn more →](/documentation/automate/workflows/workflow-builder) ## AI over email Your AI agent can now respond to requests over email, replying automatically to speed up resolution. [Learn more →](/integrations/email/overview) ## AI categories Ravenna automatically classifies every incoming request with AI, so teams can organize and analyze request volume without manual tagging. [Learn more →](/documentation/tickets/organize/categories) ## HubSpot integration Connect HubSpot to access and update CRM data from within Ravenna, so RevOps teams can resolve requests without switching tools. [Learn more →](/integrations/hubspot/overview) ## Jamf integration (preview) Connect Jamf to look up devices and run diagnostics directly from workflows and agent conversations. [Learn more →](/integrations/jamf/overview) ## PagerDuty integration Connect PagerDuty to confirm on-call coverage inside workflows, speeding up urgent access requests. [Learn more →](/integrations/pagerduty/overview) ## Application access levels Create custom access levels for applications to manage software access with more granularity across your organization. [Learn more →](/documentation/manage-access/applications) ## Slack work objects A clearer Slack interface for ticket management makes updates and edits faster. [Learn more →](/integrations/slack/overview) ## Notification center The Notification Center consolidates actionable events, tasks, and approvals in one place, so teams can track what needs attention. [Learn more →](/documentation/platform/notifications) ## Ticket link action A new workflow action attaches generated ticket links to requests for better visibility and resource management. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Task trigger updates Trigger actions automatically when a task completes, for smoother handoffs to the next owner. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Forms in the create modal Submit the correct ticket type from anywhere in Ravenna using forms in the quick-create modal. [Learn more →](/documentation/tickets/forms/overview) ## AI briefs Receive AI-generated summaries of your dashboards in Slack on a schedule you set. [Learn more →](/documentation/measure/analytics) ## Inline text formatting Format text with highlights for clearer, more readable messages and updates. ## Linear bi-directional sync Ravenna now syncs bi-directionally with Linear, keeping updates aligned between both systems. [Learn more →](/integrations/linear/ticket-replication) ## Notification defaults for teams Admins can set default notification settings for teams, so users get consistent alerts across workspaces without extra setup. [Learn more →](/documentation/platform/notifications) ## Custom prompt workflow action A new Custom Prompt action embeds generative reasoning directly into your workflows. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Wait for inactivity action A new Wait for Inactivity action helps manage idle tickets by pausing a workflow until activity stops. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Jira Service Management integration (early access) Connect Jira Service Management to automate ticket syncing between Ravenna and JSM. [Learn more →](/integrations/jira/overview) ## Linear action Escalate tickets from Ravenna to Linear to streamline handoffs between support and engineering. [Learn more →](/integrations/linear/overview) ## Workspace visibility in Slack Control which Ravenna workspaces appear in Slack to reduce clutter and focus on the ones that matter. [Learn more →](/integrations/slack/setup) ## Workflow run in ticket events Ticket events now show which workflow run caused an automated update, simplifying troubleshooting and auditing. [Learn more →](/documentation/automate/workflows/monitor) ## Multiple Slack channel connections Connect multiple Slack channels to a single queue for consistent request management across teams. [Learn more →](/integrations/slack/setup) ## Task templates Attach predefined task lists to tickets automatically for consistent, repeatable processes. [Learn more →](/documentation/tickets/tasks) ## New ticket creation modal A redesigned ticket creation modal makes creating tickets faster and clearer. ## Fleet integration Connect Fleet to access device information and run diagnostics directly from your workflows. [Learn more →](/integrations/fleet/overview) ## Google Workspace integration Sync Google Workspace groups with Ravenna to keep workflows aligned with your organization's structure and membership. [Learn more →](/integrations/google-workspace/overview) ## Tag Added workflow trigger A new Tag Added trigger automates ticket management when a tag is applied. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Auto-add followers on mention Teammates mentioned in comments or Slack threads are automatically added as followers, keeping everyone informed. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Ticket tasks Add task lists to tickets to track steps and accountability for repeatable processes. [Learn more →](/documentation/tickets/tasks) ## Move Ticket workflow action A new Move Ticket action re-routes tickets between workspaces to reduce delays and improve resolution times. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Slack notification preferences Customize Slack notifications to focus on the events that matter most to you. [Learn more →](/integrations/slack/overview) ## Custom field analytics Use custom fields in Analytics to filter and segment your request data. [Learn more →](/documentation/measure/analytics) ## Notion callout blocks in knowledge Notion callout blocks now import into Ravenna knowledge, so key information is captured for search and analysis. [Learn more →](/integrations/notion/knowledge) ## AI image processing Upload images and have AI interpret them for insights and explanations in your workflows. [Learn more →](/documentation/automate/agents/overview) ## Approvals in Slack Manage pending approvals directly in Slack with approve and decline buttons. [Learn more →](/documentation/tickets/approvals/overview) ## Form folders Organize forms into folders for easier navigation, so your team can find and use the right request faster. [Learn more →](/documentation/tickets/forms/overview) ## Service Level Agreements Set clear response and resolution expectations and track performance against them with SLAs. [Learn more →](/documentation/automate/slas) ## Attachments on tickets Add and manage files and images on tickets to keep relevant information organized. ## UI themes Customize your workspace with themes that offer adjustable brightness and color options. ## New user onboarding resources New onboarding resources help teams adopt Ravenna with customizable announcements and user handbooks. [Learn more →](/documentation/get-started/overview) ## Okta applications in workflows Okta applications are now fully integrated for access management in Ravenna workflows. [Learn more →](/integrations/okta/overview) ## Incident.io integration Connect Incident.io to streamline on-call access and speed up incident response. [Learn more →](/integrations/incident-io/overview) ## Filter select resources in form fields Admins can allowlist resources in form fields to simplify options and reduce errors for requesters. [Learn more →](/documentation/tickets/forms/custom-fields) ## Multiple application approvers Applications now support multiple approvers for access requests, improving control and collaboration. [Learn more →](/documentation/manage-access/applications) ## Duplicate workflow Duplicate workflows to save time and keep variations consistent across teams. [Learn more →](/documentation/automate/workflows/workflow-builder) ## Approval workflow trigger A new trigger runs actions automatically based on a ticket's approval decision. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Slack link unfurls Ravenna ticket links shared in Slack now unfurl with live ticket details, keeping discussions informed. [Learn more →](/integrations/slack/overview) ## /rav command updates The /rav Slack command now lets you manage your tickets and approvals directly in Slack. [Learn more →](/integrations/slack/slash-commands) ## Ravenna documentation site The revamped documentation site launched with faster navigation and clearer content. [Learn more →](/documentation/get-started/overview) ## Enhanced dashboard widgets Redesigned dashboard widgets give clearer insights and better data tracking to help teams make faster decisions. [Learn more →](/documentation/measure/analytics) ## Index and learn from entire Slack channels Add an entire Slack channel as a knowledge source. Ravenna securely indexes the historical question-and-answer pairs from threads, making that collective knowledge available to power AI responses. [Learn more →](/integrations/slack/knowledge) ## Workflow Builder The visual Workflow Builder lets you create custom automations from triggers and actions. [Learn more →](/documentation/automate/workflows/workflow-builder) ## Knowledge base folders Group knowledge documents from sources like Google Drive, Notion, and Coda into folders, set automatic daily syncs, and use the chat panel to test AI responses against specific knowledge sets. [Learn more →](/documentation/automate/knowledge/overview) ## Major AI and workflow enhancements A release packed with features to make Ravenna smarter and more automated across AI and workflows. [Learn more →](/documentation/automate/workflows/overview) ## CSAT surveys When a ticket is resolved, Ravenna can send a customer satisfaction survey to the requester's Slack DM, letting them rate the interaction and add comments. [Learn more →](/documentation/measure/analytics) ## Approval capabilities Approval capabilities add built-in review steps to your ticketing workflows. [Learn more →](/documentation/tickets/approvals/overview) ## Advanced filtering options Filter tickets using date ranges and more specific operators like "is not one of." [Learn more →](/documentation/tickets/organize/views) ## Snoozing tickets Snooze tickets until a chosen date to temporarily hide them from your queue. They reappear on the selected date so nothing is missed. [Learn more →](/documentation/tickets/organize/views) ## Group by dates Group tickets by date fields such as created, updated, due, or start, with day, week, month, or year granularity. [Learn more →](/documentation/tickets/organize/views) ## Inbound email support Assign a dedicated email address to each queue so incoming emails create tickets automatically, and replies are returned to the original sender. [Learn more →](/integrations/email/overview) ## Sub-tickets and ticket links Create sub-tickets from a parent ticket to delegate work, and add external URLs as ticket links to bookmark resources like GitHub repos or design files. [Learn more →](/documentation/tickets/relations) # Product Updates Source: https://docs.ravenna.ai/changelog/2026 Track the latest 2026 Ravenna product updates, including new features, platform improvements, integration releases, and notable bug fixes. ## A new Slack DM experience The Slack app icon on a soft gradient background Chatting with your [agent](/documentation/automate/agents/overview) in Slack now looks and feels like a regular direct message. Slack is retiring its assistant messaging experience, so the separate history tab and new chat button are gone. Your conversations live in Slack's standard message tab, and the agent replies in-thread, so every request keeps its own context. Tickets created from Slack without a specific channel, including direct messages, route to a dedicated **Slack** channel in Ravenna, which is now always visible in your workspace. The channel is named **Slack** in every workspace, and existing workspaces are updated automatically, so there is nothing to rename yourself. New workspaces also get **Web** as the name of the default channel. Setup is simpler too: * Routing follows agent presence. Connect an agent to a channel and DM conversations route to it. Visibility settings no longer affect routing, and connecting an agent no longer changes them. * Visibility settings live in one place: a **Visibility** card in **Workspace Settings > General** with two toggles, **Available in Slack** and **Available in Portal**, that control where the workspace appears when filing tickets from the Slack home tab or the portal. [Learn more →](/integrations/slack/direct-messages) ## Approvals leave the requester out A new **Allow requester as approver** switch in workspace [approval settings](/documentation/tickets/approvals/overview#workspace-settings) decides whether a ticket's requester can sit on their own approval rounds. It is off by default, so the requester is stripped from every round, even when the thing that pulled them in was an approver group they belong to. Groups expand first and the requester is removed after, so there is no gap to police by hand. The rule applies the same way in the ticket sidebar, the approval rounds UI, workflows, and forms. Turn it on when self-approval is legitimate for your team. [Learn more →](/documentation/tickets/approvals/overview#workspace-settings) **Quality of life updates:** **Copilot:** * [Copilot](/documentation/automate/copilot/using-copilot) shows its reasoning while it works on a reply: a short summary of its thinking, interleaved with tool activity. The thinking section streams in collapsed, so a long turn shows where it is headed instead of going quiet, and you can expand it to follow along or leave it closed. * Searching your [Copilot](/documentation/automate/copilot/using-copilot) chat history now searches all of your past chats, not just the ones already loaded in the sidebar. * [Copilot](/documentation/automate/copilot/build-automations) keeps a visible plan while it builds an automation and updates each step as it finishes. * Ask [Copilot](/documentation/automate/copilot/configure-workspace#outbound-webhooks) to list, create, and update the outbound webhooks that deliver workspace events to an external endpoint, and to pause or resume delivery. Each webhook appears as a card in chat, and the signing secret is entered in a masked field on that card rather than in the message box, so Copilot never sees it. Workspace admins only. * [Copilot](/documentation/automate/copilot/using-copilot) can update an existing [Foundry](/documentation/automate/foundry/integrations) integration's name, base URL, and auth settings, instead of only creating new ones. * A long attachment list in a [Copilot](/documentation/automate/copilot/using-copilot) chat collapses behind a show more button. **Foundry:** * Point a [Foundry](/documentation/automate/foundry/using-actions) function's secret input at a [Vault](/documentation/platform/organizations/vault#foundry-function-secret-inputs) credential instead of pasting the value. The workflow stores only the reference, Ravenna decrypts it in memory at run time and scrubs it from execution logs, and it works for secret fields nested inside objects and arrays. * When a secret input is not configured yet, the [agent](/documentation/automate/agents/overview) says which step it could not run instead of substituting another tool. * When an API's documentation does not cover the endpoint you asked for, [Foundry](/documentation/automate/foundry/actions) names the gap so you can point it at the right docs, instead of failing without an explanation. * The [Foundry](/documentation/automate/foundry/integrations) credential setup card in Copilot chat has a cleaner layout. **Everywhere else:** * The new **SLA Target Outcome** [ticket filter](/documentation/automate/slas) binds one target to one outcome in a single value, such as **Time to First Response met** or **Time to Resolution breached**. Stack two conditions to find tickets that met one target but breached another, which the separate target and outcome filters cannot express. It works in ticket lists, saved views, [analytics](/documentation/measure/analytics) widget conditions, and dashboard filters. * Connect [Gusto](/integrations/gusto/overview) as an HRIS to sync employees, departments, and time off into Ravenna, then use its [workflow actions](/integrations/gusto/workflows) to check a time off balance or file a request from a ticket. * [Okta setup](/integrations/okta/setup/overview) now opens with a comparison of the client secret and private key methods, and spells out every API scope the OIN app grants and what Ravenna uses it for. You can also switch a live integration from private key to client secret with **Update Credentials**, keeping the same integration ID with no resync. * The **HTTP Request** [workflow action](/documentation/automate/workflows/triggers-actions) has a **Fail on error** toggle. Turn it off and a failed call no longer stops the run: the action returns `isSuccess: false` along with the response's status code and error message, so later steps can branch on the failure. * [Email](/integrations/email/overview) channel settings gain outbound block lists. Add addresses or domains under **Blocked emails** and **Blocked domains**, and Ravenna stops sending email to them. * Select several tickets and choose **Unassign** in the bulk assign menu to clear their assignees at once. * An [agent](/documentation/automate/agents/overview) that creates or updates a [Google group](/integrations/google-workspace/overview) can add group managers and choose the requester's role, rather than always adding them as a plain member. * When a [Slack](/integrations/slack/overview) channel has no agents left to connect, you get a shortcut to create a new [agent](/documentation/automate/agents/overview). * The ticket metrics behind the [prepackaged analytics dashboards](/documentation/measure/analytics#prepackaged-dashboards) compute for every organization, with no enablement step. * Inputs, text areas, and select fields share one refreshed style across the app, and the Ravenna bot icon adapts to dark mode instead of staying light on a dark background. **Bug fixes:** * The agent no longer adds duplicate form buttons to its [Slack](/integrations/slack/overview) replies, and shows its **Create Ticket** button at most once per thread instead of repeating it on every reply. * A message to the Ravenna [Slack app](/integrations/slack/app-home) routes straight to your only routable agent instead of asking you to confirm it first. * When an [agent](/documentation/automate/agents/configure) auto-submits a form on your behalf, it clearly confirms the submission instead of also showing a form card, and it no longer implies it submitted a form it is still waiting on you to fill out. * A one-word message that matches an [agent rule](/documentation/automate/agents/configure) follows the rule, instead of the agent asking what you need. * An [agent rule](/documentation/automate/agents/configure) that says to collect several details in one message, or to look up an existing record before creating one, is honored instead of being overridden by the agent's defaults. * Listing a workspace's [Slack](/integrations/slack/overview) channels works again instead of returning an error, and the **Remove Group Members** [Slack workflow action](/integrations/slack/workflows) can remove a user group's last remaining member. * Private notes stay private: their excerpts no longer appear in notification feeds, and ticket message reads hide them from people outside your team. * A ticket summary now checks your access to the ticket and leaves private notes out unless you have full access. * Ticket message reads and writes check ticket access consistently on every call. * The new ticket modal opens with your current workspace and channel instead of the ones you last visited. * **Copy title as link** copies the ticket title as the link text, not the ticket ID. * Deleting a channel with no tickets no longer asks where to move them. * The [workflow](/documentation/automate/workflows/triggers-actions) user attribute drilldown keeps the **Manager** option under HRIS and identity provider attributes. * Editing an [SLA](/documentation/automate/slas) policy no longer loses unsaved changes when the list refreshes in the background. * [MCP](/documentation/automate/mcp/tools) clients search applications scoped to what you can access, instead of listing every application in the organization. * [Foundry](/documentation/automate/foundry/integrations) library documentation lookups follow redirects and rank catalog matches by relevance, so building an action finds the right API reference faster. * The [Foundry](/documentation/automate/foundry/integrations) OAuth provider dialog shows the correct callback URL for your instance. * The close button on the [Foundry](/documentation/automate/foundry/actions) editor's find and replace bar is no longer blocked by its own tooltip. * An [analytics](/documentation/measure/analytics) card grouped or filtered by a multi-select attribute or custom field loads again instead of erroring. * The unread badge on the in-app help chat no longer disappears after a trip through Settings. * Menus opened from sidebar items close together with the sidebar, and rows for disabled tools in the [agent tools list](/documentation/automate/agents/configure) stay readable instead of appearing dimmed. * The time field clock renders correctly in dark mode, agent log cards get their padding back, and a table row's focus ring is no longer clipped. ## Agent-led access troubleshooting The Ravenna and Okta app icons side by side on a soft gradient background Your [agent](/documentation/automate/agents/overview) can now search the [Okta](/integrations/okta/agent-tools) System Log and tell someone why they cannot get in, instead of escalating the question to an engineer. "Why can't I get into Salesforce?" used to mean digging through Okta by hand. With the new **Search Okta System Logs** tool, the agent answers with what actually happened: the failed sign-in, the MFA prompt nobody finished, the group membership that was removed last Tuesday. It reads logins, lockouts, MFA enrollments, group changes, app assignments, and policy evaluations for one person and time range. Reference it in a rule with `@Search Okta System Logs`, and add the `okta.logs.read` scope to your Okta app to turn it on. [Learn more →](/integrations/okta/agent-tools) ## Copilot fills in the details Say what you want in plain language and [Copilot](/documentation/automate/copilot/using-copilot) works out the rest: which form fits, which fields to fill, which columns you meant. * **File a ticket by describing it.** Copilot picks the right [form](/documentation/tickets/forms/overview) and fills the fields and [attributes](/documentation/tickets/forms/attributes) it can from what you said, then asks about anything missing. It shows you what it inferred, so you can correct it before the ticket is created. * **Move a ticket to another workspace.** Its status, tags, category, and attributes come along. * **Build a form end to end.** From Copilot or an [MCP](/documentation/automate/mcp/tools) client, set the [fields](/documentation/tickets/forms/custom-fields) and their order, who can see it, tags, agents, task template, icon, and color, then publish when it looks right. Nothing is deleted unless you ask. * **Add a Table card to a dashboard.** Ask for the tickets and columns you want on an [analytics](/documentation/measure/analytics) dashboard, from Copilot or an [MCP](/documentation/automate/mcp/tools) client, and check the preview in chat first. * **Rebind a [Slack emoji action](/integrations/slack/emoji-actions).** Ask which emoji triggers each Ravenna action, swap in a different one, or put it back to the default. [Learn more →](/documentation/automate/copilot/everyday-tasks) **Quality of life updates:** * The **SLA breaching in** [ticket filter](/documentation/automate/slas) takes any duration in minutes, hours, or days, rather than four preset choices. Copilot searches and saved views accept the same durations. * Press ⌘ J (Ctrl J on Windows) to open or close the [Copilot](/documentation/automate/copilot/using-copilot) sidebar, and ⌘ O (Ctrl O) to start a new chat. * A [settings](/documentation/platform/my-settings) search that finds nothing now offers to ask [Copilot](/documentation/automate/copilot/using-copilot), so "where do I turn on X" gets an answer instead of a blank page. * Archived options on a [custom field](/documentation/tickets/forms/custom-fields) are cleared once no ticket uses them, so long-lived dropdowns stop collecting dead choices. * The [AI Outcome](/documentation/measure/analytics#prepackaged-dashboards) metric counts a rule-driven agent reply as participation, includes conversations that never became a ticket, and marks a ticket **Escalated** only when the agent's answer was genuinely unusable. * [Copilot](/documentation/automate/copilot/using-copilot) can set up a [Foundry](/documentation/automate/foundry/integrations) integration for an API that takes the key as a Basic auth username, like Stripe or Mailgun, and asks for just the one key. * [Foundry](/documentation/automate/foundry/actions) debug suggestions now apply the fix when you click them, instead of only describing it. * [Foundry](/documentation/automate/foundry/overview) actions are grouped under their own integration in the [agent tools list](/documentation/automate/agents/configure) and the `@mention` picker. * Ravenna now uses one neutral palette, so the color scheme picker is gone from [appearance settings](/documentation/platform/my-settings). You keep the light, dark, and system theme choice. **Bug fixes:** * New people synced from your identity provider arrive as **Member** rather than **Guest**, so they can see the workspaces they belong to right away. * Guests, non-members, and people without an organization membership can open their own tickets and switch workspaces again, in the app and in the [portal](/documentation/platform/portal). * Ticket notifications come from the resolver's verified email address again, instead of the default sender. * Agent tool calls waiting on your approval now run once you approve them. * A [workflow](/documentation/automate/workflows/triggers-actions) paused on an approval finishes when the ticket is [force approved](/documentation/tickets/approvals/overview), and passes who approved it to the steps that follow. * [Access policies](/documentation/automate/access-provisioning/policies) match eligible and ineligible groups synced from an integration, not only groups created in Ravenna. * Moving a ticket to another channel in the same workspace keeps its ticket number. * Images keep their content type on upload, so your agent can read screenshots attached from [Slack](/integrations/slack/overview), email, and Copilot. * Changing the aggregation on a percentage card in [analytics](/documentation/measure/analytics) no longer breaks the card. * [Copilot](/documentation/automate/copilot/using-copilot) can write [Foundry](/documentation/automate/foundry/actions) actions against an integration you have not published yet, so you can try one before it goes live. * A [Foundry](/documentation/automate/foundry/integrations) integration that uses client credentials OAuth now has a **Connect** button, and tells you which credential is wrong. * A [form](/documentation/tickets/forms/overview) that points at a channel, task template, user group, tag, or agent in another workspace now names the reference it cannot find, and saving or duplicating a form updates the [portal](/documentation/platform/portal) right away. * A [Slack](/integrations/slack/overview) triage channel shows the ticket card on the original message again, and ticket update DMs reach people who have never had one. * The [analytics](/documentation/measure/analytics) change badge reads a falling response time as an improvement, so getting faster is no longer flagged red. * The [audit log](/documentation/platform/organizations/audit-log) records access against the organization where it was granted. ## Copilot's toolbox keeps growing The Ravenna Copilot app icon, a dark Ravenna mark with a four-point sparkle, on a soft gradient background [Copilot](/documentation/automate/copilot/using-copilot) can now drive more of your workspace from chat, from SLA policies and reminders to saved views, duplicate checks, and analytics. * List, create, update, and reorder **[SLA policies](/documentation/automate/slas)**, and answer SLA-aware questions about a ticket, like time remaining, breach risk, and which policy applies. * Read and configure **[approval and assignment reminder policies](/documentation/tickets/reminders)** per workspace. * List, connect, and configure the **[Slack channels](/integrations/slack/overview)** wired into a workspace. * Create a saved **[ticket view](/documentation/tickets/organize/views)** from chat, with a live table preview attached to the reply and the sidebar refreshing to include it. * Ask Copilot to check whether a ticket looks like a **duplicate** of another open ticket before you file or reply. * Create **[analytics folders](/documentation/measure/analytics)** to group dashboards, and place a new dashboard directly inside one. * Group and filter **[analytics](/documentation/measure/analytics)** queries by ticket custom fields and attributes, from both Copilot and [MCP](/documentation/automate/mcp/tools). [Learn more →](/documentation/automate/copilot/using-copilot) ## Right-click context menus across the app Right-click a ticket row, workflow node, or sidebar item to reach the actions you would otherwise hunt for in a hover menu. Select more than one row and the menu offers the bulk actions instead. ## Assign people through your own ticket attributes [User select and User multi-select custom fields](/documentation/tickets/forms/custom-fields) can now appear as [ticket attributes](/documentation/tickets/forms/attributes). Name the attribute after the role you care about, like Reviewer or Hiring manager, and set the person or group from the ticket sidebar. [Learn more →](/documentation/tickets/forms/attributes) ## Connect a Foundry integration without leaving Copilot When [Copilot](/documentation/automate/copilot/using-copilot) proposes a [Foundry](/documentation/automate/foundry/integrations) action that needs credentials, you now enter them on a card in the conversation instead of leaving for the integrations page. Fields are masked as you type and go straight to encrypted storage, so a secret never passes through the model or into the chat history, and Copilot tests the credentials before running the action. [Learn more →](/documentation/automate/foundry/integrations) **Other updates:** * An [agent](/documentation/automate/agents/configure) can stay on a ticket after it escalates to a human, without waiting to be `@mentioned` each time. The toggle is off by default, and unavailable when threaded replies are set to **Respond to all**, so the agent will not talk over your team. * A workspace [API key](/documentation/platform/workspaces/settings#api-keys) can be restricted to a list of allowed IP ranges, so a leaked key cannot be used from an unfamiliar network. Set the ranges when you create the key or edit them later from **Settings → API keys**. **Quality of life updates:** * Ask [Copilot](/documentation/automate/copilot/using-copilot) why a [workflow run](/documentation/automate/workflows/workflow-builder) failed and it names the failing step and explains the cause, instead of stopping at the run's overall status. * [Copilot](/documentation/automate/copilot/build-automations) reuses the rules, agents, and workflows you already have when it plans an automation, and warns you before editing a rule that other agents share. * [Copilot](/documentation/automate/copilot/everyday-tasks) can filter a ticket search by custom field and attribute values, so "tickets where **Tier** is Gold" resolves in one turn. * The [entitlements table](/documentation/automate/access-provisioning/entitlements) has a **Time left** column showing how much longer a user's time-bound access lasts. * The [@mention picker](/documentation/automate/agents/configure) groups tools by integration, so a long list is faster to search. * [Copilot](/documentation/automate/copilot/using-copilot) shows a countdown while it waits on a workflow or Foundry action it launched, so a long turn no longer looks stalled. The docked sidebar also has a full-screen button that moves the conversation to the full-page view. * The [ticket deflection](/documentation/measure/analytics) metric now counts unpublished closed tickets that AI resolved on its own, so the rate reflects tickets a human never saw. * The [Okta Create User](/integrations/okta/workflows) workflow action takes an optional **Secondary email**, so provisioning can capture a personal address alongside the primary one. **Bug fixes:** * Guests can see portal-enabled workspaces in the [customer portal](/documentation/platform/portal) workspace switcher again. * Posting in a [Microsoft Teams](/integrations/microsoft-teams/overview) channel triggers the [Ravenna Agent](/documentation/automate/agents/overview) again, instead of the message being dropped. * A ticket [attribute](/documentation/tickets/forms/attributes) value can be cleared after it has been set, a ticket with an older attribute value loads again, and changing an attribute now records an event on the ticket timeline. * A multi-select [custom field](/documentation/tickets/forms/custom-fields) keeps its option labels through create and update instead of falling back to raw ids. * [Foundry](/documentation/automate/foundry/overview) actions stay runnable after you link native credentials to their integration. * The [Ravenna Agent](/documentation/automate/agents/overview) can look up statuses and tags on a published ticket again, read the ticket checklist, and mark tasks complete. It also keeps nested lists in its replies instead of flattening them to one level. * A [knowledge base](/documentation/automate/knowledge/overview) document's images no longer stop loading a few hours after it is saved, and the [Notion](/integrations/notion/knowledge) picker now offers databases embedded inside a page. * Knowledge base folders and documents, and ticket custom fields, now check workspace membership consistently on every read and write. * [MCP](/documentation/automate/mcp/overview) tool calls reject a parameter that does not exist instead of ignoring it, so a bad argument fails loudly rather than returning a wrong answer. * [Ticket replication](/integrations/overview) keeps replicated systems in sync for tickets created by automation, and no longer creates a ticket from an email bounce notification. * A time-limited [access request](/documentation/automate/access-provisioning/entitlements) entitlement now expires from when it was provisioned rather than when it was requested, so you get the full window you approved. * The ticket sidebar no longer shows an empty **Form** card on a ticket whose form has no visible fields, and [Copilot](/documentation/automate/copilot/using-copilot) asks for your timezone instead of assuming one. ## A redesigned ticket page The Reply, Private note, and Mark as done chips that float above the ticket dock, each showing its keyboard shortcut: R, P, and D The ticket page has been rebuilt around the way agents actually work a ticket: read the conversation, act on it, move to the next one. Everything you reach for is now in a fixed place, a keystroke away, and arranged the way you want it. **The composer now lives in a dock at the bottom of the ticket.** It no longer moves above or below the conversation with your sort direction. The dock has two states: * **Ticket actions**, the default. **Previous** and **Next**, or and , step through the tickets in the view you came from. **Assign**, **Status**, and **Archive** sit in the middle. * **The composer.** Press R or click **Reply** to switch. Esc or **Back** returns you to the actions. **Three chips float above the dock on every ticket:** * **Reply**, R. Opens the composer for a public reply. * **Private note**, P. Opens the composer already switched to private, so an internal note can't reach the requester by mistake. * **Mark as done**, D. Resolves the ticket, and becomes **Undo mark as done** once it is resolved. **Triage without the mouse.** With the composer closed, A opens the assignee picker and S opens the status picker. **Approve from where you are reading.** When a ticket waits on your approval, **Approve** and **Deny** render in the dock instead of at the top of the page, where they used to scroll out of view. **Put each section where you want it.** Attributes, Tasks, Approvals, Subtickets, Links, and a form's captured fields can each live in the tab bar next to **Conversation** or in the ticket sidebar. * Drag a section's handle between the two zones, or reorder within one. * Your arrangement saves to your preferences and follows you across workspaces. * Form fields and approvers start in the sidebar. Subtickets, tasks, and links start as tabs. * Tabs carry a count badge, and a form's tab is labeled with the form's name. **Smaller details:** * **Keep composer open**, in the composer's menu, leaves the dock in whichever state you left it as you move between tickets. * Snippets open in a floating list above the dock instead of covering what you are writing. * Your sort direction and **Hide logs** choice persist across tickets, and posting a comment scrolls to your new message. * The whole page works on a phone. ## Report ticket durations from timestamps, not just the SLA clock Custom [analytics](/documentation/measure/analytics) cards on the Tickets data source now expose two families of duration fields. **SLA Time to First Response**, **SLA Time to Resolution**, and **SLA Time to Close** keep reading the SLA target record and honor business schedules, pause statuses, and superseded targets. The new **Time to First Response**, **Time to Resolution**, and **Time to Close** fields measure wall-clock time from the ticket's own timestamps, so you can benchmark performance across every ticket, including ones no SLA policy covers. Existing saved widgets keep pointing at the SLA-clock fields under their new **SLA** labels, so no numbers move. [Learn more →](/documentation/measure/analytics#prepackaged-dashboards) ## Peek any ticket from a list Every row in a [tickets table](/documentation/tickets/organize/views) and every card in a [Kanban](/documentation/tickets/organize/views) now has a **Peek** button that opens the ticket in a side drawer, so you can read and act on a ticket without leaving the list you were browsing. [Learn more →](/documentation/tickets/organize/views) ## Personalize your sidebar Each user can now hide individual channels and views from their own sidebar without changing anyone else's layout. Hidden items move into a collapsible section at the bottom and can be brought back at any time. You can also create a new saved view directly into a specific sidebar folder from the [sidebar](/documentation/tickets/organize/views) folder menu, instead of creating the view first and dragging it in afterwards. [Learn more →](/documentation/tickets/organize/views) ## Copilot's toolbox grows [Copilot](/documentation/automate/copilot/using-copilot) can now drive more of your workspace from chat: * Create and update **[user groups](/documentation/platform/groups)**. * Create and update **[access levels and access policies](/documentation/automate/access-provisioning/policies)**. * Read and manage **[workspace ticket statuses](/documentation/tickets/organize/statuses)**. * List and reference **[business schedules](/documentation/automate/slas)**, with a schedule attachment card on the reply. * **Publish** and **deactivate** [workflows](/documentation/automate/workflows/workflow-builder) it built for you. * **Search existing [Foundry](/documentation/automate/foundry/integrations) actions** before scaffolding a new one, so it reuses what your organization has already built. * **Run a Foundry action it just built** as part of the same conversation, so you can validate end-to-end without leaving Copilot. [Learn more →](/documentation/automate/copilot/using-copilot) ## Browse Copilot use cases from the empty state The [Copilot](/documentation/automate/copilot/using-copilot) empty state now opens onto a categorized use-case browser instead of a short list of generated starter prompts. Pick a category like Workflows, Agents, Analytics, or Knowledge, then click a ready-made prompt to drop it into the composer and start iterating. [Learn more →](/documentation/automate/copilot/using-copilot) ## Workflow tools available over MCP Every Copilot workflow tool (create, edit, publish, deactivate, list, inspect, and step-level edits) is now available through the Ravenna [MCP](/documentation/automate/mcp/tools) server, exposed via the same Copilot surface. The old tRPC-backed workflow MCP tools are retired so external MCP clients see a single, consistent workflow API. [Learn more →](/documentation/automate/mcp/tools) ## Streaming AI stays online through provider outages The Ravenna [Copilot](/documentation/automate/copilot/using-copilot) and Ravenna [Agent](/documentation/automate/agents/configure) streaming loops now fail over between AI providers automatically. If a provider degrades mid-turn, the reply continues from a fallback provider instead of erroring out. [Learn more →](/documentation/automate/copilot/using-copilot) **Quality of life updates:** * [Copilot](/documentation/automate/copilot/using-copilot) replies now consistently call the customer-facing AI an **Agent** rather than "assistant", "bot", or "AI assistant", including while it is still being proposed. * The [forms toolbar](/documentation/tickets/forms/overview) sort menu now includes **Description** and **Status**. * The [SLA policy](/documentation/automate/slas) settings page now anchors **Save changes** to the right, with the "Changes apply to new tickets only" note next to it, so the action lands where you expect it. * A generated [Foundry](/documentation/automate/foundry/integrations) action's inputs and outputs are now valid on the first pass, instead of needing a fix before the action will run. **Bug fixes:** * [Category](/documentation/tickets/organize/categories) ticket counts now reflect the real number of tickets instead of always showing 0. * A [form](/documentation/tickets/forms/overview) with hidden fields no longer blocks submit, and form editors no longer block **Save** on fields the form never renders. * [Conditional fields](/documentation/tickets/forms/overview) parented on system fields (like Priority or Status) now resolve visibility everywhere they appear. * [Analytics](/documentation/measure/analytics) time-series charts skip dates with no data instead of drawing a gap at zero, and stat cards no longer show **0** for a period with no records when the metric is undefined. * [Knowledge](/documentation/automate/knowledge/overview) source chips in a Copilot reply no longer carry a leftover list ordinal (like `1.` or `2.1)`) in their titles. * Filter dropdowns no longer lose the search field's focus when your mouse moves over the option list. * The **Create ticket** modal's file dropzone now accepts drops reliably instead of intermittently rejecting them. * A [Copilot](/documentation/automate/copilot/using-copilot) chat input card is now centered in the workflow empty state instead of anchoring to one edge. * The Ravenna [Okta](/integrations/okta/overview) **Activate User** step now succeeds when the user is already active, instead of erroring on the redundant activation. * The Ravenna [Google Groups](/integrations/google-workspace/overview) integration can now look up a group by email address, not just by group id. * A ticket's work object now renders in [Slack](/integrations/slack/overview) messages even when its metadata is large enough to hit Slack's per-message byte limit. * Tickets with [custom fields](/documentation/tickets/forms/overview) no longer intermittently error when opened or updated. * Confirmation dialogs now disable **Confirm** and **Cancel** while the underlying action is running, so a slow delete or update can't be triggered twice by an impatient double-click. ## Task cancellation You can now cancel a task on a ticket without deleting it. Cancelled tasks stay visible in the checklist, freeze their description, assignees, and completion checkbox, and can be [restored](/documentation/tickets/tasks#managing-tasks) at any time. The Tasks header shows a cancelled counter alongside the completion counter (for example, `2/5 · 1 cancelled`). A new workspace **[Close ticket task policy](/documentation/platform/workspaces/settings#close-ticket-task-policy)** decides what happens to open tasks when a ticket moves to **Done** or **Closed**. Leave the default to keep tasks open, or switch to **Cancel remaining tasks** so Ravenna prompts agents to cancel the rest of the checklist on close. [Learn more →](/documentation/tickets/tasks#managing-tasks) ## Business-hours aware inactivity auto-close The [inactivity auto-close](/documentation/platform/workspaces/settings#inactivity-auto-close) policy has a new **Business hours** selector. Point it at a business schedule and Ravenna only counts that schedule's working hours toward the inactivity threshold, so tickets are not warned or closed over nights, weekends, or holidays. Leave it unset to keep the current wall-clock behavior. [Learn more →](/documentation/platform/workspaces/settings#inactivity-auto-close) ## Drag and drop files into Copilot chat You can now drop files straight into the [Copilot](/documentation/automate/copilot/using-copilot) chat input to attach them to your next message. The dropzone lights up as you drag over the composer, and attached files show up as chips you can remove before sending. [Learn more →](/documentation/automate/copilot/using-copilot) ## Copilot can act on tags, approval templates, and any settings page Copilot now has first-class tools for [ticket tags](/documentation/tickets/organize/tags) (search, create, update) and [approval templates](/documentation/tickets/approvals/templates), so you can ask it to tag tickets or line up approvers without leaving the chat. Its `ui_control` skill also reaches every settings page now, so a request like "open my email domain settings" jumps straight to the right screen. [Learn more →](/documentation/automate/copilot/using-copilot) **Quality of life updates:** * [Copilot](/documentation/automate/copilot/using-copilot) ticket tools understand **ticket type**, so you can read, set, and filter tickets by type (Service, Incident, Question, and so on) directly from chat. * [Copilot](/documentation/automate/copilot/using-copilot) now knows the current time of day, not just the date, and gracefully falls back when a user's timezone can't be resolved, so date-sensitive answers stay accurate. * Count-card widgets in a [Copilot](/documentation/automate/copilot/using-copilot) reply now stretch to the full width of the message for easier scanning. * The Ravenna [Slack app](/integrations/slack/overview) and other LLM-facing surfaces now consistently say "channel" instead of the old "queue" wording. * Every operator in the [analytics](/documentation/measure/analytics) filter picker now reads as **is**, **is not**, **is between**, and so on. The old **has** / **does not have** wording for multi-value fields is gone, so two ANDed conditions on the same field read consistently. * Ravenna Copilot no longer carries a leftover draft into a [new chat](/documentation/automate/copilot/using-copilot); the composer clears when you start a fresh conversation. * On a Forms page, [Copilot's starter suggestions](/documentation/automate/copilot/everyday-tasks) now reflect the forms and folders actually on that page, so proposals are relevant to what you are looking at. * When Ravenna Copilot builds a [workflow](/documentation/automate/workflows/workflow-builder), it now names the parts of your request it can't build (for example, a piece that belongs in a different setting) in the same message it delivers the plan, instead of surprising you later. * [Foundry](/documentation/automate/foundry/integrations) code generation now uses Context7 OpenAPI specs directly as the source of truth, so scaffolded integrations line up with the real API contracts. * The [Foundry](/documentation/automate/foundry/integrations) Context7 picker has a **Find more matches** action for broader searches and a manual library ID input for cases where search comes up empty. **Bug fixes:** * Grouped bar charts rendered by [Copilot](/documentation/automate/copilot/using-copilot) now show their group names on the axis instead of leaving them blank. * Ravenna Copilot can now restyle an [analytics widget](/documentation/measure/analytics) (for example, switching a bar chart to a stacked bar) without redoing the underlying query. * Ravenna Copilot streams now stay open through long silent turns; a slow tool call no longer causes a proxy to sever the reply mid-generation. * When Ravenna Copilot creates an [agent rule](/documentation/automate/agents/configure), the rule link opens the new rule and the rule appears immediately in both the workspace rules list and the owning agent's rules list. * URLs in a [Ravenna Agent](/documentation/automate/agents/configure) reply render as clickable links again instead of plain text. * Sort options on the [Agents](/documentation/automate/agents/configure) table now match the sortable columns, so every visible sort works. * The sidebar unread count on a saved [view](/documentation/tickets/organize/views) now respects that view's own filters per user, so shared views no longer bleed each other's unread counts. * SLA outcome filters and featured values in [analytics](/documentation/measure/analytics) now match against the ticket's stored state, so filters return the tickets you expect. * Access eligibility for a [form](/documentation/tickets/forms/overview) is now evaluated against the requester, not the row author, so requests submitted on someone else's behalf can still reach the right form. * The [Notion](/integrations/notion/overview) knowledge base picker now offers pages whose parent is a Notion block (not just page-parented pages), so the full tree is available to add as a source. * The [Foundry](/documentation/automate/foundry/integrations) Context7 picker is now gated on the integration version state rather than its last run state, so the picker appears in the right places again. * The Ravenna [MCP](/documentation/automate/mcp/tools) server now declares proper JSON Schema types for `customFields` and `attributeFields` on ticket create and update tools, so strict MCP clients no longer reject the input. * Every Ravenna [MCP](/documentation/automate/mcp/tools) tool now advertises its real display title, so tools list cleanly in MCP clients. * The [Jira](/integrations/jira/ticket-replication) ticket replication link is now written reliably on ticket create, even when the post-create hook takes an unusual path. ## AI Outcome skips tickets without agent participation The [AI Outcome](/documentation/measure/analytics#prepackaged-dashboards) metric now returns **Not Computed** for tickets the AI agent never worked on, instead of classifying them as Escalated. Because those tickets no longer receive an outcome at all, the Resolved, Assisted, and Escalated rates on the prepackaged [Agents](/documentation/measure/analytics#prepackaged-dashboards) dashboard describe only the tickets the agent actually participated in. Bot-submitted tickets are also skipped, keeping automated noise out of your agent performance numbers. The fourth outcome value is now labeled **Unactionable**, replacing **Not Applicable**. [Learn more →](/documentation/measure/analytics#prepackaged-dashboards) **Quality of life updates:** * The [ticket filters card](/documentation/automate/copilot/everyday-tasks) in a Copilot reply has tighter padding, a compact "N applied" summary, and an **Open ⌝** affordance so filter results are easier to scan. **Bug fixes:** * A [workflow run](/documentation/automate/workflows/workflow-builder) now shows the ticket that triggered it in the run header, even when the trigger step iterated multiple times. * Picking a form through the drilldown in a [workflow builder](/documentation/automate/workflows/workflow-builder) input now stores the form's ID, so downstream steps and validation keep working instead of failing on a malformed reference. * Ravenna resources named in a [Copilot](/documentation/automate/copilot/using-copilot) reply render as clickable attachment cards again instead of plain text. * [Agent rules](/documentation/automate/agents/configure) referenced by a Copilot reply also render as clickable cards instead of plain text. * An [agent rule](/documentation/automate/agents/configure) that tags a Slack user in its instructions now keeps the `@mention` intact when the agent replies in Slack. * The **Rapid create** workspace preference in [My settings](/documentation/platform/my-settings) can now be cleared back to no default. * Copilot no longer surfaces raw database resource IDs when it talks about [agent rules](/documentation/automate/agents/configure) or related resources. * Copilot's agent-rule editor no longer suggests a "should-not-trigger" examples field. Narrow matching by tightening the [rule's trigger or instruction](/documentation/automate/agents/configure) instead. * The Ravenna [Slack app](/integrations/slack/overview) auth handshake no longer fails on a specific edge case that blocked installs. ## Private reminder DMs Approval and assignment [reminders](/documentation/tickets/reminders#shared-behavior) no longer post a public @mention on the ticket. Ravenna sends a private Slack DM (with an email fallback) to just the pending approvers or the current assignee, and honors each recipient's notification preferences before sending. [Approval reminders](/documentation/tickets/reminders#approval-reminders) DM every approver still pending on the active round. [Assignment reminders](/documentation/tickets/reminders#assignment-reminders) DM the current assignee. Everyone else on the ticket is left out of the nudge. [Learn more →](/documentation/tickets/reminders) ## Send Email workflows can use a custom sender address The [Send Email](/documentation/automate/workflows/triggers-actions#messaging-actions) action now has **Sender Name** and **Sender Address** fields. Set a display name and pick a local part on your [verified email domain](/documentation/platform/organizations/email-domains) (for example, `it-help` on `support@your-company.com`) so workflow emails go out branded to the team that owns them. Without a verified domain the action falls back to the standard workspace sender, so existing workflows keep working unchanged. [Learn more →](/documentation/automate/workflows/triggers-actions#messaging-actions) **Quality of life updates:** * [Inbound email allow lists and block lists](/integrations/email/overview#security-and-filtering) on a queue now use a tokenized input instead of a comma-separated text field, so each address or domain gets its own chip and validation as you type. * [Blocked senders](/integrations/email/overview#security-and-filtering) are now rejected before Ravenna processes the message, and the queue sends a bounce back if **Send bounced emails** is on for the queue. * Outbound Email Settings on a queue has a new [**Mask internal agent emails**](/integrations/email/overview#outbound-email-configuration) switch. Keep agents' personal addresses off customer-facing replies so only the requester and external participants are copied. * The [Send Email](/documentation/automate/workflows/triggers-actions#messaging-actions) workflow action can now target a **group** (the group's members are expanded to individual recipients at send time), alongside the existing user picker. * When a customer emails your workspace via a distribution list (Google Groups, `list-post` headers), Ravenna [keeps the group address on the reply's CC](/integrations/email/overview#email-threading-and-replies) so the whole list stays in the loop. * Form fields and approvers on a ticket now default to the ticket sidebar instead of tabs. Move them back to a tab from the ticket view if you prefer the tabbed layout. * The **Application** filter in [workflow](/documentation/automate/workflows/workflow-builder) conditions is a dropdown of your connected applications instead of a free-text field, so the value can't drift from a real application ID. * [Foundry](/documentation/automate/foundry/integrations) generation and publish failures now surface the actual reason (draft integration, hardcoded identity, missing scope) with an actionable message instead of a generic error toast. * [Foundry actions](/documentation/automate/foundry/actions) can now be code-generated against `ticket.list`, `ticket.byId`, and `ticket.create` endpoints, so Copilot can scaffold ticket-shaped automations without hand-wiring the request. **Bug fixes:** * A [workflow](/documentation/automate/workflows/workflow-builder) with a **Category Assigned** trigger now fires when Ravenna's AI classifies an incoming ticket, not only when a human sets the category. * An [analytics](/documentation/measure/analytics) filter that ANDs two values of the same multi-value field (for example, tag = A and tag = B) now returns tickets that have both, instead of zero. * [Foundry](/documentation/automate/foundry/integrations) bridged junctions declared on a native integration stay detachable, and bridge generation works on native-only integration slugs again. * A workflow **condition** step no longer fails open when the condition list is empty; empty conditions evaluate to false, and broken variable references now surface as named errors instead of silent passes. * A long Copilot Foundry tool call no longer severs the assistant turn mid-stream; the reply keeps streaming through slow generations. * The ticket create button in the ticket header lines up with the rest of the toolbar again, and its keyboard shortcut tooltip renders the right glyphs. * The Ravenna [MCP](/documentation/automate/mcp/tools) endpoint tolerates an empty JSON body on `DELETE` session termination requests, so MCP clients that end a session with no payload get a clean 200 back. ## See what your AI agent actually resolved Ticket timeline entry reading "Pixel IT marked the ticket as Done" with a green Done status badge The prepackaged [Agents](/documentation/measure/analytics#prepackaged-dashboards) dashboard is now built around [AI Outcome](/documentation/measure/analytics#prepackaged-dashboards). It reports **Resolved**, **Assisted**, and **Escalated** as headline rates alongside agent tickets and total tickets, and its trend chart stacks classified ticket volume by outcome over time. Every widget on the dashboard counts only classified tickets, meaning those whose AI Outcome is Resolved, Assisted, or Escalated. Tickets that are **Not Applicable** or **Not Computed** stay out of every rate, count, and trend, so the three rates share one denominator. [Learn more →](/documentation/measure/analytics#prepackaged-dashboards) ## Ticket attributes get their own tab In the ticket drawer, [attributes](/documentation/tickets/forms/attributes) now have their own **Attributes** tab alongside Conversation, Tasks, and Approvals, instead of sitting inline underneath the conversation. Edit attribute values from the tab, and promote another eligible field with **Add Attribute** without a trip to settings. The full ticket view keeps its sidebar **Attributes** section, which you can move to a tab if you prefer. Attributes and the tabbed ticket view are both rolling out gradually. Reach out on Slack or in-app chat if you'd like them turned on for your workspace. [Learn more →](/documentation/tickets/forms/attributes) ## Portal chat answers questions about your own tickets [Portal](/documentation/platform/portal) chat can now send a requester's questions about their own data to Ravenna AI instead of creating a ticket. "Show me my tickets from this week", "do I have any approvals waiting on me", or "chart my tickets by status" get answered in the chat. Real support requests still route to the workspace's agent and open a ticket as before. Answers are scoped to the signed-in requester, so questions about someone else's tickets or approvals are denied. Follow-up turns stay in the same conversation, and each turn rechecks the setting. **Ravenna AI in Portal** is off by default. Turn it on in **Organization Settings > Portal**. [Learn more →](/documentation/platform/portal#ravenna-ai-for-platform-questions) **Quality of life updates:** * Copilot's [create\_ticket over MCP](/documentation/automate/mcp/tools) now returns an openable ticket link, so an MCP client can jump straight to the new ticket instead of quoting an ID. * Saved credentials on a [Foundry integration](/documentation/automate/foundry/integrations) render as a star mask with a **Saved. Enter a new token to replace it.** helper, so you can tell at a glance which fields are already stored. * A [Foundry OAuth](/documentation/automate/foundry/integrations) failure now shows the provider's actual error (`invalid_client`, `invalid_grant`, `invalid_scope`, `unauthorized_client`, `unsupported_grant_type`, `temporarily_unavailable`) instead of a generic **missing code** message. * A disabled [Foundry OAuth provider](/documentation/automate/foundry/integrations) that still has active connections stays on the Integrations page as **Archived**, so you can disconnect it without it reappearing in the connect flow. * A [Foundry](/documentation/automate/foundry/integrations) action's configure panel now lets you pick an integration inline, create one from an unmaterialized provider, or open its settings without leaving the action. * Copilot's [knowledge base](/documentation/automate/copilot/overview) sources collapse into a single **Sources** popover in the chat, so long answers no longer push the reply off screen. * Copilot can now list and update [applications](/documentation/automate/access-provisioning/applications) over its tools, so you can ask it to find or edit an application without leaving the chat. * Paste a multi-line list into a [task](/documentation/tickets/tasks#creating-and-managing-tasks) row and each line becomes its own item. Ravenna strips common list markers (`- `, `* `, `1.`, `- [ ]`, `•`) as it splits, so you can paste straight from a doc. * A **Remove Template** action in the [Tasks](/documentation/tickets/tasks#managing-tasks) section header deletes every task that came from an applied template, including subtasks, and keeps the ones you added by hand. **Bug fixes:** * Guests can no longer bypass form intake by opening the ticket composer from the [tickets table](/documentation/tickets/organize/views); the header only offers it to workspace members and admins. * Duplicating a [workflow](/documentation/automate/workflows/workflow-builder) with an **AI Prompt** trigger now mints a fresh webhook URL for the copy, so the two workflows no longer share a direct URL. * A [metric widget](/documentation/measure/analytics)'s actions menu stays open while you move to click one of its items instead of disappearing on hover-out. * Icon-only combobox triggers across the app keep their width while loading, so buttons no longer jump as options resolve. * A [workflow](/documentation/automate/workflows/workflow-builder) with a webhook trigger no longer fires when the workflow is paused; only active workflows run on webhook events. * Copilot's stop button now halts an in-flight reply on the server, instead of stopping the stream on your side while generation continued. * A [Foundry](/documentation/automate/foundry/integrations) connect deep-link opens straight into the configure sheet again, rather than dropping you on the Integrations list. * Copilot chat header buttons expose proper labels to screen readers. * Copilot ticket-filter suggestions apply as complete filters, and pausing a long-running Copilot tool no longer wedges the session. * Copilot's agent-select dropdown caps its height and scrolls internally, so a workspace with many agents no longer stretches the picker off screen. * Rich text formatting from Copilot's composer bubble menu survives once the message is sent. * Copilot's scroll-to-bottom button only appears when you have actually scrolled up, so it no longer overlaps the suggested-reply chips. ## Run approval rounds in parallel Approvals section showing a stage of 2 Rounds, with HR Approval and Manager Approval both In Progress at 0 of 1 approvals An [approval template](/documentation/tickets/approvals/templates) or an ad-hoc approval on a ticket can now run rounds side by side instead of one after another. Drag one round onto another in the round list to group them into a single stage, and Ravenna activates every round in that stage together. Rounds in the stage still enforce their own policy independently, so a stage can pair, for example, a manager approval with a security approval and wait on both. Ordering is stored on each round as a stage index. When every round in the active stage is decided, the next stage activates automatically. Approvers who appear in more than one round of the same stage are notified once, and the ticket audit log collapses a parallel stage's kickoff into a single event. [Learn more →](/documentation/tickets/approvals/rounds#run-rounds-in-parallel) ## More native bridges in Foundry [Foundry](/documentation/automate/foundry/integrations) actions can now reuse the credentials from thirteen more connected integrations without configuring a separate Foundry integration: **HubSpot**, **Incident.io**, **Vanta**, **Freshservice**, **JumpCloud**, **Intune**, **Iru**, **Rippling**, **Jira**, **Linear**, **GitHub**, **PagerDuty**, and **Fleet**. Select any of them as the action's connection and Foundry supplies the token at run time. [Learn more →](/documentation/automate/foundry/integrations) **Quality of life updates:** * A pending approver now sees the **Approve** and **Decline** buttons docked in the ticket composer, so you can decide without scrolling to the approval card. See [approvals](/documentation/tickets/approvals/overview). * [Access policies](/documentation/automate/access-provisioning/policies) can now require the requester's **manager's manager** as an approver, in addition to the direct manager. * Copy a [task template](/documentation/tickets/tasks) into another workspace from the task template settings, choosing the destination workspace, folder, and a new name and description. * [Custom ticket attributes](/documentation/tickets/forms/attributes) can now be edited from the create ticket modal, the edit modal, and the ticket drawer, and a plus button on the ticket sidebar promotes an eligible custom field to a workspace attribute without a settings round-trip. * The [Copilot](/documentation/automate/copilot/overview) form builder preserves dedicated field types (like Application Select or User Select), conditional-field parents, and per-field flags when it duplicates a form, so a form asked for "like this one" comes out matching the source. * Copilot resolves partial dates like "Aug 12" against today's year instead of asking which year you meant. See [Copilot](/documentation/automate/copilot/overview). * Copilot answers generic automation questions ("what can I automate?") directly instead of interrogating you for specifics before it responds. See [Copilot](/documentation/automate/copilot/build-automations). * [Copilot](/documentation/automate/copilot/overview) suggested-reply chips scroll sideways in a single row now, instead of wrapping onto multiple lines and pushing the composer down. * Automation settings (reminder policies, ticket inactivity, reopen policies) save with debounced writes and confirm each save with a toast, so you can adjust a value and know it stuck. See [reminders](/documentation/tickets/reminders). * [Analytics](/documentation/measure/analytics) single-value and grouped-value widget cards were redesigned with a cleaner header, badge-based deltas, and consistent chrome across the dashboard and Copilot. * Copilot [task tools](/documentation/tickets/tasks) are now available over [MCP](/documentation/automate/mcp/tools), replacing the older duplicate task endpoints. **Bug fixes:** * Agent replies no longer render literal backticks around inline code. See [Copilot](/documentation/automate/copilot/overview). * The [AI Outcome dashboard](/documentation/measure/analytics) no longer shows mismatched populations between rate cards and their underlying counts. * The **Hide empty values** toggle now defines the denominator for percentage [metrics](/documentation/measure/analytics), so hidden buckets are excluded from the total instead of quietly diluting the rate. * [Business schedule](/documentation/automate/slas) hours and card-select conditional fields save correctly again on first submit. ## Ask Ravenna AI in the Portal Turn on **Ravenna AI in Portal** from Portal settings and anyone visiting the [Portal](/documentation/platform/portal) can ask about their own tickets and approvals, instead of filing a ticket to find out where something stands. Each person only ever sees their own requests, so this exposes nothing new. [Learn more →](/documentation/platform/portal) **Quality of life updates:** * The model picker is gone from the [Copilot](/documentation/automate/copilot/overview) chat header. It no longer changed anything, since Copilot chooses the model for you. **Bug fixes:** * A long workflow title no longer runs underneath the **+** button you use to insert a variable. * You can change how an [integration](/integrations/overview) signs in, for example from an API key to OAuth, and save it without having to disconnect and set it up again. * When you send Ravenna a file in a Slack DM, it now lands on your ticket and the AI agent waits to see it before replying. * You can remove the last round from an [approval process](/documentation/tickets/approvals/rounds) that does not require one, instead of being stuck with a round you no longer want. ## Approve and decline requests in chat Approvers can now respond to a request from wherever the conversation is happening. Two new [Ravenna tools](/documentation/automate/agents/configure#ravenna-tools), **Approve Request** and **Decline Request**, let an agent record an approver's decision when they reply "approved" or "denied, the budget is too high" instead of asking them to open the ticket. A decline carries the reason through to the requester. Both tools only ever act as the person talking, so a requester or a bystander in the thread cannot approve on someone else's behalf. After recording a decision the agent knows whether the round finished, whether the whole request is approved, and how many approvers are still outstanding, so it can answer "what happens next" in the same reply. [Learn more →](/documentation/automate/agents/configure#ravenna-tools) ## Copilot works your ticket checklists [Copilot](/documentation/automate/copilot/everyday-tasks#work-a-tickets-checklist) can now read and edit a ticket's [task checklist](/documentation/tickets/tasks). Ask what's left, mark several items done in one request, rename or reassign a task, nest it under a header, or apply a task template by name. Copilot reads a template's items before applying it, so you can check you picked the right one. Copilot also reports a ticket's approval state now, including each round, who has approved or declined, the reason they gave, and who is still pending. Ask "who still needs to approve IT-4892" and you get the answer without opening the ticket. [Learn more →](/documentation/automate/copilot/everyday-tasks#work-a-tickets-checklist) ## Roll back a Foundry function to a prior publish [Foundry](/documentation/automate/foundry/actions#version-history) now keeps a version history for every function. Each code change snapshots a checkpoint in the **Chat** tab, and each publish records a deployable version, so there are two ways back. **Restore** on a checkpoint marker rewinds the draft's code, schemas, settings, and integration bindings, plus the conversation, to that moment. Your current state is saved first, so a restore is itself reversible. Click the **published v3** badge in the function workspace header to open **Publish history** and roll the live version back instead: rolling back from `v5` to `v3` re-publishes immediately as `v6`, annotated `↳ rolled back to v3`, and keeps your chat where it is. [Learn more →](/documentation/automate/foundry/actions#version-history) **Quality of life updates:** * **Agent Outcome** is now **AI Outcome** everywhere: the tickets table, [views and filters](/documentation/tickets/organize/views), and [analytics](/documentation/measure/analytics). * [AI Outcome](/documentation/measure/analytics) gained an **Assisted** value for tickets where the agent did substantive work but a human finished the ticket, alongside **Resolved**, **Escalated**, and **Not Applicable**. Tickets the classifier has not reached yet read **Not Computed**. * Clicking a segment of an [AI Outcome chart](/documentation/measure/analytics) opens the tickets behind it. * The **Percent of** [aggregation](/documentation/measure/analytics#configuration-options) is now a single share-of-total mode driven by **Group by**. Group by **SLA > Outcome**, **AI Outcome**, or **Resolution Path** for those rates, and every ticket is counted rather than excluded when it has no value. Cards built before the change keep their current numbers, so only new cards use the new mode. * A new **Date & Time** [custom field type](/documentation/tickets/forms/custom-fields) captures both halves in one field. In Slack it renders as Slack's combined picker and is read in the submitter's timezone, and the value is stored as wall-clock time so 9:00 AM stays 9:00 AM for everyone. * [Form pickers](/documentation/tickets/forms/overview) across Ravenna only offer published forms. A draft or archived form that was already attached to a queue, agent, or Slack channel stays visible so you can remove it, labeled with why it is no longer selectable. * A workspace's default form is now an ordinary form. It is created **Published** so the workspace can take tickets immediately, and you can edit, archive, or delete it to replace the starter form with your own. See [forms](/documentation/tickets/forms/overview). * The [Slack](/integrations/slack/creating-tickets) ticket modal prefills the description with the message you started from, and the workspace picker only lists workspaces where you have a published form you can submit. The generic **Others** option is gone. * The [Google Drive](/integrations/google-drive/knowledge) knowledge picker has five tabs (All files, My Drive, Shared with me, Shared drives, Starred), so team-owned files in a shared drive are reachable. * An unconfigured placeholder step in the [workflow builder](/documentation/automate/workflows/workflow-builder#unconfigured-steps) can take child steps and branch, so you can lay out a workflow's shape before choosing its actions. * The **HTTP Request** [workflow action](/documentation/automate/workflows/triggers-actions) no longer sends a `Content-Type` header on bodyless GET and DELETE calls, which strict servers were rejecting. * [Foundry](/documentation/automate/foundry/actions) names function outputs that hold a Ravenna entity ID with Ravenna's canonical field names, so callers can expand an ID into the full user, ticket, or application instead of getting a bare string. * Agent rules authored through [MCP](/documentation/automate/mcp/tools) render their form references as badges in the rule editor rather than raw `[form: ...]` text. * [Copilot](/documentation/automate/copilot/overview) suggested follow-ups are stored with the conversation, so they are still there when you reload a session or come back to it later. * The [integrations settings](/documentation/automate/foundry/integrations) page has matching horizontal padding on desktop, in line with the rest of settings. **Bug fixes:** * Spam, delivery bounces, and monitoring alerts no longer count toward the [AI resolution rate](/documentation/measure/analytics) denominator, so rates on a noisy inbox reflect the tickets a person actually opened. **Assisted** and **Not Applicable** also render their labels in the tickets table instead of a blank cell. * A dashboard widget's **View** action now carries the widget's filters into the ticket list it opens. See [analytics](/documentation/measure/analytics). * The **SLA target** [filter](/documentation/tickets/organize/views) no longer produces invalid SQL. * A required field in a [form](/documentation/tickets/forms/overview) layout section no longer blocks submits, and [checkbox](/documentation/tickets/forms/custom-fields) fields drive conditional logic correctly on the web and in Slack. * The tickets table no longer crashes when a [custom field](/documentation/tickets/forms/custom-fields)'s stored value does not match its current type, and editing a custom field on a ticket refreshes the table without a reload. * The [Slack ticket mirror](/integrations/slack/ticket-mirror) card is no longer silently dropped on tickets large enough to exceed Slack's block limits. * [Workflow](/documentation/automate/workflows/workflow-builder) URLs with underscores are no longer corrupted by markdown escaping. The workflow runs table's **Ticket** and **Version** columns are no longer sortable either, since neither maps to a real field and clicking to sort them used to error out. * The **Auth Test Endpoint** field on a [custom Foundry integration](/documentation/automate/foundry/integrations) keeps what you type instead of being rewritten as you go. * The [audit log](/documentation/platform/organizations/audit-log) loads the next page of results instead of repeating the first. * [Out of office](/documentation/platform/my-settings) status reverts to your manual setting when a Slack sync fails, rather than leaving a stale status behind. * [Foundry](/documentation/automate/foundry/integrations) OAuth integrations refresh their tokens just in time instead of returning 401s, show **Reconnect** for client-credentials connections, and no longer crash on secrets containing colons. * Images sent to AI agents are passed to the model as S3 URIs, fixing attachment handling on large files. * Guests no longer see the table view option in the sidebar, where it was never applicable. ## Notion and Jamf Pro in Foundry Notion and Jamf Pro logos side by side representing new Foundry native credential bridges Foundry actions can now use credentials from your connected Notion and Jamf Pro integrations. Select either as the action's connection and Foundry supplies the credentials at run time, joining Slack, Google, Okta, and FleetDM as available native bridges. [Learn more →](/documentation/automate/foundry/integrations) ## Attach existing Slack threads to tickets Workflow builder showing a Reaction Added trigger connected to a Create Ticket Thread action The Slack **Create Ticket Thread** workflow action can now attach an existing Slack thread to a ticket by URL, instead of only creating new threads. Add an optional custom message and toggle the ticket card on attach. Comments sync bidirectionally from the moment of attach. [Learn more →](/documentation/automate/workflows/triggers-actions) **Quality of life updates:** * Drag-to-reorder ticket detail sections between the tab bar and sidebar. Your layout saves to user preferences and follows you across workspaces. * [Analytics](/documentation/measure/analytics) widgets can now pin their own date range instead of following the dashboard picker. * [Confluence knowledge sync](/integrations/confluence/knowledge) uses the shared knowledge sources picker. Choose specific pages and blog posts (up to 3 levels deep) instead of pulling in the whole space. * New **Agent Outcome** column on the tickets table, sortable and groupable. See [views and filters](/documentation/tickets/organize/views). * [Copilot](/documentation/automate/copilot/overview) visual refresh: rounded side panel, consistent attachment cards, and a smoother thinking indicator. * [Foundry](/documentation/automate/foundry/overview) studio now shows clickable suggestion chips above the input when the model offers follow-up choices. * [SLA analytics and filters](/documentation/automate/slas) now account for business hours, pauses, and superseded targets. * A new **Complete Tasks** [workflow action](/documentation/automate/workflows/triggers-actions) marks task list items as complete on the trigger ticket. * Workflow [code actions](/documentation/automate/workflows/triggers-actions) can now return structured JSON data. Downstream steps reference individual fields via the variable picker. * The [MCP](/documentation/automate/mcp/tools) ticket tools now accept a `files` parameter for attaching files directly from tool calls. * A new [MCP tool](/documentation/automate/mcp/tools) lets AI assistants open access requests programmatically. * The **Send Email** [workflow action](/documentation/automate/workflows/triggers-actions) now supports file attachments. **Bug fixes:** * Submitting a [request form](/documentation/tickets/forms/custom-fields) no longer fires duplicate events, so form-triggered workflows run once per submit. * Private [form custom fields](/documentation/tickets/forms/custom-fields) can now be toggled required directly on the form without the workspace-level floor applying. * The **Assignee is Me** [ticket filter](/documentation/tickets/organize/views) now works on the main tickets table. * [Slack emoji](/integrations/slack/emoji-actions) self-assignment (👀) and [Public Emoji Actions](/integrations/slack/emoji-actions) now respect the workspace **Assignee Options** scope. * [Okta](/integrations/okta/overview) external-group syncs on tenants with many groups no longer hit rate limits. * [SLA](/documentation/measure/analytics) drill-downs work again, and the ticket filter is now labeled **SLA Outcome** (Met / Breached). ## Knowledge Gaps Knowledge Gaps feature showing a book icon with a Beta badge [Knowledge Gaps](/documentation/automate/knowledge/knowledge-gaps) looks at tickets your AI agent could not resolve, groups the similar ones together, and surfaces them as a ranked list of recurring topics your knowledge base does not cover well yet. Each gap gets a severity bucket driven by ticket volume and a 30-day trend, a classification of whether content is missing or just insufficient, and example tickets so you can see what customers are actually asking. Detection runs automatically each week per workspace, and you can generate a KB article directly from any cluster. Knowledge Gaps is in private Beta. Reach out on Slack or in-app chat if you'd like access. [Learn more →](/documentation/automate/knowledge/knowledge-gaps) ## Gate agent tools with per-rule execution policies Each tool referenced in an [agent rule](/documentation/automate/agents/configure#tool-execution-policies) now has an **execution policy** that decides what happens before the agent invokes it: **Auto-execute** for read-only lookups, **Requires confirmation** to prompt the requester before a change, or **Requires approval** to open an approval round. Policies are scoped per rule, so the same tool can run automatically in a low-risk rule and require sign-off in a sensitive one. Write and delete tools default to confirmation, and read tools default to auto-execute. When you pick **Requires approval**, choose workspace admins or any [approval template](/documentation/tickets/approvals/templates), including named users, groups, and role-based approvers like the requester's manager. If a single agent run plans multiple approval-gated calls, Ravenna groups them by approver set and opens one parallel round per group, so approvers see one consolidated request instead of a stream of prompts. [Learn more →](/documentation/automate/agents/configure#tool-execution-policies) ## Scheduled Slack ticket reports built by Copilot Ask [Copilot](/documentation/automate/copilot/build-automations) for a recurring Slack report of live ticket data, for example your open tickets each morning or a team's backlog every Monday, and it builds the workflow end to end. Copilot creates a cron-based schedule trigger, queries the tickets you describe, formats the results, and posts them to a Slack DM or channel. You preview the formatted message and iterate on it before turning the workflow on. [Learn more →](/documentation/automate/copilot/build-automations#walkthrough-scheduled-slack-reports-of-ticket-data) **Quality of life updates:** * The built-in tool group in the [agent configuration](/documentation/automate/agents/configure#ravenna-tools) tools picker is now labeled **Ravenna**, matching how the docs and rules already refer to these built-in tools. * [Custom form fields](/documentation/tickets/forms/custom-fields) can now be marked **Hidden**, which removes them from every requester-facing form surface (web request form, portal, Slack and Teams dialogs, bulk editor, AI agent) while keeping them editable by agents on the ticket, prefillable by workflows, and available via the API. Required and Hidden are mutually exclusive. * **Text Area** [custom fields](/documentation/tickets/forms/custom-fields) now support opt-in rich text. Admins flip a **Rich text** toggle on the field and requesters get a formatting toolbar on the web and Slack's native rich text input, with values stored as markdown. * [Copilot](/documentation/automate/copilot/overview) and the [MCP server](/documentation/automate/mcp/tools) ticket tools (create ticket, update ticket, add ticket message, update ticket message) now accept a `files` parameter so tool calls can attach files (up to 5 per call) directly from a URL or base64 payload. Each attachment is validated, MIME-checked, size-capped, and mirrored to Slack like any other ticket attachment. * The Slack [Create Ticket Thread](/documentation/automate/workflows/triggers-actions) workflow action can now attach an **existing** Slack thread to a ticket by URL, post an optional custom message, and toggle the ticket card. Comments sync bidirectionally from the moment of attach. * Workspace admins can now fast-forward timer-based Wait steps on in-flight [workflow runs](/documentation/automate/workflows/monitor) from the run detail panel, immediately advancing past the sleep without cancelling and re-running the whole workflow. * Admins can now block and unblock individual [organization members](/documentation/platform/roles-access) from the org members table. Blocked users are signed out on their next request and shown an account-suspended screen, without removing them from the org or losing history. * A new **Edit Completed Approvals** workspace setting lets admins edit or reset an [approval process](/documentation/tickets/approvals/rounds) after it has been decided. The timeline now shows the correct outcome for prior decisions even after a reset. * When an access request needs manual [provisioning](/documentation/manage-access/applications#post-provisioning-message), the ticket assignee now gets a Slack DM in the ticket's mirror thread with a **Provision access** button that provisions the entitlement inline. * The workflow builder's app and action selection sidebar supports full keyboard navigation. Use the arrow keys to move through search results and press **Enter** to select, no mouse required. * [Copilot](/documentation/automate/copilot/overview) messages render through a new streaming-aware markdown pipeline, eliminating the visual flash between the streaming and finished states. Full-page Copilot also gets larger, easier-to-read text. **Bug fixes:** * [Google Drive knowledge sync](/integrations/google-drive/knowledge) now detects when its access token has been revoked and prompts you to reconnect the integration, instead of failing silently and leaving documents out of date. * A running [workflow](/documentation/automate/workflows/overview) no longer receives duplicate trigger signals after it has already started. Trigger signals are now scoped to starting new runs only, so the same ticket event is not processed repeatedly. ## Native Ravenna Github App Ravenna GitHub App connected for knowledge sync The GitHub integration for [knowledge sync](/integrations/github/knowledge) is now powered by the Ravenna GitHub App. Install it on an organization or personal account, pick exactly which repositories Ravenna can read, and manage access from GitHub at any time. Documentation files import with their folder structure preserved and stay up to date through auto-sync. [Learn more →](/integrations/github/knowledge) ## Curate Portal suggestions per workspace Suggested questions in the [Portal](/documentation/platform/portal) can now be tailored per workspace. Each workspace maintains its own list of suggestions, adds back any organization-level questions it has dropped, creates new suggestions inline, or hides suggestions entirely with a single toggle so requests reach the right place. Workspaces start from the organization list until an admin customizes it, and only portal managers see the controls. [Learn more →](/documentation/platform/portal) ## Custom ticket attributes in Slack and workflows [Custom ticket attributes](/documentation/tickets/forms/attributes) now appear on the Slack work object card and are fully supported in [workflows](/documentation/automate/workflows). Workflow actions can create or update tickets with attribute values, workflow conditions can match on attributes, and Copilot suggests and validates attributes when building workflow steps. The workflow step input panel lists attributes alongside built-in ticket fields. [Learn more →](/documentation/automate/workflows) **Quality of life updates:** * The queue **Ticket Sync** settings now use a single toggle to turn the integration on or off, and the disconnect control lives with it in the card header. * The tickets table SLA column is cleaner. It shows the most urgent pending target while a ticket is active, then a compact `SLA: met/total` summary once every target is resolved. * Foundry's **Available APIs** panel now lists every Foundry-enabled integration, including native integrations like Slack workspaces and connected APIs like Meraki. Clicking a native integration creates a new function with the integration already connected. See [Foundry integrations](/documentation/automate/foundry/integrations). * [Copilot](/documentation/automate/copilot/overview) suggests up to three quick replies, ordered best-first, so the strongest suggestion is always visible. * Saving an [agent rule](/documentation/automate/agents/customize) without a title now shows an inline **Required** error and focuses the title field. Long agent names in the picker are no longer cropped. * The [analytics](/documentation/measure/analytics) percentage aggregation dropdown has an explicit **None (share of total)** option, and the Agent Outcome filter can target tickets with no outcome yet with **is empty** and **is not empty**. * [MCP](/documentation/automate/mcp/overview) OAuth now supports the `offline_access` scope, so MCP clients stay signed in across sessions without re-authenticating. * The default inactivity window for the workspace [auto-close policy](/documentation/platform/workspaces/settings#automation) is now 30 days, so new workspaces get a longer default before a stale ticket is warned and closed. Existing workspaces keep whatever window they already set. **Bug fixes:** * [Agent rules](/documentation/automate/agents/customize) no longer flag knowledge resources in nested folders as invalid. Rules that point at documents inside subfolders stay green. * The Portal home loads more smoothly. Hero, chat input, team list, and workspace cards now reveal together, and organizations that enable **Show organization logo instead of profile picture** without uploading a logo get a clean default fallback. * Date-range filter calendars on ticket lists and analytics widgets highlight the day you clicked, including in timezones near the international date line. ## Rearrange steps in the workflow builder Dragging the Get On-Call Users step below the Ticket Created trigger to reorder it in the workflow builder Drag a step to reposition it in the [workflow builder](/documentation/automate/workflows/workflow-builder#reorder-steps). Grab a step by its card and drop it onto a highlighted target to move it up or down within a linear chain, or to swap it with another step, and Ravenna rewires the surrounding connections for you. Triggers, loop boundaries, and branch group roots like an If/Else split stay pinned so the graph stays valid. Reordering is available to anyone who can edit the workflow. [Learn more →](/documentation/automate/workflows/workflow-builder#reorder-steps) ## Share forms publicly, no login required Turn on **Public access** for a [form](/documentation/tickets/forms/overview#share-forms-publicly) to host it at an unguessable URL that anyone can submit without signing in, so you can collect requests from vendors, event attendees, or anyone outside your organization. Public forms accept simple input fields only and never expose workspace data, and each submission is rate limited and protected by a CAPTCHA. Copy the public link from the **Share** popover, and rotate the link whenever you need to invalidate the old one. [Learn more →](/documentation/tickets/forms/overview#share-forms-publicly) ## Use Slack, Google Workspace, and Okta credentials in Foundry actions Slack, Google Workspace, and Okta connected to Foundry as native integrations Foundry-generated actions can now call the Slack, Google Workspace, and Okta APIs using your connected integrations, without configuring a separate token. Select one as the action's integration and Foundry supplies the credentials at run time: Slack signs each request with the stored workspace token, while Google Workspace and Okta mint a short-lived, scope-narrowed token from the org connection you already trust. Generated code just calls the API method it needs. Slack actions bind to a specific workspace, and admins can repoint an action to a different workspace from the action's **Integrations** panel. [Learn more →](/documentation/automate/foundry/integrations) **Quality of life updates:** * Ticket details now leads with a date chip and a requester chip in the metadata row, and drops the redundant assignee chip since assignee already lives in the sidebar. Long ticket subjects no longer leave a big gap above the first message, and message reaction tooltips render in the right place instead of jumping to the top of the page. * The **Share** popover on [analytics dashboards](/documentation/measure/analytics) has been refreshed with a cleaner layout, clearer sharing options, and tighter defaults so it matches the rest of the settings surfaces. * The [ticket sidebar](/documentation/tickets/organize/views) shows fewer, quieter SLA badges. Non-actionable states are hidden, the SLA section only expands when there's something to show, and the sidebar renders faster on tickets with many attributes. * Ravenna AI messages have a refreshed card and bubble treatment across the `/ai` chat, the side panel, and agent chat. User messages get a tighter bubble, and attachment cards (workflows, tickets, filters, widgets) share a consistent shell. * Organization admins can now retry a failed [custom email domain](/documentation/platform/organizations/settings#email) verification directly from settings. If AWS can't find the DNS records inside the 72-hour window, a **Retry Verification** button restarts the check without deleting and re-adding the domain. **Bug fixes:** * Ravenna AI's message classifier now understands image and file attachments. A screenshot or document dropped into a thread, even with no accompanying text, is treated as a reply to the agent when the agent recently asked for one, so evidence-only responses no longer get skipped. * Slack tickets that Ravenna auto-creates from a new thread now include the triggering message before they publish. Ticket previews, notifications, and Ravenna AI's first read all see the actual request instead of an empty body. * The [tickets table](/documentation/tickets/organize/views) no longer breaks its layout when custom-field columns are added. Rows keep their alignment as columns are toggled. * Guests can no longer perform ticket mutations they shouldn't. Guest workspace members are now treated the same as non-members for ticket edits, matching how [roles and access](/documentation/platform/roles-access) already describe guest behavior. * Non-member requesters can attach files to a form's file custom field on the [Portal](/documentation/platform/portal) and on public [hosted forms](/documentation/tickets/forms/overview), and rapid double-clicks on submit no longer create duplicate tickets. * Agent chat logs no longer leak conversations across agents. When you open an agent's chat history, you only see conversations that belong to that agent. * Microsoft Entra group sync now links groups back to the enterprise applications they're assigned to, so [Entra-backed access levels](/integrations/microsoft-entra/overview) resolve correctly for group-based provisioning. * SSO sign-ins no longer trip the email verification step. Users completing SSO log in on the first try instead of being sent through an extra verification round trip. ## SLA policies now switch when ticket attributes change An SLA target badge showing 4h 00m remaining SLA targets are no longer frozen at the moment a ticket is created. When a ticket's priority, category, tags, channel, assignee, requester, or form changes, Ravenna re-evaluates every matching [SLA policy](/documentation/automate/slas) and switches the ticket to the one that now applies. Elapsed time carries over, so the new policy's clock reflects the real wait time rather than restarting. If no policy matches anymore, the ticket's targets are cleared automatically. This keeps SLA tracking accurate on tickets whose scope evolves after they come in. [Learn more →](/documentation/automate/slas) ## Plan multi-step automations with Copilot Copilot has a new `plan_automation` tool that recommends the right shape for a multi-resource ask before it builds anything. Describe the goal, and Copilot reads your workspace inventory (queues, forms, custom fields, agents, agent rules, connected agent tools, Foundry integrations, and workflow actions), picks between a native workflow, an agent with rules, or a Foundry-backed integration, and returns a concrete plan you approve before any create step runs. Asks that aren't automations (like analytics questions) are politely declined with a pointer to the right surface. [Learn more →](/documentation/automate/copilot/build-automations) **Quality of life updates:** * Agent rules can now set tags and statuses. Rule instructions that reference `[tag: ...]` or `[status: ...]` in [agent rules](/documentation/automate/agents/customize) apply those values automatically after publishing, using the same bracket mention pattern that already worked for categories and workflows. If a rule sets a status, it runs after publishing so it isn't overridden by the queue's default open status. * New users provisioned in Okta now flow into Ravenna automatically. When [Okta workflows](/integrations/okta/workflows) create a user, the sync creates the matching Ravenna user in place instead of waiting for the person's first sign-in. * Foundry actions bound to Slack can be retargeted to a different workspace again. The linked native bridge row in the configure panel gets a switch icon (admin only) that lists your org's other Slack workspaces and repoints the action in one click. * Foundry `ctx.fetch` once again reaches unauthenticated public APIs (like a weather endpoint) from a function whose primary integration is a native bridge. The bridge's host allowlist now only constrains the bridge client's own authed calls, not the generic escape hatch. **Bug fixes:** * Slack Connect messages now route to the workspace that actually owns the channel. Previously, a guest posting in a shared channel owned by another org could be silently dropped when the connected queue lived in a different Ravenna org; the channel-first lookup now resolves across orgs. * Copilot no longer crashes the entire page when a single response attachment card fails to render. Each card sits behind its own error boundary and degrades to a muted "Couldn't display this item." fallback so sibling cards, follow-up chips, and the assistant's answer keep working. This covers `/ai`, the side panel, KB explain, and agent chat. * Guest workspace members can no longer open a ticket by direct link that they wouldn't see in their filtered list. Ticket visibility, semantic search, and unread counts are now consistently scoped to participants for guests across every surface. Copilot ticket lookups also verify the ticket belongs to the caller's workspace, closing a cross-workspace read/write hole. * Workflow direct URLs are decoded correctly on workspaces using a custom domain, so tokenized links from workflow actions resolve on the first click instead of failing at the URL parser. * Slack knowledge base answers with citations render as the original plain markdown source links again, replacing the card layout that was in flight. ## Auto-close stale tickets after a warning Workspaces with the inactivity policy on now get a recurring sweep that finds tickets which have gone quiet, decides whose turn it is to reply, posts a single warning that mentions the right person, and closes the ticket automatically if nobody responds within another inactivity window. Empty tickets — where the requester opened a ticket but never described the ask — are also picked up and nudged instead of being skipped. One knob (`inactivityHours`) governs both the warning and the close, so agents stop hunting through untouched tickets that nobody plans to answer. [Learn more →](/documentation/platform/workspaces/settings#automation) ## User settings work without a workspace Profile, notifications, preferences, appearance, connected apps, and passkeys now live at slugless `/settings/*` URLs and load for any signed-in user, including org-portal members who don't belong to a workspace. The org portal sidebar surfaces **Profile** and **Notifications** entries so those users can actually reach and save their settings — including their Slack vs. email notification preferences — instead of being bounced to the Portal chat. Existing workspace-scoped links redirect to the new paths automatically. [Learn more →](/documentation/platform/my-settings) **Quality of life updates:** * The ticket details page is now responsive on mobile and tablet: keyboard hints and navigation labels hide on narrow screens, padding tightens, and message cards resize so tickets are usable from a phone. Conversation preferences — sort direction and **Hide logs** — now persist across tickets, and posting a comment auto-scrolls to the newest message when the thread is sorted oldest-first. * The **Access Entitlements** and **Access Levels** settings filters default to multi-select ("is one of"), so you can filter by several applications, access levels, or statuses in one pass instead of stacking single-value filters. * Ticket events now display the correct application for manually provisioned entitlements, so audit history matches what agents see in the app. * A new **Processing** status is available on entitlement triggers, so [workflows](/documentation/automate/workflows/triggers-actions) can fan out on in-flight SAR provisioning alongside the terminal outcomes. * Comments on work objects and public forms are no longer gated behind feature flags — both are on for every workspace. * The Foundry action sidebar keeps you at the group root when you clear a search instead of snapping back to a previously-open group, and surfaces a warning when an action references a native integration that has been deleted. * The Ravenna AI [Copilot](/documentation/automate/copilot/everyday-tasks#analytics-and-reporting) chat picks up analytics parity with the standalone dashboards, so questions asked from the `/ai` chat return the same shape of data you'd see building the equivalent widget by hand. * Refreshed icons and chrome across the `/ai` surface make the chat panel, message actions, and tool chips easier to scan at a glance. **Bug fixes:** * The **Wait** and **Wait Until** workflow steps once again accept duration strings like `5d`, `-3h`, and `+1w`. Recent form-generation changes had silently blocked letters and reduced the inputs to bare numbers. * The **Agent Outcome** filter on saved ticket views now returns tickets that actually match the selected value, and automatically pairs itself with a **Done**/**Closed** status filter so results aren't hidden by the default view scope. * Editing a ticket attribute (**Status**, **Priority**, **Channel**, and others) in the sidebar no longer flashes the old value before settling on the new one after the save. * Public [hosted forms](/documentation/tickets/forms/overview) with select, multi-select, or timezone fields no longer crash when opened by an anonymous submitter, and use consistent fonts across every field. * Ravenna AI now attributes access requests and escalations to the actual person the requester named, not the message author, so a manager filing a request on behalf of a teammate provisions access for the teammate. * Slack Workflow app forms once again populate the **Application Select** dropdown and its dependent fields (like **Access Level**), so forms opened from a Slack workflow finish end to end. * Sidebar form titles wrap and truncate cleanly at two lines instead of overflowing their card, and the SLA sidebar layout and attachment overlay rendering are fixed. * The Ravenna AI conversation and message classifier are pinned to the current generation of Google models after Google retired the previous flash tier, so agent responses and classification stop failing on retired-model errors. ## Use Cloudflare credentials in Foundry actions Cloudflare connected to Foundry as a native integration Foundry-generated actions can now call the Cloudflare API using your connected Cloudflare integration, without configuring a separate token. Selecting Cloudflare as an action integration signs each request with the stored API token and bakes your account ID into the base URL, so generated code just appends the API path. The Cloudflare connect modal now also asks for the required account ID up front, so submissions no longer silently fail. [Learn more →](/documentation/automate/foundry/integrations) ## Auto-close tickets when an access request is provisioned Tickets linked to an access request now move to a **Closed** status automatically when the request finishes provisioning. Ticket status stays in sync with what's actually happening in the connected app, so agents don't have to circle back and close the ticket by hand once access is granted. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Filter directly from the Cmd-K command palette The global search palette (`Cmd/Ctrl+K`) now has a filter row above ticket results. Status and priority quick-filter buttons are always visible, and a **+ Filter** menu exposes the full field list with a guided operator → value flow. Active filters render as compact chips and carry through to the **See all results** page so you don't lose the query on the way to the full [table view](/documentation/tickets/organize/views). **Quality of life updates:** * The **Add sub-ticket** modal now supports multi-select, so you can attach several tickets as sub-tickets in one pass instead of adding them one at a time. Selected tickets stay pinned even if they fall out of the current search, and `Cmd/Ctrl+Enter` confirms the batch. See [ticket relations](/documentation/tickets/relations) for how the hierarchy works. * Organization admins can now invite members directly from **Organization Settings → Members**, picking the target workspace in the invite modal. Previously, invites had to be sent from each individual workspace. * The workflow editor now has a pencil icon next to the breadcrumb that opens the same rename dialog as the [workflow list](/documentation/automate/workflows/workflow-builder), so you can name a new workflow without leaving the editor. The button hides once the workflow is **Active**. * Ticket metadata chips are now interactive: click the assignee or priority chip to change it inline, click the ticket ID to copy it, and jump straight to the source Slack thread from the source chip. Tickets with no priority no longer render an empty chip. * The ticket action dock puts **Private note** ahead of **Mark as done**, and the **Undo mark as done** state uses a dedicated icon so the two actions are easier to tell apart at a glance. * The **Download all attachments** action from yesterday's release now also covers a ticket's own attachments. When a ticket has more than one attachment, an **Attachments (N)** header appears above the tiles with a **Download all** button that packages them into a single zip. See [ticket attachments](/documentation/tickets/attachments). * Chatlog filters for **Message**, **Sender**, and **Agent** now match in the database instead of scanning first-message content in application code, so chatlog queries return faster on large workspaces and skip the extra work entirely when no chatlog filter is set. * Analytics dashboards go back to the multi-hue categorical chart palette, restoring distinct colors per series after a brief monochrome-blue experiment. **Bug fixes:** * Fixed a data-scoping issue on chat log routes where a user with a chat log ID from another organization could read that org's events. Ticket event reads, updates, and deletes now enforce organization and workspace access on every request. No user action is required. * Adding a hyperlink in the ticket-create rich text editor no longer submits the underlying **Create ticket** form. Confirming or pressing **Enter** in the link popover now only applies the link. * Form composers with a **Requester** system field no longer show two **Requester** entries in the interpolation dropdown. * Renaming a system field (for example, **Description** → **Justification**) on a form no longer trips the duplicate-label check when the same field is re-added, and drag-drop no longer appends a numeric suffix. The label edit modal now also notes that a rename only applies to the current form. * Deleting an approval round now soft-deletes it, so the ticket event history around the approval stays intact. Notifications only fire when an in-progress round is deleted. ## Automatically reopen resolved tickets when the requester replies Ravenna now reopens a ticket in a **Done** or **Closed** status group when the requester sends a new message that reads as a genuine request. Reopens work across every channel, including email, Slack, Microsoft Teams, the Admin, and the Portal. Bot senders and internal agent comments never trigger a reopen. When a reopen fires, Ravenna posts a private system note on the ticket explaining why it moved back to **Open**. The setting is on by default. Workspace admins can toggle it from the new **Re-Open Tickets** card under **Settings** → **Workspace** → **Automation**. [Learn more →](/documentation/platform/workspaces/settings#re-open-tickets) ## Lock shared table views and duplicate any view Shared [table views](/documentation/tickets/organize/views) now have an **Allow edits** toggle that controls who can promote personal changes back to the shared view. When it's off (the new default), non-owner, non-admin members no longer see the **Save for all** and **Save view options to view** actions, so their personal filter, column, sort, and display-mode tweaks stay scoped to them. Owners and workspace admins always bypass the lock. Every member can still customize the view for themselves through the existing personal overrides model. Any workspace member can also **Duplicate** a view from the sidebar's view menu. Duplicates are always created private, locked (**Allow edits** off), and owned by you. Each copy captures your *effective* view, layering your personal filter and display overrides on top of the shared configuration instead of cloning only the owner's saved definition. [Learn more →](/documentation/tickets/organize/views#lock-shared-views) ## Inline previews and download all for ticket attachments Ticket attachments now open in a redesigned preview with a header, filename, and one-click download. Inline previews cover PDFs, audio, and text files alongside images and video. Messages with more than one attachment get a **Download all attachments** action in the message menu that packages everything into a single zip. [Learn more →](/documentation/tickets/attachments) **Quality of life updates:** * The entitlement status [workflow trigger](/documentation/automate/workflows/triggers-actions) now accepts multiple statuses in one rule, so a single workflow can fan out on **Provisioned**, **Deprovision failed**, **Skipped provisioning**, and other outcomes together instead of duplicating the trigger. * LLM calls that power Copilot, agents, and the message classifier now fall back to a secondary provider on retryable errors, so a transient outage or rate limit at one provider no longer surfaces as a failed run. * The **SLAs** section on the ticket sidebar now starts collapsed when a ticket has no matching SLA targets, so the attribute panel stays focused on fields that apply. **Bug fixes:** * The workflow editor side panel no longer shows stale inputs after switching a step to a different action. The panel now re-renders cleanly when the selected action changes. * Message editor: pressing **Shift+Enter** at the end of a code fence now creates the code block instead of leaving raw backticks. Picking a language that isn't recognized falls back to plain text instead of throwing. * [Copilot analytics](/documentation/automate/copilot/everyday-tasks#analytics-and-reporting): grouped **average**, **sum**, **min**, **max**, and **percent of** queries no longer error out. Grouping by a time field (like created at or hour of day) now defaults to a daily bucket so the query runs without extra prompting. ## Use Microsoft Entra credentials in Foundry actions Microsoft Entra connected to Foundry as a native integration Foundry-generated actions can now call the Microsoft Graph API using your connected Microsoft Entra integration, without registering a separate OAuth provider. When you select Microsoft Entra as an integration on an action, Foundry mints a short-lived Graph token at run time using the Entra app registration your org already trusts, and Copilot's code generation gets an Entra-specific hint that steers it toward the right Graph permissions. [Learn more →](/documentation/automate/foundry/integrations) **Quality of life updates:** * `/support` is now a Slack [slash command](/integrations/slack/slash-commands) alongside `/rav` and `/help`, giving teams that use "support" as their everyday word another discoverable entry point into ticket creation. * Foundry actions now let you configure a linked built-in integration inline from the **Integrations** panel, so admins can adjust scopes and native credential settings without leaving the action editor. * Ticket lists now sort by more [custom field types](/documentation/tickets/forms/custom-fields), including **Duration**, **Timezone**, and **Boolean** fields, so queues built on those columns stay in a consistent order. * [Google Workspace group sync](/integrations/google-workspace/workflows) now stores the group description alongside owners, managers, and settings, so descriptions stay in step with what's set in the Google Admin console. **Bug fixes:** * Imported Slack bot users are once again selectable as assignees, authors, approvers, and requesters when a workspace has bot users enabled, restoring parity with mention search. ## Inline-edit dates and custom fields in the tickets table You can now edit date columns and custom field columns directly from the tickets table, without opening each ticket. Click a cell to update a due date, single- or multi-select tag, or text value in place and move on to the next row. [Learn more →](/documentation/tickets/organize/views) ## Resolution path metric on ticket analytics The Tickets dashboard now includes a **Resolution path** breakdown that classifies every resolved ticket as **human touched**, **AI resolved**, **workflow only**, or **unclassified**. Group any Tickets widget by **Resolution path** to see the mix over time, and use the new **No Human Touch** percent-of field to track the share of resolved volume that closed without an agent stepping in. [Learn more →](/documentation/measure/analytics) **Quality of life updates:** * The [Okta requester card](/integrations/okta/cards) now shows the user's **Status** and **Last login**, so you can spot deactivated or stale accounts at a glance. * The Portal home now lists workspaces you belong to but haven't opted into as a portal user, so members can jump straight into those teams instead of hitting a dead end. * The [agents editor](/documentation/automate/agents/configure) tool list has a cleaner header with an inline **Add** button, a lighter tool row layout, and tidier @mention chips. * The [OAuth provider dialog](/documentation/automate/foundry/integrations) groups fields under **Basic**, **Authorization**, and **Token exchange** headings, adds a grant type control that hides irrelevant fields, and cleans up the **Advanced settings** section. * The **Connect fields** tab in the OAuth provider dialog is now hidden for org-scoped providers, since connect fields only apply to global provider templates. * When [Foundry action research](/documentation/automate/foundry/actions) hits an unhelpful cached page, it can now skip the cache, exclude URLs it has already tried, and fetch a direct URL you paste in, so iterating on doc discovery is faster. **Bug fixes:** * Foundry agent tools now route through the same approval and confirmation gates as other agent actions, so guardrails you configured on an integration apply everywhere. * Foundry OAuth integrations using the **Client Credentials** grant type now refresh their tokens correctly instead of failing once the initial token expires. * SharePoint knowledge base citations now open in the SharePoint browser viewer instead of forcing a file download. * Knowledge base resyncs now patch source URLs on existing documents, so links stay current when a source changes how it exposes URLs (for example, SharePoint's viewer URLs). * Google Drive knowledge sources now resolve file IDs from the correct field, fixing metadata fetches for documents added after the recent knowledge source refactor. * @mentions in Slack messages used with **Rapid ticket creation** now convert to plain names in the ticket description instead of leaving raw Slack IDs. ## Configure your Okta requester card Okta requester card on the ticket sidebar showing status, email, department, manager, and timezone The Okta card on the ticket sidebar is now driven by a field configuration you control, so you can show the identity attributes your agents actually need and hide the rest. Field visibility persists per workspace and applies to every ticket where the requester resolves to an Okta user. [Learn more →](/integrations/okta/cards) ## Client Credentials OAuth providers in Foundry Register a Foundry OAuth provider with the **Client Credentials** grant type for server-to-server APIs that authenticate the whole org with a single machine credential. A new **Connect fields** builder lets you collect per-org values (like a tenant ID or account slug) during connect and interpolate them into the token URL, so one provider template covers customers with different endpoints. [Learn more →](/documentation/automate/foundry/integrations#grant-types) **Quality of life updates:** * You can now [sort ticket lists by a single-select custom field](/documentation/tickets/forms/custom-fields), so queues built on tags like tier, environment, or region stay in a consistent order. * SLA over-time analytics widgets now [include tickets with no priority](/documentation/measure/analytics), so at-risk and breached counts match what you see in the ticket list. * The Okta password reset and MFA reset agent tools are now separate actions, so agents pick the exact remediation instead of running both. See the [Okta workflows](/integrations/okta/workflows) reference. * When an AI agent hits its tool-call limit, it now posts a short summary of what it got done instead of leaving the conversation in a "thinking" state, in Slack, on tickets, and in the Portal. * Slack message edits now sync attachment additions and deletions to the linked ticket, keeping the ticket file list in step with the source message. * Consecutive SLA events on a ticket are grouped in the activity timeline, so long-running tickets read more like a summary and less like a wall of events. * The knowledge base document picker now reuses an existing Google Drive connection when one is already set up, so you skip the reconnect step when adding new folders. * Knowledge sources whose documents are all archived are now hidden from the ingestion queue, so status views only surface sources with real work to do. * The SharePoint integration tile now uses the SharePoint logo. **Bug fixes:** * The SLA tag filter now displays the tags you've selected instead of showing an empty chip. * Synced groups from identity providers now appear on the **Application → Groups** tab again. * Reminders on tickets now cancel correctly when the ticket status changes to a state that shouldn't carry a reminder. * The escalation banner in Slack no longer renders with a broken border. * Time to Resolution and Time to Close widgets no longer show negative durations when a ticket is reopened and closed again. * The knowledge source picker modal no longer clips its content on smaller screens and scrolls the full list. * Notion knowledge sources refreshed right after a re-auth now wait for the index to catch up, so documents no longer briefly disappear. * Reconnecting a Freshservice knowledge base no longer duplicates or orphans source records. * Foundry OAuth providers now free their slug on delete, so you can recreate a provider with the same name. Connecting a Client Credentials provider from **Settings → Integrations** now works on the first click. * The Foundry OAuth **Connected** badge now shows immediately after a successful connect instead of only after a page refresh. ## Chart analytics from Copilot and MCP Ask Copilot to count, chart, or trend data over tickets, ticket messages, knowledge base documents, or workflow runs. Copilot picks the right card type, renders it inline, and offers to save it as a widget on a new or existing dashboard. The same tools are exposed over the MCP server, so any connected AI client can query analytics, list and read dashboards, and add or update widgets without leaving the conversation. [Learn more →](/documentation/automate/copilot/everyday-tasks) ## Slack DMs for @mentions in private notes @mention a workspace member in a [private note](/documentation/tickets/private-notes) and they get a Slack DM about the callout. The DM includes who mentioned them, the ticket title, an excerpt of the note, and buttons to open the ticket in Ravenna or jump to the matching Slack thread. Because private notes never appear in request or DM threads, this DM is the only way a mentioned teammate is alerted. [Learn more →](/documentation/tickets/private-notes) **Quality of life updates:** * [Agent outcome rate as a percentage aggregation](/documentation/measure/analytics) is now available on analytics widgets, so you can chart the share of tickets resolved by AI without pre-computing the math. * [Agent outcome and automation status filters on analytics widgets](/documentation/measure/analytics) let you scope any chart to deflected, agent-assisted, or human-handled tickets, and to automated, automatable, or non-automatable resolutions. * Foundry skips the initial clarifying questions when you describe a new function and preserves your existing code as it iterates, so you spend less time re-confirming intent and re-pasting work. * Foundry iteration prompts now include test run results and the identity behind each change, so follow-up edits stay grounded in what actually happened on the last run. * The inline **Create new tag** row is back in the tag picker, so you can add a missing tag without leaving the dropdown. * The role editor hides the **Guest** role for non-guest members, so you no longer have to scroll past an option that does not apply. **Bug fixes:** * AI-generated ticket titles and descriptions no longer pull content from private notes, keeping internal context out of customer-visible fields. * Ticket cards and form submission cards render correctly in the [Portal chat](/documentation/platform/portal) when the ticket lives in a different workspace, instead of failing to load. * The parent ticket link in the ticket detail metadata chips is clickable again, so you can jump from a sub-ticket to its parent in one click. * Slack form submission attachments are scoped to the submitter's request, so files uploaded through one form no longer surface in unrelated Slack ticket threads. * Drag-and-drop reordering of [form custom fields](/documentation/tickets/forms/overview) saves the new order reliably instead of snapping back. * Switching between Copilot agents mid-conversation no longer leaves the chat wired to the previous agent. ## Share form links anywhere, including Slack Slack Form Unfurl Copy a direct Portal URL to any form from the forms list or form detail page, then drop it into a Slack channel, DM, or thread. The link unfurls as a card with an **Open Form** button that launches the form as a Slack modal, so requesters can submit without leaving Slack or hunting through screenshots. [Learn more →](/documentation/tickets/forms/overview) **Quality of life updates:** * [Notion and GitHub knowledge source picker](/documentation/automate/knowledge/overview) now lets you both add new sources and remove already-imported ones in the same dialog, with the list staying in sync as you edit. * [Confluence panels import as GitHub-style alerts](/integrations/confluence/knowledge) so info, note, tip, warning, and error panels keep their callout styling when synced into Ravenna knowledge instead of flattening to plain paragraphs. * [Percent of distribution mode for analytics](/documentation/measure/analytics) adds a new behavior to the **Percent of** aggregation. Pair it with a **Group by** dimension and leave **Field to Aggregate** empty to chart each group's share of the total as percentages that sum to 100%. * Applying an approval template to a ticket runs noticeably faster, so large templates with many approver groups no longer stall the ticket while the rounds are built. **Bug fixes:** * Workflow step input filters: **Channel**, **Source**, **Provisioning Method**, and **Access Level** options now populate reliably in ticket filter conditions, even when those fields aren't referenced elsewhere in the workflow. * Outbound ticket emails skip bot accounts when resolving recipients, so SES no longer rejects messages addressed to non-mailable system users and email-sourced tickets thread cleanly. * Ticket due dates fail fast on malformed input instead of silently parsing to an unintended date, so an invalid value is rejected rather than saved as the wrong day. * The **Static Webpage** icon inverts correctly in dark mode in the knowledge document tables, matching the other source icons. * Response-time analytics no longer count bot replies when setting a ticket's first responded-at timestamp, so first-response metrics reflect human agent activity. ## Form tools for the Copilot MCP server Ravenna's Copilot now exposes its form-building tools over MCP. Any connected AI client can create and update forms, add and edit fields, and inspect form collections without leaving the conversation. Teams configuring intake for IT requests, HR onboarding, or RevOps approval flows can describe the form they want, let the assistant assemble it, then iterate on field types and validation in place. [Learn more →](/documentation/automate/mcp/tools) **Other updates:** * [Change assignee from a Kanban ticket card](/documentation/tickets/organize/views) without opening the ticket, so triage and standups stay on the board * [Cleaner Slack form rendering](/integrations/slack/creating-tickets) keeps form titles, icons, and field layout consistent across light and dark Slack themes **Bug fixes:** * Ticket card tooltips in the Ravenna AI chat no longer crash the app on hover * The date-edit trigger is back in the ticket Dates section so due dates and other dates can be edited inline again * New-ticket drafts persist correctly when the create-ticket modal is closed and reopened, so in-progress requests are not lost ## Table widgets on analytics dashboards A Table widget listing open access requests alongside dashboard charts A new **Table** widget type joins metric, grouped, and trend visualizations on analytics dashboards. Pick the columns you want, sort and search inline, and surface the underlying ticket rows next to the charts that summarize them, useful for ops reviews, backlog standups, or any moment where the dashboard answer is "show me the list." [Learn more →](/documentation/measure/analytics) ## Drill into any chart value Click a bar, slice, or data point on any Tickets-powered chart to open a drill-down modal listing the individual tickets behind that value. The chart's filters, group, and date range carry over, and you can search and sort inside the modal. A one-click handoff opens the same result set in the full tickets list for bulk actions or export, so you can investigate spikes without losing your place on the dashboard. [Learn more →](/documentation/measure/analytics#drilling-into-chart-values) ## Filters on reminder policies Approval and assignment reminder policies now accept ticket condition filters, so a single workspace policy can target only the tickets that should be nudged. Scope reminders to a specific queue, priority, requester group, or any combination of ticket attributes. For example, escalate access-review approvals after one business day while leaving low-priority requests alone. [Learn more →](/documentation/tickets/reminders) ## Search across knowledge folders Knowledge now supports root-level search from the **Folders** tab. One query matches both folder names and document titles across every folder in the workspace, with each result tagged by type and parent folder. Jump straight to a specific runbook or policy without remembering which folder owns it. [Learn more →](/documentation/automate/knowledge/overview#searching-across-folders) ## Opt-in streaming for the Ravenna copilot The Ravenna copilot can now stream responses progressively as they are generated. Long answers, like multi-paragraph troubleshooting or summaries of a ticket thread, start appearing immediately instead of arriving as one block, making the copilot feel faster across IT, HR, and support work. **Other updates:** * [Approvers and Approved At columns are back in ticket exports](/documentation/tickets/organize/views#export-tickets) so audit-ready CSVs include who approved a ticket and when * [Business schedule archive guardrails](/documentation/platform/workspaces/settings) block archiving or deleting a schedule that still has SLAs attached, and show you exactly how many SLAs to move first * Microsoft Teams connections now reject linking the same Teams tenant to more than one Ravenna organization, so admins get a clear error instead of a half-connected workspace * [Foundry OAuth provider test connection](/documentation/automate/foundry/integrations#oauth-providers) now flags a reachable token endpoint that rejects `client_credentials` as a warning, so you can save providers that only verify through the authorization code flow * Group sync from HRIS and identity providers now processes large directories in batches, so workspaces with thousands of groups complete a sync without timing out **Bug fixes:** * Analytics donut charts hold a consistent gap between slices instead of widening as values shift * Jira's assignable-user picker paginates through every project member instead of stopping at the first page * The Portal workspace picker only lists workspaces that actually have the Portal turned on * Ticket detail polish: approval rounds, message cards, and the side scrollbar render cleanly on long tickets * Ticket due dates persist correctly across edits * Large group syncs from identity providers process in batches so workspaces with thousands of groups complete reliably without database timeouts ## Snippets for reusable replies Snippets Save frequently used responses as snippets at the workspace level and insert them into any ticket reply to keep tone, formatting, and policy language consistent. Snippets are available through the Ravenna API and as MCP tools, so agents and external tools can drop in approved wording without retyping. [Learn more →](/documentation/tickets/snippets) ## Approval and assignment reminders Two new reminder types keep work moving without manual nudging. [Approval reminders](/documentation/tickets/reminders#approval-reminders) re-ping approvers on a configurable cadence until an approval round completes, and [assignment reminders](/documentation/tickets/reminders#assignment-reminders) prompt assignees on tickets that have gone quiet. Both honor the workspace's default business schedule so reminders fire only during working hours, and a new **Reminder Expired** workflow trigger lets you escalate or reassign when a reminder cycle runs out. ## Conditions for reminder policies Approval and assignment [reminder policies](/documentation/tickets/reminders) now support **conditions**. Add one or more filter groups to a policy and reminders only fire for tickets that match. For example, only nudge approvers on `High` and `Urgent` priority tickets, or only chase assignees in a specific queue. Leave conditions empty to keep reminding on every ticket, as before. Conditions are re-evaluated every time a reminder is about to fire. A ticket that moves out of scope is silently skipped without burning a slot against your **Maximum reminders** cap, and resumes nudging if it moves back into scope. To keep things bounded, a reminder chain stops on its own after 30 days if a ticket never matches. [Learn more →](/documentation/tickets/reminders#conditions) ## Workspace Automation settings A new Automation section in workspace settings consolidates assignment reminders, agent escalation defaults, and related routing toggles in one place instead of spreading them across feature pages. Workspace admins can audit and tune automation behavior without hunting through individual workflows or queues. [Learn more →](/documentation/platform/workspaces/settings) **Other updates:** * [Workflow duplication and cross-workspace copy](/documentation/automate/workflows/triggers-actions) clone a workflow into the same workspace or a different one, with collection placement preserved * [Foundry Dry Run mode](/documentation/automate/foundry/using-actions) executes a Foundry action against the live API but rolls back side effects, so you can validate request shape and auth without changing data * [AI agent outcome on the tickets dashboard](/documentation/measure/analytics) breaks resolved tickets into deflected, agent-assisted, and human-handled so you can size automation impact at a glance * [Explain in Agents Chat Logs](/documentation/automate/agents/customize) surfaces the reasoning, rule match, and tool calls behind any agent response from the chat log timeline * [Agent version upgrades](/documentation/automate/agents/configure) move an agent from V2 to V3 in place, preserving rules, knowledge, and history * [Ticket Created notification group for requesters](/documentation/platform/notifications) controls whether requesters get a confirmation message when their ticket is created * [Inbound email block list and subdomain matching](/integrations/email/overview) reject mail from specific senders or whole domains before a ticket is created, with explicit subdomain semantics * [CSV export for the Applications list](/documentation/automate/access-provisioning/applications) exports the current filtered view for access reviews and audits * [Short ID and ID filters for ticket views](/documentation/tickets/organize/views) filter by the ticket ID or short ID shown in the UI, including ranges and "in" sets * [Create Application and Access Levels MCP tools](/documentation/automate/mcp/tools) plus approval template tools let AI assistants stand up new applications and approval flows end to end **Quality of life updates:** * Manager approver resolution clearly documents the lookup order across HRIS, identity providers, and manually set managers * Freshservice knowledge base sync respects the category you select instead of pulling every Solutions article * Slack emoji actions show a clear notice when a non-member triggers them on a private ticket * Confluence sync resolves `@mentions` to the underlying Ravenna user when an email match exists * Notion page fetches in the knowledge selector now stream asynchronously so large workspaces stop timing out * Reminders, SLAs, and other timer-based features all default to the workspace's business schedule so weekend hours are handled consistently ## Freshservice ticket replication Freshservice tickets syncing with Ravenna Connect Freshservice for full bidirectional ticket replication. Tickets, comments, custom fields, and status changes sync in real time over webhooks, author attribution is preserved across both systems, and private comments stay private. Freshservice Solutions articles can also sync as a knowledge source so your agent answers from your existing support content. [Learn more →](/integrations/freshservice/ticket-replication) ## GitHub repositories as a knowledge source Selecting GitHub repositories to sync as knowledge Connect GitHub repositories so your agent can answer from documentation you already maintain. Pick which repos to sync and Ravenna pulls in Markdown, text, and documentation files, preserves your folder structure, and stays current as you push changes. [Learn more →](/integrations/github/knowledge) ## Business schedules for SLAs Configuring a business schedule with working hours and holidays SLA targets can now follow your team's actual working hours. Define a business schedule with a timezone, weekly hours, and holidays, then attach it to any SLA policy. Targets pause outside business hours and resume when your team is back online. [Learn more →](/documentation/automate/slas) ## Redesigned cron trigger Scheduled workflow trigger using a cron expression The scheduled workflow trigger now uses standard cron expressions and any timezone, so recurring workflows no longer depend on UTC offsets or rigid dropdowns. Existing schedules migrate automatically. [Learn more →](/documentation/automate/workflows/triggers-actions) **Other updates:** * [MCP OAuth sign-in](/documentation/automate/mcp/overview) lets you log in once and reach every workspace from a single session, with no per-workspace API keys * [Settings home](/documentation/platform/workspaces/settings) is a searchable landing page that surfaces every organization, workspace, and personal setting as a card * [Sort tickets by custom fields](/documentation/tickets/organize/views) sorts a ticket table by date, number, text, or dropdown values * [Personal view overrides](/documentation/tickets/organize/views) let you adjust filters and display on a shared view without affecting teammates * [User groups for app owners and approvers](/documentation/automate/access-provisioning/applications) assign a team instead of a single person so coverage continues when individuals are out * [Copilot conditional fields and form deletion](/documentation/automate/copilot/configure-workspace) build show/hide dependencies, restrict picker options, or delete forms in natural language * [Agent form-link emails](/integrations/email/overview) send the requester a direct link to a prefilled Portal form during an email conversation * [Search Users action](/documentation/automate/workflows/triggers-actions) looks up users by criteria and feeds results into downstream steps * [Arrow key ticket navigation](/documentation/get-started/shortcuts) moves between tickets without returning to the list **Quality of life updates:** * Approval descriptions appear inline so you can review and act without opening a separate view * Guest user navigation hides Command K and search for external guests * Forwarded emails identify the original sender instead of the forwarding service * Column visibility and reorder changes on custom views save and reset reliably * Slack form modals no longer fail when an agent prefills a multi-select field ## Approval-gated agent tools Agent tool execution policies with approval gates Agent rules now support per-tool execution policies. Configure each tool to auto-execute, require user confirmation, or require approval from a designated approver before running. Approval-gated tools batch into a single approval round per agent plan, so approvers review one consolidated request instead of many. [Learn more →](/documentation/automate/agents/configure) ## Retry failed workflow runs Retry a workflow run directly from the run history. Rerun from the beginning, retry against the latest published version, or resume from the failed step while reusing successful upstream outputs. The new run links back to the original for full traceability. [Learn more →](/documentation/automate/workflows/monitor) **Other updates:** * [Agent ticket ownership](/documentation/tickets/roles) separates AI agent work from human assignees so internal routing skips notifications, CSAT, and OOO delegation * [Named-assignee escalation](/documentation/automate/agents/configure) specifies which user a ticket is assigned to when it escalates to a human * [Wait for Approval timeout branch](/documentation/automate/workflows/triggers-actions) adds an On Timeout path so stalled requests can be escalated or auto-closed * [Application approver field](/documentation/automate/access-provisioning/applications) designates a dedicated approver, separate from the application owner * [HiBob Get OOO Users](/integrations/hibob/overview) lists who is on vacation for a date range * [Compare previous period toggle](/documentation/measure/analytics) overlays the preceding period on trend cards * [/help Slack command](/integrations/slack/overview) adds a discoverable alias for /rav **Quality of life updates:** * Forms default to Draft on creation so you can configure before publishing * Task templates use inline editing instead of separate tabs * Externally-synced knowledge documents hide the Edit button with guidance to edit at the source **Bug fixes:** * Email rendering no longer freezes on large threads, and reply threading is fixed for forwarded chains * Form fields render correctly for non-workspace members * Multi-turn conversational form filling completes properly * Slack admin escalation works correctly for channel create and archive actions ## Trigger workflows from external systems Configuring an external webhook trigger for a workflow Trigger a workflow from any external system using a secure webhook URL. Each workflow gets a unique URL that third-party tools, automation platforms, or custom integrations can POST to, and the payload becomes available as workflow context. No API keys needed. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Smart approval routing Approval rounds now support skip conditions based on requester attributes, ticket properties, or integration data. For example, skip "Manager approval" when no manager is set. If every round is skipped, the ticket auto-approves with no manual intervention. [Learn more →](/documentation/tickets/approvals/rounds) ## Smarter agents Your agent can now read files shared in Slack. PDFs, images, and documents are processed automatically and used to answer questions, prefill form fields, and route tickets. The agent also knows where a user is writing from, so it won't tell someone to post in a channel they're already in. [Learn more →](/documentation/automate/agents/customize) ## Time-off management with HiBob The HiBob integration adds two workflow actions. Get Time-off Balance retrieves an employee's remaining PTO across all policy types, and Request Time Off submits requests on their behalf with an optional approver and description. [Learn more →](/integrations/hibob/overview) **Other updates:** * [Assignee Group filter for SLAs and views](/documentation/automate/slas) targets policies and views to tickets where the assignee belongs to a specific group * [Google Workspace security group creation](/integrations/google-workspace/workflows) adds label support to the Create Group action * [Auto-populate ticket defaults from view filters](/documentation/tickets/organize/views) pre-fills assignee, status, priority, and tags from your active view * [Dynamic Wait Until dates](/documentation/automate/workflows/triggers-actions) accept dynamic values from triggers or upstream steps * [Email delivery status badges](/integrations/email/overview) show whether outbound emails were delivered, in the ticket timeline * [Workflow failure notifications for completed-with-errors](/documentation/automate/workflows/monitor) fire on partial errors, not just fully failed runs **Quality of life updates:** * Redesigned badges and chips with consistent sizing and cleaner dark mode colors * Breadcrumbs truncate long page names instead of wrapping * Custom field columns order before the actions column in ticket tables * Workflow runs pagination is visible without scrolling * Agents clearly explain why a blocked action was denied **Bug fixes:** * Slack agent tools resolve channels and users correctly on Enterprise Grid * Approval wait triggers resolve correctly after a ticket moves between queues * Foundry actions with stored credentials execute correctly inside workflows * Custom SELECT fields render as proper dropdowns in workflow conditions ## Admin audit log The admin audit log filtered by actor and event type Track every administrative change across your organization with a searchable audit log. The audit log in organization settings records actions on agents, integrations, knowledge bases, and forms with full before and after context. Filter by event type, actor, resource, or date range, group events for pattern analysis, and export to CSV for compliance reporting. [Learn more →](/documentation/platform/organizations/audit-log) ## Approval rounds Build multi-stage approval workflows with configurable policies per round. Each round can require any one approver, all approvers, or a custom threshold before advancing. Sequential execution keeps review structured and auditable for access requests and sensitive operations. [Learn more →](/documentation/tickets/approvals/rounds) ## Intune device management actions Six new workflow actions and agent tools for Microsoft Intune: Autopilot Reset, Retire Device, Sync Device, Rotate BitLocker Key, Wipe Device, and Assign Script. Automate endpoint lifecycle management from workflows and agent conversations without leaving Ravenna. [Learn more →](/integrations/intune/workflows) **Other updates:** * [Conditional KB routing in agent rules](/documentation/automate/knowledge/overview) directs knowledge lookups to specific folders based on the topic of the conversation * [Task template folders](/documentation/tickets/tasks) group task templates by department, workflow type, or any structure you choose * [Google Workspace temporary password generation](/integrations/google-workspace/workflows) adds a temporary password option to the Reset MFA/Password action * [JumpCloud workflow actions](/integrations/jumpcloud/overview) add user lifecycle management and group operations, reaching parity with Okta * [Allowlist cap removed for Slack dropdowns](/documentation/tickets/forms/custom-fields) supports more than 100 options using searchable external selects * Draft and archived forms are no longer presented to AI agents **Quality of life updates:** * Icons on form tabs and ticket type selectors add visual indicators to navigation * The full Lucide icon library is available within the platform * Form tabs remember your last selection across sessions * Agent table layout fixes alignment and spacing issues **Bug fixes:** * Fixed form submission errors in Slack * Fixed conditional form fields clearing descendant values when a parent changes * Fixed knowledge base document deletion silently failing * Fixed icon picker dark mode gradient and broken icon names * Fixed rich text editor color in dark mode ## Workflow runs in analytics A custom dashboard tracking workflow run volume and success rates Custom dashboards now support a Workflow Runs data source. Track execution volume, success rates, and failure patterns grouped by workflow name, run status, collection, or related ticket dimensions like channel, assignee, and priority. [Learn more →](/documentation/measure/analytics) ## Share ticket workflow action Keep a ticket in its original workspace and channel while creating a shared reference in another workspace. Share actions let teams collaborate across workspace boundaries without moving tickets or losing context. [Learn more →](/documentation/automate/workflows/triggers-actions) ## AI reasoning in workflow runs The AI's explanation now appears alongside its decision when AI Decision Maker and Custom Prompt steps execute, visible in the workflow run step details. It's easier to understand why the model chose a path or made a decision. [Learn more →](/documentation/automate/workflows/monitor) **Other updates:** * [Type and Multi-application custom fields](/documentation/tickets/forms/custom-fields) add two new field types for forms * [JumpCloud application sync](/integrations/jumpcloud/overview) pulls applications with status, logo, and metadata for access management * [JumpCloud manager sync](/integrations/jumpcloud/overview) syncs manager relationships for approval chains and routing * [Intune device app lookup](/integrations/intune/agent-tools) retrieves installed applications on managed devices via agent rules and workflows * [Conditional visibility for all field types](/documentation/tickets/forms/overview) extends show/hide rules to layout and system fields * [Auto-submit forms by default](/documentation/automate/agents/customize) skips the form UI when an agent has prefilled all required fields * [Members filter bar and inline editing](/documentation/platform/users/members) add filtering and inline owner editing to member tabs * Ravenna is now listed on the [JAMF Marketplace](https://marketplace.jamf.com/details/ravenna) **Quality of life updates:** * Stale Slack forms rebuild instead of showing an error * Slack messages respect configured custom field ordering * Agents check the knowledge base before triage so existing docs can resolve requests * User lookup resolves guests by searching the full organization * Applications table supports sorting by status, owner, and source * Browser tabs show readable form names instead of raw IDs ## Forms 2.0 The Forms 2.0 builder with lifecycle stages and audience controls Forms now support a full lifecycle with draft, published, and archived stages. Draft forms stay hidden from requesters until you publish them, and archived forms no longer appear for selection without being deleted. Audience controls let you restrict which forms appear for different groups: everyone, workspace members only, or specific user groups. [Learn more →](/documentation/tickets/forms/overview) ## JumpCloud, OneLogin, and Microsoft Intune integrations [JumpCloud](/integrations/jumpcloud/overview) and [OneLogin](/integrations/onelogin/overview) are now generally available with user provisioning, directory sync, and access management workflows. [Microsoft Intune](/integrations/intune/overview) is a new MDM integration that shows device compliance data in tickets and supports automated device management through agent tools and workflows. **Other updates:** * [Ticket Type field](/documentation/tickets/organize/types) assigns one of five categories to tickets: Service, Incident, Problem, Change, or Access * [User groups in approval rounds](/documentation/tickets/approvals/rounds) can be selected as approvers * [Settings-driven form filling](/documentation/automate/agents/customize) uses deterministic agent settings to control conversational form behavior * [Okta auto-provisioning](/integrations/okta/overview) creates Organization Guest accounts for external Okta users during directory sync * [Jira private comment sync](/integrations/jira/ticket-replication) syncs Jira Service Desk internal comments to Ravenna private notes, and vice versa * [Skip-invite toggle and bulk resend](/documentation/platform/users/members) skip invitation emails when adding members and resend pending invitations in bulk **Quality of life updates:** * Inline text filters save when you click away from the input * Form fields render in the correct sequence across all form contexts * Custom field labels and descriptions increased to 2,000 characters * Custom fields are hidden by default in table views, and Reset Columns restores the default * Bulk unarchive restores child tickets throughout the hierarchy * Linear status mapping applies when creating issues, not just during status updates ## Secure API credentials with Vault Vault storing encrypted API credentials for workflows Workflows that call external APIs no longer need credentials hardcoded into individual steps. Vault provides encrypted, organization-level storage for API keys, tokens, and secrets. Admins create a credential once and any workflow references it at runtime through the HTTP Request action. Credentials are encrypted at rest and never displayed after creation. [Learn more →](/documentation/platform/organizations/vault) ## Smarter workflow auto-triggers Workflow auto-trigger detection now reads the intent behind an agent rule instead of scanning for keywords. If a rule's purpose is to run a workflow immediately, the agent skips the confirmation step, and it recognizes when a user has already confirmed in conversation. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Send and resolve in one click The ticket composer now includes a Send and resolve option that combines replying and closing into a single action. Choose it once and it becomes the default for later messages in that ticket, with keyboard shortcut support. [Learn more →](/documentation/tickets/organize/statuses) **Other updates:** * [Email footer customization](/integrations/email/overview) appends rich text like disclaimers and contact info to outbound emails from a channel * [MCP assigned tasks](/documentation/automate/mcp/tools) lists assigned task items for the current user * [Google Create Group Managers role](/integrations/google-workspace/workflows) assigns the Managers role when provisioning groups * [Duplicate agent rules](/documentation/automate/agents/configure) clone a rule to the same agent or a different one * [Ticket create API requesterEmail](/api/overview) sets the requester by email instead of user ID **Quality of life updates:** * A public thread reply warning appears when users reply in the public request thread of a private ticket * Jira setup now specifies that a standard user account is required, not a managed service account ## Connect AI assistants to Ravenna with MCP An AI assistant managing Ravenna tickets through MCP The Ravenna MCP server opens your workspace to AI assistants like Claude, Cursor, and VS Code through the Model Context Protocol. Manage tickets, look up users, configure access policies, and more from a single conversation instead of switching between tools. [Learn more →](/documentation/automate/mcp/overview) ## Agents pick the single best matching rule When multiple agent rules could apply, the agent now selects the single most specific match instead of trying to satisfy several at once. The result is more predictable, focused responses when rules overlap. [Learn more →](/documentation/automate/agents/configure) **Other updates:** * [Group Lookup agent tool](/documentation/automate/agents/configure) searches for user groups by name during conversational form filling * [User group workspace scoping](/documentation/platform/users/groups) enforces workspace-aware visibility for manually created groups in select fields * [Slack thread link as workflow variable](/documentation/automate/workflows/workflow-builder) passes a clickable Slack thread URL to webhooks and downstream steps * [Workflow triggers show a confirmation button](/documentation/automate/workflows/triggers-actions) by default when triggered without a form **Quality of life updates:** * Workflow step management supports deleting individual steps or entire branches, with keyboard shortcuts * Workflow badge navigation opens the specific run in a new tab from ticket events ## Push-based identity verification in workflows A workflow step sending an Okta Verify push notification A new Verify Identity with Push action sends an Okta Verify push notification and waits for the user's response. The action supports if/else branching so workflows follow different paths depending on whether the user approves or denies, for example requiring step-up verification before granting access to a sensitive resource. [Learn more →](/integrations/okta/workflows) ## Bulk actions with workflow loops Workflows now support a Loop action that iterates through a collection, running contained actions for each item. Process lists of users, tickets, or other data returned by actions like Search Tickets or List Groups, then notify, update, or chain multi-step operations across the whole set. [Learn more →](/documentation/automate/workflows/triggers-actions) **Other updates:** * [Parent ticket support in Update Ticket](/documentation/automate/workflows/triggers-actions) organizes tickets into parent-child hierarchies through workflows * [Google Workspace Create User fields](/integrations/google-workspace/workflows) add department, job title, manager, organizational unit, and recovery contact info * [Google Workspace Get Group](/integrations/google-workspace/workflows) returns an isSuccess boolean and includes group owner and manager IDs * [Google Workspace user sync](/integrations/google-workspace/setup) excludes suspended and archived users to match your active roster ## Relative date scheduling in workflows Scheduling a workflow action relative to a target date A new Wait Until action pauses execution until a specific date or a date relative to a target. Set an offset to trigger actions before or after key dates, for example a reminder five days before an onboarding start date or a follow-up a week after a renewal. [Learn more →](/documentation/automate/workflows/triggers-actions) ## Conditional form fields The form builder now supports conditional field visibility. Fields show or hide based on the value of another field, so requesters only see what is relevant. Nest dependent fields, collapse groups to keep complex forms manageable, and rely on visibility rules that carry through to the ticket detail view. [Learn more →](/documentation/tickets/forms/overview) **Other updates:** * [Knowledge gaps tab](/documentation/automate/knowledge/overview) surfaces topics where agents could not find an answer, with frequency and example conversations * [Ticket automation status metric](/documentation/measure/analytics) classifies resolved tickets as automated, automatable, or non-automatable * [Access levels tab](/documentation/automate/access-provisioning/applications) gives each application a dedicated tab with click-to-edit configuration **Quality of life updates:** * Auto-linked URLs in custom fields detect and linkify bare URLs in text fields * Slack thread reaction notices explain when emoji actions are used on thread replies ## AI-powered assistance for everything in Ravenna The Copilot chat panel open in the Admin Copilot is an AI assistant built into the Admin that knows your workspace. It understands your tickets, workflows, knowledge base, and team configuration, so you can describe what you need instead of clicking through menus. Whether you're triaging a backlog, setting up an automation, or finding a company policy, Copilot works alongside you in a single chat panel. [Learn more →](/documentation/automate/copilot/overview) ## Manage tickets, build automations, and configure your workspace by chat Search and filter tickets, draft responses in context, and summarize long threads without leaving the chat. Describe a workflow and Copilot builds it with triggers, conditions, approvals, and branching, or edits an existing one using its history. Set up agents, channels, and forms by describing what you need, and Copilot suggests configurations that fit how your team works. Learn more about [everyday tasks](/documentation/automate/copilot/everyday-tasks), [building automations](/documentation/automate/copilot/build-automations), and [configuring your workspace](/documentation/automate/copilot/configure-workspace). **Other updates:** * [Real-time Slack status sync](/documentation/platform/users/settings) detects status changes instantly via Slack events instead of polling every 30 minutes * [Custom display names for synced applications](/documentation/automate/access-provisioning/applications) rename applications from identity providers while keeping the original integration name * [Add Followers from user groups](/documentation/automate/workflows/triggers-actions) keep entire teams in the loop on relevant tickets at once ## Conversational form filling An agent collecting form fields through natural conversation Agents now collect form field values through natural conversation instead of presenting a static form. When a request triggers a form, the agent asks for each field one at a time in chat and submits the completed form automatically. A configurable field threshold (default: 5 fields) controls when agents use conversational mode versus the standard form UI, so simple requests flow naturally while complex forms still present the full UI. [Learn more →](/documentation/automate/agents/customize) ## Google Drive file transfers for offboarding A new Transfer User Files workflow action moves Drive files and Calendar data between users during offboarding, with configurable scope for private, shared, or all files. The action runs asynchronously and returns a transfer ID for tracking. [Learn more →](/integrations/google-workspace/workflows) **Other updates:** * [User Lookup agent tool](/documentation/automate/agents/configure) searches for users by name or email to populate user selection fields in forms * [Direct SSO login URL](/integrations/sso/setup) provides one-click access from an identity provider portal * [Microsoft Entra manager syncing](/integrations/microsoft-entra/overview) displays manager relationships on user profiles automatically * [Workflow email replies bypass queue settings](/integrations/email/overview) so recipients can always respond to automated outreach **Quality of life updates:** * API key Last Used tracking helps you identify stale keys * Workspace description guidance helps you write descriptions that improve routing * Emoji reactions are clarified to work on channel-level messages only ## Out of office and ticket delegation User settings for delegates and out of office status A dedicated user settings page lets team members configure their profile, assign delegates, and manage out of office status. Delegates receive ticket assignments and approvals on your behalf, and OOO status can sync automatically from Slack, so tickets always route to an available teammate. [Learn more →](/documentation/platform/users/settings) ## On-call schedule routing with Incident.io The Incident.io integration supports on-call schedule routing. It retrieves everyone currently on-call for a schedule and matches them to Ravenna users by email, so you can auto-assign tickets, notify on-call engineers, or build dynamic routing rules. [Learn more →](/integrations/incident-io/workflows) ## Smart ticket link names Ticket links auto-populate with page titles when you paste a URL. Ravenna fetches the title from the linked site's metadata, or uses the ticket title for internal links, so you don't type link names by hand. [Learn more →](/documentation/tickets/links) **Other updates:** * [Iru Assign Blueprint](/integrations/iru/workflows) workflow action for device configuration management * [Configurable sync intervals](/integrations/jira/setup) for Jira, Freshservice, and Linear integrations * [Google Workspace Get Group](/integrations/google-workspace/workflows) now returns group manager IDs **Quality of life updates:** * Workspace settings expanded with General details, bot users, and Slack appearance tabs * Slack Create Ticket Thread action now creates or replaces request threads * Category column and custom field grouping in table views ## Launch Week Winter 2026 Launch Week Winter 2026 product announcements Ravenna announced five major product launches during Launch Week Winter 2026. **Ravenna Agents** resolve employee requests autonomously using natural-language rules, knowledge base integration, and multi-turn conversations across Slack and email. [Learn more →](/documentation/automate/agents/overview) **Ticketing integrations** with [Jira Service Management](/integrations/jira/overview), [Freshservice](/integrations/freshservice/overview), and [Linear](/integrations/linear/overview) replicate tickets with sync of comments, status, assignments, and resolutions. **HRIS integrations** with [BambooHR](/integrations/bamboohr/overview), [HiBob](/integrations/hibob/overview), [Workday](/integrations/workday/overview), and [Rippling](/integrations/rippling/overview) bring employee context into Ravenna for personalized responses and routing. **MDM integrations** with [Jamf](/integrations/jamf/overview), [Fleet](/integrations/fleet/overview), and [Iru](/integrations/iru/overview) surface device diagnostics in tickets and enable automated device actions. **Workflow templates** provide pre-built automations for common operations like MFA resets, access requests, and channel provisioning. [Browse templates](/documentation/automate/workflows/workflow-builder). ## A more configurable workspace Workspace settings for ticket mirror field visibility Customize which fields appear on ticket mirrors across your workspace. Control visibility for status, priority, description, assignee, requester, approvers, source, and custom fields to keep Slack channels focused. [Learn more →](/documentation/platform/workspaces/settings) ## Wait for Message workflow action A new Wait for Message action pauses workflow execution until specific users send a message on a ticket. Set a timeout and optionally filter by message source to control when the workflow resumes, for example waiting on a customer response before continuing. [Learn more →](/documentation/automate/workflows/triggers-actions) **Other updates:** * [Automatic SSO redirect](/integrations/sso/overview) detects an organization's SSO from the email domain and redirects to authenticate * [Confluence archived pages](/integrations/confluence/knowledge) archive automatically in Ravenna to keep knowledge in sync * [Collapsible Kanban columns](/documentation/tickets/organize/views) focus the board on specific workflow stages, saved per view * Workflow actions that need a third-party integration show a Setup Required badge * Agent negative feedback creates support tickets by default ## Workflow versioning and in-flight controls Workflows gained versioning, pause and deactivate controls for in-flight runs, better timezone handling, and error alerts when a run fails. [Learn more →](/documentation/automate/workflows/overview) Workflow version controls in the workflow builder ## Generate knowledge base articles from tickets Generate a knowledge base article from any ticket directly in the Admin, turning resolved requests into reusable documentation. [Learn more →](/documentation/automate/knowledge/overview) Generating a knowledge base article from a ticket **Other updates:** * Email support is fully integrated in workflows, with sending, receiving, attachments, and automatic CC followers * Bulk drag-and-drop reorganization moves Analytics, Workflows, and Form resources into and out of folders ## Cloudflare Access integration A new integration with Cloudflare Access automates access requests for Cloudflare-protected applications end to end. Connecting Cloudflare Access to Ravenna's request and approval workflows removes manual steps, keeps access decisions auditable, and aligns with Zero Trust architectures. [Learn more →](/integrations/overview) Cloudflare Access integration in Ravenna ## Application provisioning methods Software access requests now support multiple provisioning methods, including group provisioning, application provisioning, and manual provisioning. Choose the method that fits how each application is managed, including tools that don't support SCIM. [Learn more →](/documentation/automate/access-provisioning/applications) Choosing an application provisioning method ## Workflow run insights New debug capabilities give clearer visibility into workflow runs and failures. When a run doesn't complete as expected, you can see detailed, actionable information about what went wrong and where, making troubleshooting faster. [Learn more →](/documentation/automate/workflows/monitor) Workflow run failure details # Software access requests for agents Source: https://docs.ravenna.ai/documentation/automate/access-provisioning/agent Enable AI agents to help users request, check, and refresh application access through natural conversation. When Software Access Requests is enabled on an agent, the agent can help users request new application access, check their current access status, and extend expiring access through natural conversation. ## What the agent can do Users describe what they need and the agent presents the right form with eligible applications and access levels prefilled. Users ask about their access and the agent shows what they currently have, including expiration dates. When access is expiring, the agent can offer to submit a renewal request. The agent knows which applications and access levels the user is eligible for based on their group membership and access policies. *** ## Enabling software access requests Navigate to **Agents** in the sidebar and select the agent you want to configure. Select the **Identity** tab on the agent configuration page. Scroll down to the **Advanced Settings** card. Toggle **Software Access Requests** on. The toggle only appears once access provisioning is configured for your organization. If you have not set up applications and access levels yet, start with the [setup guide](/guides/how-to/setting-up-access-provisioning). *** ## How it works When a user asks for access, the agent looks up: * Applications the user is eligible to request (based on access policies and group membership) * Available access levels for each application * The user's current active entitlements * Policy requirements like access duration and business justification The agent uses this context to guide the conversation: * If the user already has access, the agent informs them and asks if they want a different level or an extension * If only one access level exists, it is automatically selected * If business justification is required by the policy, the agent asks for it * If the policy lets the requester pick a duration, the agent presents the choices. On a fixed duration or no expiry, it does not ask. *** ## Writing agent rules for access requests Create rules to guide your agent's behavior for access request scenarios. When a user requests access to an application, ask which application they need and their business justification. Then use @List Applications to find the application. Present the appropriate access request form with details prefilled. When a user asks about their current access, use @List Applications to check their active entitlements. Tell them what access they have, when it expires (if applicable), and offer to help extend or request additional access. *** Learn more about [agent configuration](/documentation/automate/agents/configure) ## Activation The agent's access provisioning capabilities require the **Software Access Requests** toggle to be on (Identity tab > Advanced Settings). When both are active, the agent can look up eligible applications, access levels, current entitlements, and policy requirements for the requesting user. *** ## Agent behavior expectations * If the user already has the requested access level: inform them and ask if they want a different level or an extension * If only one access level exists for an application: auto-select it * If the user is ineligible (not in any eligible group for the policy): tell them the application is not available and suggest eligible alternatives * Always collect business justification before form submission if the policy requires it * Present duration options only when the policy's duration mode is `choice`. Do not ask for a duration on `fixed` or `none`. *** ## Constraints * The agent can only surface applications where the user is eligible based on access policy group rules. * If no default policy exists and the user is not in any eligible group, the application does not appear in results. * The agent respects the same approval routing as the form-based flow. Enabling the agent does not bypass approval templates. * Automated provisioning requires an active identity provider integration. The agent cannot provision access on its own. # Applications Source: https://docs.ravenna.ai/documentation/automate/access-provisioning/applications Build and manage your application catalog with access levels, provisioning methods, and identity provider integrations. Applications represent the external tools and services your organization uses. By defining applications in Ravenna with their corresponding access levels and provisioning methods, you create a structured catalog that supports automated access requests. ## Setting up applications Go to **Settings** > **Applications** in the left sidebar. Click **Add Application** to create a new application entry. Provide the application details: * **Name**: Display name for the application. * **Domain**: The application's web domain (optional). * **Details**: Rich text notes about the application (optional). These notes appear in hover cards when users view the application in ticket custom fields. * **Owner**: User or user group responsible for managing this application. Selecting a group lets the entire group act as the owner for routing and fallback purposes. * **Approver**: User or user group responsible for approving access requests. When a group is selected, every member is treated as an approver. If no approver is set, the application owner is used as a fallback. * **Post provisioning message**: Optional rich text message sent to the requester after access is granted. Use it to share login instructions, onboarding resources, or follow-up steps. * **Workspaces**: Select which workspaces can surface this application in request forms. Add access levels to define the permission tiers available for this application. See [Access levels](#access-levels) below. Click **Save** to create the application. *** ## Synced applications Applications can be automatically imported from your identity provider rather than created by hand. When you connect Okta or Microsoft Entra ID, Ravenna discovers the applications in your IdP and adds them to your catalog. Each synced application shows the integration name as its **Source**. Google Workspace does not import applications. Google publishes no API that lists the SAML and OIDC apps configured in a Workspace tenant, so Ravenna cannot read that catalog. Add your Google-federated applications manually, then use **Group** provisioning to grant access through a Google Group. Users and groups sync normally. **What syncing means in practice:** * The application name and image stay in sync with the IdP. You cannot edit them directly in Ravenna. * You cannot delete a synced application while the integration is active. * You can set a **Display Name** to override the IdP name shown to users. The original name is preserved for sync purposes and appears alongside the display name in the format `Display Name (Original Name)`. Use display names to make application names more recognizable to your users without affecting how the IdP integration works. Learn about [Okta integration](/integrations/okta/overview), [Google Workspace integration](/integrations/google-workspace/overview), and [Microsoft Entra ID integration](/integrations/microsoft-entra/overview) *** ## Provisioning methods The provisioning method on an application (or access level) controls how access is granted after a request is approved. Provision access by adding the user to a group in your identity provider. After approval, Ravenna adds the user to the mapped IdP group, which then grants access to the application through the IdP's own assignment rules. **Supported by:** Okta, Google Workspace, Microsoft Entra ID Use this when your IdP manages application access through group membership. Provision access by assigning the user directly to the application in the IdP. Rather than adding the user to a group, Ravenna adds them to the application itself using the identity provider's application assignment API. **Supported by:** Okta only Use this when direct application assignment is preferred over group-based access in your IdP. No automated provisioning. After approval, an authorized provisioner must manually grant access in the target system and then mark the entitlement as provisioned in Ravenna. Authorized provisioners for a manual access level include the application owner, the ticket assignee, and workspace admins. **No IdP required.** Use this for applications that are not connected to an identity provider, or where automated provisioning is not possible. Provisioning is handled by a workflow action. After approval, a configured workflow runs and performs whatever provisioning steps you define, including calling external APIs, sending notifications, or chaining multiple actions. **No IdP required.** Use this for custom provisioning logic that goes beyond standard IdP operations. *** ## Access levels Access levels define the permission tiers available within an application. Each level represents a specific set of capabilities a user can be granted, and each has its own provisioning method, approvers, and optional IdP group mapping. ### Creating access levels Go to **Settings** > **Applications**, select an application, and open the **Access Levels** tab. Click **Add Access Level**. Provide: * **Name**: A clear name that communicates what the level grants, such as "Admin", "Editor", or "Viewer". * **Description**: A plain-language explanation of what permissions this level includes. * **Access Policy**: The policy governing this level. It determines who is eligible to request it and which approval template routes the request. * **Provisioning Method**: How access is granted once approved. See [Provisioning methods](#provisioning-methods) above. For Group provisioning, select the corresponding IdP group from the dropdown. Ravenna uses this mapping to add the user to the group after approval. Learn about [access policies](/documentation/automate/access-provisioning/policies) ### Example access level structure Define levels that reflect how your organization actually uses each application. Here is an example for Slack: | Access level | Description | | --------------- | ---------------------------------------------------------- | | Admin | Full admin capabilities including workspace settings | | User Admin | User administration without workspace configuration access | | Channel Manager | Create, edit, delete, and manage channels | | Member | Standard user without admin capabilities | Structure access levels based on real usage patterns in your organization, not theoretical permission models. ### Archiving access levels Archive access levels you no longer want users to request. Archived levels are hidden from request forms but retain their approval history and IdP mappings for audit purposes. Go to **Settings** > **Applications**, select the application, and open the **Access Levels** tab. Select the access level row and use the **Archive** action. To archive several at once, select multiple rows and use the **Archive** bulk action. To restore an archived access level, filter the table by **Archived** status, select the level, and use the **Unarchive** action. Archiving an access level does not revoke access already granted through it. Existing tickets, approval history, and IdP mappings are preserved. To revoke previously granted access, handle the deprovisioning separately in your identity provider. *** ## Assignment strategies Assignment strategies control how approvers are assigned to access request tickets for a given access level. Assignment strategies are the older approach to approver routing. When your access levels use access policies, approval routing comes from the policy's approval template instead, and the access level form shows an **Access Policy** selector in place of the approver and assignment strategy fields. Automatically approves the request without human intervention. The system bot is assigned as the approver and the request is approved immediately. Use this for low-risk applications or access levels where automatic approval is acceptable, such as dev environments or self-service tools. Assigns all specified approvers to the ticket. Any one of them can approve the request. Use this when multiple people are qualified to approve and you want the fastest possible response from the available pool. Distributes approval requests evenly across the approver pool. Only one approver is assigned per request, rotating through the list to balance workload. Use this when you want fair distribution of approval responsibilities across a team. Configure different assignment strategies for different access levels within the same application. For example, Member access might use "Auto" for immediate approval while Admin access uses "Round Robin" to distribute the review work. *** ## Identity provider integration Map access levels to groups in your identity provider for automated provisioning. After an access request is approved, Ravenna can automatically add the user to the mapped group or application. Not all providers support the same provisioning methods: | Capability | Okta | Google Workspace | Microsoft Entra ID | | --------------------------------------------- | ------------------------------------ | ----------------------- | ----------------------- | | Application sync/import | Yes | No | Yes (enterprise apps) | | Group sync | Yes | Yes | Yes | | Group provisioning (add user to group) | Yes | Yes | Yes | | Application provisioning (assign user to app) | Yes | No | No | | Supported provisioning methods | Group, Application, Workflow, Manual | Group, Workflow, Manual | Group, Workflow, Manual | ### Okta Connect your Okta integration and map access levels to Okta groups or applications. Okta is the only provider that supports both group-based and direct application assignment provisioning. Go to **Settings** > **Integrations** and configure your Okta connection. When creating an access level, select the corresponding Okta group from the dropdown. Choose how the access level provisions once a request is approved: * **Group**: Ravenna adds the user to the mapped Okta group, which then grants application access through Okta's assignment rules. * **Application**: Ravenna assigns the user directly to the Okta application without group membership. Provisioning runs automatically after approval. No workflow is required. Learn more about the [Okta integration](/integrations/okta/overview) ### Google Workspace Connect your Google Workspace integration and map access levels to Google Groups. Google Workspace supports group-based provisioning only. Direct application assignment is not available through this integration. Applications do not import from Google Workspace, so create them manually first. Google Groups do sync, and those are what the access level maps to. Go to **Settings** > **Integrations** and configure your Google Workspace connection. Users and groups begin syncing. Go to **Settings** > **Applications** and click **Add Application**. Name it after the app your Google Group grants access to, such as Slack or Zoom. When creating an access level, select the corresponding Google Group from the dropdown. Every synced Google Group is available, since Ravenna cannot tell which groups Google associates with which app. Choose **Group**. After approval, Ravenna adds the user to the mapped Google Group, which grants access to connected Workspace apps and shared resources. No workflow is required. Learn more about the [Google Workspace integration](/integrations/google-workspace/overview) ### Microsoft Entra ID Connect your Microsoft Entra ID integration and map access levels to Entra groups. Entra supports group-based provisioning only. Direct application assignment is not available through this integration. Go to **Settings** > **Integrations** and configure your Microsoft Entra ID connection. When creating an access level, select the corresponding Entra group from the dropdown. Choose **Group**. After approval, Ravenna adds the user to the mapped Entra group. No workflow is required. *** ## Archiving applications Archive applications you no longer want users to request access to. Archived applications are hidden from request forms by default, but their access levels and approval history remain intact for audit purposes. Go to **Settings** > **Applications** and select the application you want to archive. Use the **Archive** action in the application's details. A confirmation appears before the application is archived. To archive multiple applications at once, select them from the applications table and use the **Archive** bulk action. To restore an archived application, filter the table by **Archived** status, select the application, and use the **Unarchive** action. While an application is archived, Ravenna blocks changes to its access levels and rejects new access requests tied to it. Unarchive the application before resuming access request activity. Archiving does not revoke any access already provisioned through the application. To revoke previously granted access, handle the deprovisioning separately in your identity provider. *** ## Deleting applications Delete an application to permanently remove it from your catalog. Deletion is permanent and cannot be undone. If you need to preserve approval history, ticket references, or audit trails, [archive the application](#archiving-applications) instead. Go to **Settings** > **Applications** and select the application you want to delete. Use the **Delete** action in the application's details. A confirmation dialog appears before the application is permanently removed. Deleting an application does not revoke any access already provisioned through it. Handle any deprovisioning separately in your identity provider. *** ## Exporting to CSV Export your application catalog to CSV for audits, reporting, or offline review. The export reflects any search, sort, or filter you have applied in the applications table. Go to **Settings** > **Applications**. Apply any filters you want included in the export. Only applications currently visible in the table are exported. Click **Export** in the toolbar. The file downloads as `applications-export-.csv`. Exports are capped at 10,000 applications per file. Use filters to narrow the list if your catalog exceeds that limit. ## Mental model The application is the core primitive of the access catalog. It answers the question: what can users request access to, and at what permission level? Key relationships: * An organization has many applications. * An application has many access levels. * Each access level has a provisioning method and can optionally map to an IdP group. * Each access level has an assignment strategy that controls how approvers are assigned. * Applications are organization-scoped but can be made visible in specific workspaces. **Synced vs manual:** Applications with `integrationApplicationId != null` are synced from an identity provider (Okta or Microsoft Entra ID). `isSynced` is the relevant check for enforcing edit restrictions: synced applications cannot be deleted, and their name and image are controlled by the IdP. All other fields (display name, owner, approver, workspaces, post provisioning message) can be set regardless of sync status. **Google Workspace never produces synced applications.** Google exposes no API for the tenant's SAML and OIDC app catalog, so Google-federated applications are always manual entries. Group provisioning still works: it resolves the access level's mapped group to a Google Group and adds the user there, without consulting the application record. **Access levels** are scoped to a single application. There is no shared or global access level concept across applications. *** ## Provisioning method selection | Method | When to use | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | **Group** | IdP manages application access through group membership. After approval, add the user to the mapped IdP group. | | **Application** | Direct application assignment is preferred over group membership in the IdP. After approval, add the user to the application directly. | | **Manual** | No IdP connection or automated provisioning path exists. A human must provision access and mark the entitlement complete. | | **Workflow** | Custom provisioning logic is required, such as calling external APIs or chaining multiple steps beyond what standard IdP actions support. | If no IdP integration is active, use **Manual** or **Workflow**. Group and Application methods require a connected integration; provisioning actions will fail if the integration is disconnected even if the mapping is configured. *** ## Assignment strategy selection Assignment strategies are configured per access level, not per application. Different levels within the same application can use different strategies. | Strategy | Approvers assigned | Approval required from | Best for | | --------------- | ------------------------ | -------------------------- | ---------------------------------------------------------- | | **Auto** | System bot | None, approved immediately | Low-risk apps, dev/test environments, self-service tools | | **All** | All configured approvers | Any one approver | Multiple qualified approvers, fastest response time needed | | **Round Robin** | One approver (rotated) | The assigned approver | Balancing workload across a team, avoiding bottlenecks | Common pattern: use Auto for basic access levels (such as Member) and All or Round Robin for elevated access levels (such as Admin). *** ## Constraints and gotchas * Applications are organization-scoped. All workspaces share the same catalog, but workspace visibility is configurable per application. * Synced applications (`integrationApplicationId != null`) cannot be deleted and do not allow name or image edits. Custom display names are cosmetic only and do not affect integration behavior. * Archived applications reject new access requests and modifications to their access levels with an `APPLICATION_NOT_ACTIVE` error. Unarchive before resuming activity. * Archiving and deletion do not revoke previously provisioned access. Revocation must be handled in the IdP. * Access level IdP group mappings require an active integration. If the integration is disconnected, mappings persist but provisioning actions will fail. * Owner and approver fields each accept either a user or a user group, but not both simultaneously. Selecting one clears the other. * The post provisioning message is sent only after successful provisioning (full or partial). It is not sent on rejection or failed provisioning. * Exports are capped at 10,000 applications per file. # Entitlements Source: https://docs.ravenna.ai/documentation/automate/access-provisioning/entitlements Track and manage active access grants with entitlement lifecycle states, extensions, and revocation. An entitlement is a record that tracks the full lifecycle of an access grant for a user to an application or user group. Ravenna creates an entitlement when an access request is approved, then tracks it through provisioning, active use, expiration, revocation, or failure. Entitlements give you a complete picture of access state, not just what is currently active, but also what failed, was revoked, or expired. *** ## Entitlement lifecycle Each entitlement has a status that reflects where it is in the provisioning lifecycle. | Status | Description | | ----------------------------------- | ------------------------------------------------------------------------------------- | | Pending | The request is approved but provisioning has not started yet. | | Processing | The provisioning or deprovisioning action is in progress. | | Active | The user was successfully granted access. | | Deprovisioning | Access removal is in progress. | | Inactive | The user's access was successfully removed. | | Failed Provisioning | Granting access failed (for example, an IdP API error). | | Failed Revocation | Removing access failed. | | Skipped Provisioning | Provisioning was skipped (for example, the user already had access). | | Skipped Revocation | Revocation was skipped (for example, another active grant still requires the access). | *** ## Viewing entitlements Navigate to **Settings** > **Applications** > **Entitlements** tab to see all active and historical entitlements across your applications. Use the filters to narrow results by application, access level, status, user, or workspace. Each row shows the user, application, access level, status, created date, time left, and expiration. The **Time Left** column shows a live countdown for active time-bound entitlements, formatted as `2d 5h left`, `3h 20m left`, `45m left`, or `30s left` as the deadline approaches. Active entitlements with no expiration show `Never expires`. Entitlements that are not active (pending, deprovisioning, inactive, or failed) show `—`. *** ## Extending entitlements When access has a duration set by the access policy, you can extend it before or after expiration. Extension creates a new entitlement record linked to the original for lineage tracking. The extended entitlement inherits the same application and access level. The duration set by the policy starts when the entitlement is provisioned, not when the request is submitted or approved. If a policy grants 7 days of access and approval takes a day, the user still gets a full 7 days from the moment access is granted. *** ## Revoking entitlements Revoke access by selecting an active entitlement and choosing **Revoke**. You can add an optional revoke note for the audit trail. * **Synced applications:** triggers deprovisioning via the IdP integration, removing the user from the group or application. * **Manual applications:** marks the entitlement as deprovisioned. A human must remove the actual access in the target system. Revoking an entitlement for a synced application immediately removes the user's access in the identity provider. *** ## Manual provisioning For applications with a manual provisioning method, entitlements require a human to grant access. Authorized provisioners (application owner, ticket assignee, workspace admins, and org admins) can mark entitlements as provisioned. Manual provisioning prompts appear in two places: * **On the access request ticket**, where any authorized provisioner can mark the entitlement as provisioned. * **In Slack**, as a direct message to the ticket assignee. When a manual entitlement moves to Processing, Ravenna DMs the assignee an "Access ready to provision" message with a **Provision access** button. Clicking it marks the entitlement provisioned without leaving Slack, and the message updates to confirm. After granting access in the external system, the provisioner marks the entitlement complete in Ravenna through either path. The Slack DM goes to the ticket assignee. If the ticket is unassigned, the prompt only appears on the ticket itself, so make sure manual access requests get routed to an owner. *** ## Ticket closure When every access request on a ticket reaches a provisioned state, Ravenna moves the ticket to **Done** automatically. This applies whether provisioning happened through an identity provider or was confirmed manually, and it also applies when only some of the requested access could be granted. You do not need a workflow to close access request tickets. *** ## Workflow triggers The **Entitlement Status Changed** trigger fires when an entitlement changes status. Configure it to trigger on one or more statuses to notify requesters, alert IT on failures, or fan out across multiple outcomes. Learn about [workflow triggers](/documentation/automate/workflows/triggers-actions) ## Data model An `AccessEntitlement` record includes: * `id`, `userId`, `status`, `createdAt` * `accessRequestId`: the originating request * `userGroupId`, `applicationId`: the provisioned resource * `expiresAt`: set when the access policy defines a duration. Ravenna calculates it from the moment the entitlement is provisioned, not from when the request was submitted or approved. A 2-day grant that takes a day to approve still lasts 2 days once access is granted. * `revokedAt`, `revokedByUserId`, `revokeNote`: populated on revocation * `provisionedAt`: timestamp when provisioning completed * `parentEntitlementId`: links an extension to its origin entitlement * `lineage` (computed): array of related entitlements for extension chains, derived from `parentEntitlementId` relationships Status transitions follow: Pending → Processing → Active (or Failed Provisioning). On revocation: Active → Deprovisioning → Inactive (or Failed Revocation). *** ## Key operations * **List**: filterable by application, user, status, and workspace * **Extend**: creates a child entitlement with `parentEntitlementId` set to the original. Does not modify the original record. * **Revoke**: sets `revokedAt`, `revokedByUserId`, and triggers deprovisioning for synced apps. Failure results in `Failed Revocation` status. * **Manual provision**: marks a pending manual entitlement as provisioned after a human grants access in the target system. Reachable from the ticket or from the Slack DM sent to the ticket assignee when the entitlement enters `processing`. *** ## Constraints * Entitlement records are immutable; status changes accumulate as audit history rather than overwriting. * Extension creates a new record and does not modify the original. * Revocation of a synced app calls the IdP integration. If the call fails, the entitlement status is set to `Failed Revocation`. * `Skipped Revocation` occurs when another active entitlement grants the same access, preventing unnecessary removal. * When an access request reaches `provisioned` or `partially_provisioned`, the originating ticket is set to the workspace's Done status by the system user. No workflow is involved. * The Slack manual provisioning prompt requires a published ticket with an assignee who has Slack connected. # Access provisioning Source: https://docs.ravenna.ai/documentation/automate/access-provisioning/overview Manage application access requests with policies, approval templates, and automated provisioning through identity providers. Access provisioning handles the full lifecycle of application access in your organization: users request access, policies determine eligibility and route approvals, and identity provider integrations grant access automatically once approved. Every request is tracked as an entitlement with clear status, expiration, and audit trail. *** ## What you can do Sync your application catalog from Okta or Entra ID, or add applications by hand. Define access levels with provisioning methods that map to IdP groups for automated granting. Control who can request access, link approval templates, set duration options, and require business justification. Policies sit between users and access levels. Every approved request becomes an entitlement. Monitor active grants, handle extensions and revocations, and respond to provisioning failures. Let your AI agent help users discover eligible applications, submit requests, and renew expiring access through conversation in Slack. *** ## How it works A user requests access to an application, either by submitting a form or asking the AI agent. Ravenna evaluates the access policy to confirm the user is eligible, then applies the linked approval template to route the request to the right approvers. Once approved, access is provisioned through your identity provider automatically. ```mermaid theme={"system"} graph TD Q1{User requests access} Q1 --> Q2(Policy checks eligibility) Q2 --> Q3(Approval template
routes request) Q3 --> Q4{Approved?} Q4 -->|Yes| Provisioned(Access provisioned
via IdP) Q4 -->|No| Declined(Request declined) Provisioned --> Tracked(Entitlement created
and tracked) classDef question fill:#E2EAEF,stroke:#165d6e,stroke-width:1px,color:#0f172a classDef full fill:#165d6e,stroke:#165d6e,color:#ffffff classDef partial fill:#269cbd,stroke:#269cbd,color:#ffffff classDef blocked fill:#F1F5F9,stroke:#94a3b8,color:#475569 class Q1,Q4 question class Q2,Q3 full class Provisioned,Tracked partial class Declined blocked ``` For applications without an identity provider connection, provisioning is manual: an authorized person grants access in the target system and confirms it in Ravenna. *** ## Key concepts ### Applications Applications are the tools and services your organization manages access to. They can be **synced** from Okta or Microsoft Entra ID, or created **manually** for tools outside your IdP. Google Workspace syncs users and groups but not applications, so Google-federated apps are always manual entries. Each application has one or more **access levels** representing permission tiers, like Viewer, Editor, or Admin. Each access level specifies a provisioning method: | Method | How access is granted | Supported providers | | --------------- | ---------------------------------------------------------------------------------- | ------------------------------------------ | | **Group** | User is added to a mapped IdP group | Okta, Google Workspace, Microsoft Entra ID | | **Application** | User is assigned directly to the application in the IdP | Okta only | | **Manual** | A human grants access externally, then confirms in Ravenna | All (no IdP required) | | **Workflow** | Ravenna hands the approved request off to a workflow for custom provisioning logic | All (no IdP required) | Group and Application give you end-to-end automation with no workflow to build. Reach for Workflow only when provisioning needs custom logic the other methods cannot express. Learn more about [applications and access levels](/documentation/automate/access-provisioning/applications) ### Access policies Access policies govern who can request each access level and under what conditions. A policy defines: * **Eligibility** based on user group membership * **Approval template** for routing requests to the right approvers * **Duration options** for how long access should last * **Business justification** requirements When no policy is attached to an access level, requests are auto-approved. Attach a policy to add governance without changing the provisioning path. Learn more about [access policies](/documentation/automate/access-provisioning/policies) ### Entitlements An entitlement is a concrete access grant: a record that a specific user has been provisioned a specific access level on a specific application. Entitlements track status (provisioned, deprovisioned, failed), expiration dates, and the full history of how access was granted. Learn more about [entitlements](/documentation/automate/access-provisioning/entitlements) *** ## Synced vs manual applications **Synced applications** import from your identity provider. Their access levels map to IdP groups, so after approval Ravenna adds the user to the correct group and access flows through your existing assignment rules. Changes in the IdP sync back to Ravenna automatically. **Manual applications** are for tools not managed by an IdP. After approval, an authorized provisioner (the application owner, ticket assignee, or a workspace admin) grants access in the target system and confirms it in Ravenna. This is particularly valuable for bringing untracked tools under governance: teams often adopt SaaS products outside of IT's visibility, and manual applications give you a formal request flow and audit trail for these tools without requiring an IdP connection. **What is Shadow IT?** Shadow IT refers to tools and services adopted by teams without IT's knowledge or approval. Think department-purchased design tools, free-tier analytics platforms, or AI products signed up with a work email. These create security blind spots: access is granted informally, there is no offboarding process, and sensitive data can end up in systems nobody is tracking. Adding these as manual applications in Ravenna brings them under governance immediately, giving you request workflows, approval routing, and a clear record of who has access. Most organizations use a mix of both synced and manual applications. Start with synced applications for automated provisioning, then add manual entries for anything outside your IdP. *** ## Where Ravenna fits in your identity stack Most organizations already use an identity provider like Okta, Google Workspace, or Microsoft Entra ID to manage authentication and baseline access. Ravenna is not a replacement for your IdP. Instead, it adds the governance, approval, and request layer that identity providers do not provide natively. Your identity provider handles **birthright access**: the baseline permissions every employee gets automatically based on their role, department, or location. These are managed through IdP group rules that apply access as employee attributes change. Ravenna handles **just-in-time access**: the ad hoc or incremental requests that fall outside standard birthright grants. These are project-based needs, temporary responsibilities, or exceptions that require human decision-making, approval workflows, and audit trails. | Responsibility | Identity provider | Ravenna | | ------------------------------------ | ----------------- | -------------------------------------- | | Authentication and SSO | Yes | No | | Birthright access via group rules | Yes | No | | Access request intake and routing | No | Yes | | Multi-step approval workflows | No | Yes | | Time-bound access with expiration | Limited | Yes | | Conversational requests via AI agent | No | Yes | | Audit trail per request | Limited | Yes | | Provisioning into IdP groups | N/A | Yes (Okta, Google Workspace, Entra ID) | | Direct application assignment | N/A | Yes (Okta only) | | Provisioning for non-IdP tools | N/A | Yes (manual tracking) | For the **joiner** phase of the employee lifecycle, Ravenna complements your IdP by triggering onboarding workflows when a new employee is detected. These workflows can send forms to hiring managers, provision access to applications not covered by SSO, add users to Slack channels, and create tickets for manual provisioning steps. For **movers and leavers**, Ravenna's entitlement tracking gives you a clear record of who has access to what. Time-bound entitlements expire automatically, and revocation of synced-app access triggers deprovisioning in the IdP immediately. *** ## Enabling for agents Toggle **Software Access Requests** on in your agent's Identity tab under Advanced Settings to let it assist with access provisioning. The agent can then show users which applications they are eligible for, surface current access and expiration dates, prefill request forms, and offer to submit renewal requests for expiring grants. The agent respects the same eligibility rules and policies as the form-based flow. Learn more about [software access requests for agents](/documentation/automate/access-provisioning/agent) *** ## Getting started Sync your catalog from your identity provider, or add applications manually for tools outside your IdP. Define who approves access and in what order at **Settings** > **Approval Templates**. Policies reference these, so build them first. Set eligibility, allowed durations, and justification requirements, then attach the approval template that should route requests. Set up permission tiers for each application, attach an access policy to each, and choose a provisioning method. Create one form with application and access level select fields. Eligibility filtering tailors it to each requester automatically. Turn on Software Access Requests in your agent's Identity tab under Advanced Settings so users can request access through Slack. Follow the full [setting up access provisioning](/guides/how-to/setting-up-access-provisioning) guide for step-by-step instructions
## Mental model Access provisioning is built from four resources that chain together: | Resource | Role | Key relationship | | ----------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | **Application** | The tool or service (e.g., GitHub, Salesforce). | Has many access levels. Can be synced from an IdP or created manually. | | **Access level** | A permission tier within an application (e.g., Admin, Viewer). | Belongs to one application. Has a provisioning method and optionally links to an access policy. | | **Access policy** | Governance rules for requesting an access level. | Links to an approval template. Controls eligibility, duration, and justification. | | **Entitlement** | A concrete access grant for a user. | Created when an approved request is provisioned. Tracks status, expiration, and lineage. | The request flow: user submits request for an access level -> policy evaluated (eligibility) -> approval template materialized on ticket -> provisioning executed -> entitlement created. *** ## Agent activation The agent's access provisioning capabilities require the **Software Access Requests** toggle to be on (Identity tab > Advanced Settings). When active, the agent can look up eligible applications filtered by the user's group membership, access levels with their policy requirements (approval, duration options, business justification), and the user's current active entitlements. *** ## Constraints * Automated provisioning requires an active integration with Okta, Google Workspace, or Microsoft Entra ID. * Access policies are organization-scoped. A single policy can be shared across access levels in different applications. * Entitlements are immutable records. Extensions create new linked entitlements rather than modifying the original. * Revocation of synced-app entitlements triggers deprovisioning in the IdP immediately. * If the agent cannot resolve eligibility (user not in any eligible group and no default policy exists), the application does not appear in results. # Access policies Source: https://docs.ravenna.ai/documentation/automate/access-provisioning/policies Define who can request access, approval requirements, and how long access lasts with access policies. Access policies define the rules governing who can request access and under what conditions. Each policy controls eligibility, attaches an approval template that routes requests to the right approvers, and sets constraints like how long access lasts and whether a business justification is required. Policies are the middle layer of the cascade: an approval template attaches to a policy, and a policy attaches to one or more access levels. Create the approval template first, then the policy, then attach the policy when you configure an access level. *** ## What policies provide Define which user groups can (or cannot) request access under this policy. Attach an approval template that defines who approves and in what order. Let requesters pick a duration, enforce a fixed one, or grant permanent access. Require requesters to explain why they need access. *** ## Creating a policy * **Name**: Descriptive name (e.g., "Standard access", "Privileged access review") * **Description**: When this policy should be used * **Icon and color**: Visual identifier for the policy * **Owner**: User responsible for managing this policy * **Eligible Groups**: User groups allowed to request access under this policy. Leave empty to allow all users. * **Ineligible Groups**: User groups excluded from requesting access, even if they also belong to an eligible group. Select an existing approval template, or leave empty for auto-approval. The template defines approval rounds, each round's policy (any, all, or threshold), and its approvers. Create the template at **Settings** > **Approval Templates** if you have not already. Choose an **Access Duration** mode, which controls how long access granted under this policy lasts and whether requesters see a duration field at all. See [access duration modes](#access-duration-modes) below. Toggle **Business Justification** on to require requesters to explain their need. *** ## Access duration modes The **Access Duration** setting on a policy decides who controls the length of the grant. It also decides whether the request form shows a duration field, so you set expiry once on the policy rather than per form. | Mode | What happens | Also configure | | ------------------------------ | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | | **Requester picks a duration** | The requester chooses from a list of allowed durations on the request form. | **Duration Options**: the durations to offer, such as `10m`, `1h`, `1d`. At least one is required. | | **Fixed duration** | Access always lasts a set amount of time. No duration field appears on the form. | **Duration**: the enforced length, such as `8h`. Required. | | **No expiry** | Access is permanent. No duration field appears on the form. | Nothing. | Duration values use short-form notation: `m` for minutes, `h` for hours, `d` for days. Combinations work too, such as `1d12h`. The duration measures from when the entitlement is provisioned, not from when the request is submitted or approved. A `1d` grant that takes four hours to approve still lasts a full day once access is granted. ### How the form adapts The **Duration** and **Business Justification** fields on your access request form are policy-driven. They appear only for access levels whose policy calls for them, and when they appear they are required. * A requester picking an access level whose policy uses **Fixed duration** or **No expiry** never sees the Duration field. * A requester picking an access level whose policy leaves **Business Justification** off never sees that field. * When a field does render, the requester has to fill it in, so you do not need to mark it required on the form yourself. This is what lets one form serve your whole catalog. Two people opening the same form, or the same person selecting two different access levels, see different fields. When a policy uses **Requester picks a duration** and has a default duration set, the form preselects it as long as it is one of the offered options. *** ## Linking policies to access levels Policies are assigned to individual access levels, not to entire applications. A single policy can be shared across multiple access levels. When a user requests an access level, the linked policy determines eligibility and approval requirements. If no policy is linked to an access level, the request is auto-approved. *** ## How policies connect to approval templates An access policy references an approval template. When a request is submitted, Ravenna applies the template to the ticket automatically, materializing its rounds as concrete approval steps. Dynamic approvers in the template (the requester's manager, application owner, and so on) are resolved at apply time. You do not need a workflow for this routing. Learn about [approval templates](/documentation/tickets/approvals/templates) *** ## Managing policies **Editing** a policy only affects future requests. Existing in-flight requests retain the policy rules that were in place when they were submitted. **Archiving** hides the policy from new assignments while preserving history and existing entitlements that reference it. **Deleting** permanently removes the policy. Access levels that referenced it fall back to auto-approval. ## Data model `AccessPolicy` fields: | Field | Type | Description | | ------------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | string | Display name | | `description` | string | When this policy should be used | | `icon` | string | Lucide icon name | | `color` | string | Hex color for visual identification | | `isDefault` | boolean | Marks the organization's default policy | | `requiresBusinessJustification` | boolean | Whether requesters must provide a reason | | `durationMode` | `choice` \| `fixed` \| `none` | Who controls the grant length. `choice` means the requester picks from `durationOptions`, `fixed` means `defaultDuration` is enforced, `none` means permanent access. | | `durationOptions` | string\[] | Durations offered when `durationMode` is `choice`. At least one is required in that mode. | | `defaultDuration` | string \| null | Required when `durationMode` is `fixed`. Also used to preselect an option in `choice` mode when it appears in `durationOptions`. | | `ownerId` | string | User responsible for managing the policy | | `approvalTemplateId` | string \| null | When set, approval is required; when null, auto-approval | Relationships: * `eligibleGroups` (`UserGroup[]`): groups allowed to request * `ineligibleGroups` (`UserGroup[]`): groups explicitly excluded * `accessLevels` (`AccessLevel[]`): levels this policy governs *** ## Policy evaluation flow 1. User submits an access request for an access level. 2. System looks up the access level's linked access policy. 3. Eligibility is checked: user must be in `eligibleGroups` (or no groups set) and must not be in `ineligibleGroups`. Deny wins over allow, so membership in an ineligible group excludes the user even when they are also in an eligible group. 4. If eligible: the approval template is applied (or the request is auto-approved if `approvalTemplateId` is null). 5. If ineligible: the request is blocked. *** ## Policy-driven form fields The `DURATION` and `BUSINESS_JUSTIFICATION` fields on an access request form are gated by the selected access level's policy: * The Duration field renders only for access levels whose policy uses `durationMode: choice` and has at least one entry in `durationOptions`. It is hidden for `fixed` and `none`. * The Business Justification field renders only for access levels whose policy has `requiresBusinessJustification` set. * When either field renders, it is required. Visibility implies requiredness, so the form's own required flag does not need to be set. Both gates are honored in the web form and in Slack modals. *** ## Constraints * Policies are organization-scoped. * A policy can be linked to multiple access levels across different applications. * `durationMode: fixed` requires a valid finite `defaultDuration`. Use `none` for permanent access rather than an unbounded fixed duration. * A requested duration that is not one of the policy's `durationOptions` snaps to the closest allowed option rather than being accepted as-is. This matters for API and MCP submissions, where the duration is free-form. If no option can be resolved, the request is rejected. * Switching duration modes preserves the inactive mode's configuration, so a stored `defaultDuration` may not be present in `durationOptions`. * Removing a policy from an access level means that level falls back to auto-approval. * The `isDefault` flag marks the organization's default policy, used when no specific policy is assigned to an access level. # Configure Source: https://docs.ravenna.ai/documentation/automate/agents/configure Configure agent capabilities by writing rules, defining escalation instructions, granting knowledge access, and connecting integration tools. Define what your agent can do through escalation instructions, rules, knowledge access, and tool integrations. *** ## Escalation instructions Escalation instructions guide your agent on handling situations it cannot resolve independently. Without custom instructions, agents use default behavior: * Escalate to a human agent only when you cannot solve the problem using knowledge base lookups or available tools * Avoid unnecessary back-and-forth with the requester. If clarifying questions don't help, proceed with escalation * When escalating, create a ticket and inform the user that a human agent will take over * Once escalated, do not attempt to further solve the issue ### Configure escalation instructions Open your agent's settings page. Locate the **Escalation Instructions** section under Capabilities. Click **Add** (or **Edit** if instructions already exist). Write your escalation guidelines using natural language and `@` mentions. Save your escalation instructions. ### Use mentions in escalation instructions Reference resources using `@` mentions: * **Knowledge bases**: Direct the agent to check specific knowledge sources before escalating * **Forms**: Create tickets with specific forms when escalating * **Categories, tags, and statuses**: Classify or update the ticket so downstream workflows can pick it up **Example with knowledge and form:** Before escalating, check `@IT Knowledge Base` one more time for any relevant articles. If still unable to resolve, create a ticket with `@Form - General Support` and inform the user that a specialist will follow up within 24 hours. **Example with form and category (hands off to a workflow via ticket state):** When you cannot resolve a user's access request, create a ticket with `@Form - Escalated Access Review` and set `@Category - Access Review`. Inform the user that their request requires manager approval and they'll be notified within 1 business day. ### Best practices * Be specific about escalation triggers with clear conditions * Include user communication telling the agent what to say when escalating * Set expectations with information about response times or next steps * Reference resources using `@` mentions to connect escalation to specific forms, categories, or knowledge bases *** ## Rules Rules are natural language instructions that define how your agent handles specific scenarios. Each rule teaches your agent a capability using prompts that reference Ravenna resources like forms and knowledge folders. ### Rule structure Each rule contains: * **Title**: Descriptive name for the rule (for example, "Password reset handler") * **Instruction**: Natural language prompt telling the agent what to do and when * **Enabled/disabled toggle**: Control whether the rule is active ### When to use rules Create rules when you want your agent to: * Handle specific kinds of request consistently * Route requests to the correct form * Reference specific knowledge sources for answers * Follow defined processes for common scenarios * Provide specialized responses for particular topics ### Writing effective rules **Be specific about triggers** Clearly define when the rule should activate. When a user asks about password resets, account lockouts, or login issues... **Reference resources with @ mentions** Use `@` to link to specific Ravenna resources. Check `@IT Knowledge Base` for relevant articles before responding. Create a ticket with `@Form - Password Reset` if action is needed. **Define expected outcomes** Tell the agent what success looks like. Inform the user that their request has been logged and provide the ticket number. **Keep instructions focused** Each rule should handle one scenario. Create multiple rules for different use cases rather than one complex rule. **Knowledge-first response** When a user asks a question, first check `@IT Knowledge Base` for relevant articles. If you find an article that answers the question, provide a summary and link to the article. If no articles are found, create a support ticket with `@Form - General Inquiry` and inform the user that their request has been logged. **Password reset handling** When a user requests a password reset or reports being locked out of their account, create a ticket with `@Form - Password Reset`. Confirm to the user that their request has been submitted and that IT will process it shortly. **Software access requests** When a user requests access to software or applications, ask them to specify which application they need and their business justification. Then create a ticket with `@Form - Software Access Request` including the details they provided. Learn about [software access requests](/documentation/automate/access-provisioning/agent) for enabling policy-aware access provisioning on agents **Hand off to a workflow via a form** When a user requests software access, ask which application they need and their business justification. Then create a ticket with `@Form - Software Access Request` including the details they provided. A workflow triggered by the form submission will handle provisioning and approvals automatically. **Hardware issues** When a user reports hardware problems (laptop, monitor, keyboard, mouse), first ask clarifying questions about the issue. Then create a ticket with `@Form - Hardware Support` and let them know an IT technician will follow up. **Multi-step process** When a new employee starts, create a ticket with `@Form - Employee Onboarding` capturing the new hire's details. A workflow triggered by the form submission will provision their accounts, assign equipment, and schedule orientation. Confirm with the manager that the onboarding process has begun. * Use clear, conversational language as if explaining to a colleague * Break complex logic into numbered steps for multi-part processes * Include fallback behavior telling the agent what to do if the primary action isn't possible * Specify tone when needed, adding guidance like "respond empathetically" for sensitive topics When you type `@` in a rule, escalation instruction, or skill, the resource picker groups suggestions by resource type. If your workspace organizes resources into folders or collections, you can drill into them to find a specific item without scrolling through a flat list. Drilldown is available for resources that support nested hierarchies: * Knowledge folders and their subfolders * Form folders and their subfolders **How drilldown works** * Folder entries show the total number of items they contain, including items in nested subfolders. * Press **Tab** or **→** on a folder to open it and see its contents. Press **←** or **Backspace** to go back up one level. * Press **Enter** on a folder to grant the agent access to the entire folder, including everything nested inside. * Press **Enter** on an individual document or form to grant access to just that item. **Selecting a whole folder vs. a specific item** Selecting a folder is a quick way to give the agent broad access to a topic. For example, mentioning `@IT Knowledge Base` grants access to every document inside that folder and its subfolders. If you want the agent to use only a specific article, drill in and select that document directly. **Mention chip display** Once you select an item, the mention chip shows the top-level resource category followed by the item name (for example, `IT Knowledge Base / VPN Setup`). Intermediate subfolder names are omitted to keep rules readable. Documents whose parent folder has been deleted or archived still appear at the root of the picker so you can reference them. Re-organize or archive these items in the source view if you want to clean them up. You can write rules that instruct the agent to send responses privately. When a rule involves sharing credentials, API keys, or other sensitive information, the agent automatically sends that content as a private DM to the requester. You can also explicitly instruct the agent to respond privately in a rule. When a user asks for their database credentials, look up the credentials in `@IT Credentials KB` and respond privately with the connection details. Never share credentials in the public channel. **Form access** You must reference forms within rules for the agent to create tickets of that type. Your agent does not have access to all forms by default. The agent only uses forms that are **Published**. If a referenced form is in **Draft** or **Archived** status, the agent skips it and falls back to other matching rules or escalates. Publish a form before referencing it in a rule to ensure the agent can present it to users. **Rule selection** The agent selects the single best matching rule for each request. When multiple rules could apply, it picks the most specific one. Keep rules distinct for predictable behavior. ### Manage rules at workspace level Create reusable rules at the workspace level from the **Rules** tab on the Agents page. Workspace-level rules can be shared across multiple agents for consistent behavior. Navigate to **Agents** in your workspace and click the **Rules** tab. Click **New Rule** and enter a descriptive title. Write the instruction using natural language and `@` mentions to reference forms, knowledge folders, and tools. Click **Save** to create the rule. **Workspace-level vs agent-specific rules** | Aspect | Workspace-level rules | Agent-specific rules | | --------------- | --------------------------------------------------- | --------------------------------------- | | **Location** | Rules tab on Agents page | Individual agent's Capabilities section | | **Reusability** | Can be attached to multiple agents | Only available to that specific agent | | **Management** | Centralized editing with changes applied everywhere | Edited per agent | | **Best for** | Common scenarios shared across teams | Agent-specific behavior | Create workspace-level rules for common scenarios like password resets or software access requests that multiple agents should handle consistently. Use agent-specific rules for behavior unique to a particular agent or channel. **Reuse rules across agents** Attach workspace-level rules to multiple agents: 1. Create a rule in the **Rules** tab 2. Open any agent and navigate to **Capabilities** > **Rules** 3. Click **Add Rule** and select from your workspace rules 4. Add the same rule to as many agents as needed When you update a workspace-level rule, changes automatically propagate to all agents using that rule. You cannot delete a rule currently attached to one or more agents. Remove it from all agents before deletion. **Duplicate rules** Create an independent copy of a rule and attach it to any compatible agent: 1. Open an agent and navigate to **Capabilities** > **Rules** 2. Click the action menu on the rule you want to copy 3. Select **Duplicate** 4. Enter a title for the new rule (defaults to the original title with "Copy" appended) and choose a target agent 5. Click **Duplicate** to create the copy The duplicate is fully independent. Editing the original rule does not affect the copy, and vice versa. Use duplicate when you want to create an independent variation of a rule for a different agent. Use attach when you want multiple agents to share the same rule. **Delete a rule** To delete a workspace rule, open it in the editor and click **Delete**. Rules that are currently attached to one or more agents must be detached first. Deletion is permanent and cannot be undone. **Customize the rules table view** The **Rules** tab on the Agents page displays all workspace-level rules in a sortable table. Use the **View** menu above the table to control which columns are visible. Hide columns you do not need to focus on the information that matters for your workflow. On the **Rules** tab, click the **View** button above the rules table. Select or clear the checkbox next to each column to show or hide it. Your selection is remembered for the next time you open the table. **Bulk delete rules** Delete multiple workspace-level rules at once from the **Rules** tab. Use bulk delete to clean up unused or outdated rules in one action instead of removing them individually. On the **Rules** tab, use the checkbox at the start of each row to select the rules you want to delete. Use the checkbox in the table header to select every rule on the current page. Click the **Delete** button that appears in the bulk actions bar above the table. Review the list of rules in the confirmation dialog and click **Delete** to remove them. You cannot bulk delete rules that are currently attached to one or more agents. Detach a rule from every agent before including it in a bulk delete. If your selection includes attached rules, the delete action skips them and reports which rules were not deleted. Bulk delete is permanent. Deleted rules cannot be restored, and any agents that previously used them lose those instructions. *** ## Knowledge Select specific knowledge folders for your agent to access when answering user questions. This ensures the agent provides accurate information based on your organization's knowledge base. Learn how to [set up and manage knowledge sources](/documentation/automate/knowledge/overview) *** ## Tools Tools extend your agent's capabilities to query data, execute commands, and automate tasks. Agents have access to built-in Ravenna tools for ticket management and web search, plus additional tools from installed integrations like device management systems and CRM platforms. ### How tools work Tools are referenced in rules using @ mentions. When you write a rule, use @ mentions to specify which tool actions the agent should use and when to use them. ### Tool availability and explicit opt-in By default, some built-in tools only appear to the agent when the workspace has matching context. For example, the agent hides `@Set Category` when the workspace has no categories, and hides form-related tools when no forms are attached to a matched rule. This keeps the tool surface focused so the agent never sees an action with nothing to act on. Attaching a tool to the agent, or `@`-mentioning it in a rule, counts as an explicit opt-in and bypasses those context-presence checks for that turn. Use this when you want a tool surfaced even if the supporting context is sparse or builds up over the conversation. * **Admin opt-in:** Tools attached to the agent under **Capabilities** > **Tools** are always available to the agent. * **Rule opt-in:** Tools `@`-mentioned in a matched rule are available for that turn, even if other context (forms, categories) is empty. * **Knowledge lookup stays scoped.** `@Search Knowledge Base` is a data boundary, not just an affordance. It only appears when the agent has at least one knowledge folder attached, or a matched rule mentions a `@Knowledge folder` or `@Knowledge document`. Explicit tool opt-in does not unlock knowledge search on its own — you must also point the agent at the knowledge to search. * **Integration availability still applies.** Disconnected integrations make their tools unavailable regardless of opt-in. The **Tools** picker in the agent editor mirrors what the agent will actually see at runtime. Tools that depend on workspace context — such as `@Search Knowledge Base` when no knowledge folders are attached — are hidden from the picker so you do not advertise an action the agent would silently drop. **Example rule using Ravenna tools:** When a user requests approval on a ticket, use @Approve Ticket to mark the ticket as approved. Confirm to the user that the ticket has been approved and any automated workflows will proceed. **Example rule using Fleet device management tools:** When a user reports their device is slow or having performance issues, @Look up device with Fleet to get the device information, then @Run query with Fleet to check system diagnostics. Analyze the returned information and provide basic troubleshooting steps based on what you find. **Example rule using HubSpot CRM tools:** When a user asks about a customer's account status or deal information, @Search contacts with HubSpot to find the contact by email, then @List deals with HubSpot to retrieve their active deals. Summarize the account status and recent activity for the user. ### Ravenna tools Built-in tools available to all agents for ticket management, application lookup, and information retrieval. Creates new tickets with specified properties like title, description, channel, priority, and custom fields. Agents can create tickets based on conversation context, automatically routing requests to the appropriate channels with pre-filled information. **Common use cases:** * Create support tickets from Slack conversations * Generate tickets with pre-filled form data * Route requests to specific channels * Automate ticket creation for common kinds of request Updates existing ticket properties including title, description, priority, tags, assignees, requester, and custom fields. Agents can modify tickets based on new information gathered during conversations. **Common use cases:** * Add context to existing tickets * Update priority based on urgency * Modify ticket properties from conversation * Add tags for categorization Adds a user as an approver to a ticket. Agents can manage approval workflows by adding approvers based on conversation context or the form. **Common use cases:** * Add managers as approvers for access requests * Route approvals to specific team members * Manage multi-step approval processes * Dynamically assign approvers based on the form **Example rule:** When a user requests that someone be added as an approver to a ticket, use @Add Approver to add the specified user as an approver. Confirm to the user that the approver has been added and will be notified. Approves a ticket on behalf of the user. The user must be an approver on the ticket or a workspace admin. Enables conversational approval workflows where authorized users can approve requests through natural language. **Authorization:** * User must be listed as an approver on the ticket, OR * User must be a workspace admin **Common use cases:** * Enable conversational approvals in Slack * Streamline approval workflows * Allow admins to approve any ticket * Reduce approval friction for authorized users **Example rule:** When a user who is an approver or workspace admin says they approve a ticket or request, use @Approve Ticket to mark the ticket as approved. Confirm to the user that the ticket has been approved and notify them that any automated workflows will proceed. Records the speaking user's approval on the ticket's active approval round. Unlike **Approve Ticket**, this tool only ever approves as the person talking, so a requester or bystander cannot approve on someone else's behalf. **Authorization:** * User must be a pending approver on the ticket's active round If the user is an approver on a later round, the tool explains that an earlier round must finish first. If they are not an approver at all, it says so and the agent relays that. **What the agent learns:** after recording the approval, the tool reports whether the round finished, whether the whole request is now approved, how many approvers remain in the active round, and how many later rounds are still pending. The agent uses this to answer "what happens next" without a second lookup. **Common use cases:** * Approve a request by replying "Approved" or "LGTM" in Slack * Tell an approver how many sign-offs are still outstanding * Keep multi-round approvals moving without opening the ticket **Example rule:** When an approver replies with approval language such as "approved", "LGTM", or "go ahead", use @Approve Request to record their decision. Then tell them whether the request is fully approved or how many approvers are still pending. Records the speaking user's decline on the ticket's active approval round, with an optional reason that is saved on the ticket and shown to the requester. **Authorization:** * User must be a pending approver on the ticket's active round **Decline reason:** if the user gives a reason in their message, such as "denied, the budget is too high", the agent passes it through and the requester sees it. If they give no reason, the decline is recorded without one. **Common use cases:** * Decline a request conversationally in Slack * Capture the rejection reason so the requester knows what to change * Close out requests that should not proceed without opening the ticket **Example rule:** When an approver replies with declining language such as "declined", "denied", or "reject this", use @Decline Request to record their decision. Pass along any reason they gave so the requester can see it, and confirm that the requester has been notified. Retrieves the list of applications available in the workspace. Agents can reference this list when helping users request access to software and tools. **Common use cases:** * Help users discover available applications * Validate application names in access requests * Provide information about available software * Guide users through application access processes Retrieves all access levels for a specific application. Access levels define permission tiers for applications (for example, Read Only, Editor, Admin). Agents use this tool to populate access level fields in forms and workflows accurately. **Tool name:** `@List Access Levels` **Input:** Requires an application ID **Automatic prefilling:** When only one access level exists for an application, agents automatically prefill it in forms even if the user didn't explicitly mention it. **Common use cases:** * Populate access level fields in access request forms * Validate user-requested access levels against available options * Determine available permission tiers for applications * Auto-fill forms when only one access level exists **Example rule:** When a user requests access to an application, first use @List Applications to find the application ID. Then use @List Access Levels with that application ID to determine available access levels. If the user specified an access level (like "Read Only" or "Admin"), match it to the available options. If only one access level exists, automatically use it. Create the access request ticket with the appropriate access level prefilled. Mentions a user in the agent's response with proper platform-specific formatting. The tool automatically handles platform differences, using Slack user IDs for Slack conversations and display names for other channels like email and web. **Tool name:** `@Mention User` **Common use cases:** * Include multiple people in collaborative responses * Notify specific users about actions or updates * Facilitate multi-user conversations * Loop in relevant team members **Example rule:** When providing updates about a ticket, mention the ticket assignee using @Mention User so they're notified of the conversation. Include a summary of the update in your response. Searches the web for current information not available in your knowledge base. Agents can research topics, find documentation, and provide up-to-date answers requiring external information. **Common use cases:** * Find current information not in knowledge base * Research technical questions * Look up external documentation * Provide real-time information Searches for users by name or email within your organization. Returns matching user records with their Ravenna user IDs. Use this tool when the agent needs to identify a specific user, for example to populate user selection fields in forms or resolve a name mentioned in a request. **Tool name:** `@User Lookup` **Search behavior:** * Matches against first name, last name, and email address, even with partial or approximate input * Supports multi-word queries (searches each word across all fields) * Returns users ordered by relevance * Scoped to your organization only **Common use cases:** * Resolve user names to Ravenna user IDs for user selection fields * Look up team members when processing requests that reference people * Find users when the requester mentions someone by name * Populate manager or approver fields in access request forms When users are @mentioned in Slack, the Ravenna user ID is already included in the message metadata. The agent only needs User Lookup when the user is referenced by name without an @mention. **Example rule:** When a user submits a request that involves another person (like "my manager Sarah Chen" or "please add John to the project"), use @User Lookup to find the referenced user's Ravenna ID. Use this ID to populate any user selection fields in the form. Searches for user groups within your workspace. Returns matching group records with their IDs, names, descriptions, and source (for example, RAVENNA, OKTA, GOOGLE\_WORKSPACE, or SLACK). Use this tool when the agent needs to resolve a group name to populate user group selection fields in forms. **Tool name:** `@Group Lookup` **Search behavior:** * Searches across group name, description, email, and other metadata fields registered by integrations * Supports multi-word queries (each word must match somewhere across the group's searchable fields) * Scoped to the current workspace. Only groups visible in that workspace are returned * When called with a form ID and field ID, results respect the field's allowlist and source constraints (for example, only native groups or only groups from a specific integration) **Common use cases:** * Resolve group names to IDs for user group selection fields in forms * Look up teams or departments when processing requests that reference a group * Find groups when the requester mentions a team by name or email **Example rule:** When a user submits a request that involves a team or group (like "assign this to Team Falcon" or "the Engineering group needs access"), use @Group Lookup to find the group's ID. Use this ID to populate any user group selection fields in the form. Assigns a category to the current ticket. Categories are workspace-wide classification labels that help organize and route tickets. **Tool name:** `@Set Category` **Common use cases:** * Automatically categorize tickets based on conversation content * Apply categories as part of triage rules * Set categories to trigger category-based workflows **Example rule:** When a user reports a hardware issue, use @Set Category to assign the "Hardware" category to the ticket. This ensures the ticket is routed to the correct team and triggers any hardware-specific workflows. Retrieves all available tags in the workspace. Returns tag names, IDs, and descriptions. Agents use this tool to discover valid tags before applying them to tickets. **Tool name:** `@List Tags` **Common use cases:** * Discover available tags before adding them to tickets * Validate tag names mentioned by users against the workspace tag list * Provide users with a list of available tags for categorization **Example rule:** When a user asks to tag a ticket, use @List Tags to find the matching tag. If the tag exists, apply it to the ticket. If no matching tag is found, let the user know and suggest similar available tags. Retrieves all available categories in the workspace. Returns category names, IDs, and descriptions. Agents use this tool to discover valid categories before assigning them. **Tool name:** `@List Categories` **Common use cases:** * Discover available categories before assigning one to a ticket * Validate category names mentioned by users * Help users understand the available categorization options **Example rule:** When a user asks about ticket categories or wants to categorize a ticket, use @List Categories to find available options. Present the relevant categories and use @Set Category to apply the user's choice. Retrieves all available ticket statuses in the workspace. Returns status labels, IDs, and status groups. Agents use this tool to discover valid statuses when updating tickets. **Tool name:** `@List Statuses` **Common use cases:** * Discover available statuses before updating a ticket's status * Validate status names mentioned by users * Help users understand the ticket lifecycle stages **Example rule:** When a user asks to change a ticket's status, use @List Statuses to find the matching status. Update the ticket with the correct status and confirm the change to the user. Searches and filters tickets using text search and property-based filters. Supports hybrid search combining keyword and semantic matching on ticket titles and ticket numbers. **Tool name:** `@List Tickets` **Search and filter options:** * **Text search**: Searches ticket titles and ticket numbers * **Filters**: Priority, assignee, status, queue, form, requestor, source, tags, created date, updated date, resolved date, and due date **Common use cases:** * Find tickets matching specific criteria for reporting or triage * Look up tickets assigned to a particular user or team * Search for tickets by keyword across a workspace * Filter tickets by status, priority, or date range **Example rule:** When a user asks about their open tickets, use @List Tickets to search for tickets where the requestor is the current user and the status is open. Summarize the results and highlight any high-priority items. Retrieves detailed information about a specific ticket including title, description, priority, status, assignee, requester, tags, and timestamps. Accepts full ticket IDs, 8-character short IDs, or PREFIX-NUMBER format (for example, TICK-1234). **Tool name:** `@Get Ticket Info` **Supported ID formats:** * Full CUID (for example, `clx123...`) * 8-character short ID (for example, `abc12345`) * PREFIX-NUMBER (for example, `TICK-1234`) **Common use cases:** * Look up the current status and details of a specific ticket * Check who is assigned to or requested a ticket * Retrieve ticket context before making updates * Answer user questions about a specific request **Example rule:** When a user asks about the status of a specific ticket, use @Get Ticket Info to retrieve the ticket details. Summarize the current status, assignee, and priority for the user. Retrieves the conversation history for a ticket in chronological order. Returns message content, author information, and timestamps. Accepts the same ID formats as Get Ticket Info. **Tool name:** `@Get Ticket Messages` **Common use cases:** * Review the conversation history on a ticket * Understand what has been discussed or resolved * Provide context when escalating or reassigning tickets * Summarize a ticket's communication thread **Example rule:** When a user asks what happened on a ticket or wants a summary of the discussion, use @Get Ticket Messages to retrieve the conversation history. Provide a concise summary of the key points and any actions taken. Retrieves all channels in the workspace. Returns channel names, IDs, prefixes, and emoji icons. Use this to find channel IDs for filtering tickets or routing new tickets to the correct channel. **Tool name:** `@List Channels` **Common use cases:** * Help users discover available channels for submitting requests * Find channel IDs for ticket filtering or creation * Provide an overview of how the workspace is organized **Example rule:** When a user asks where to submit a request or wants to know what channels are available, use @List Channels to retrieve the workspace channels. Help them identify the most appropriate channel for their request. Retrieves detailed information about a specific channel by ID, including its name, prefix, emoji, and creation date. **Tool name:** `@Get Channel Info` **Common use cases:** * Look up details about a specific channel * Verify channel configuration before routing tickets * Provide channel context when helping users navigate the workspace **Example rule:** When a user asks about a specific channel, use @Get Channel Info to retrieve the channel details. Share the channel name, prefix, and purpose with the user. Creates a new channel in the workspace with a specified name and emoji. The channel prefix is generated automatically by the system. **Tool name:** `@Create Channel` **Common use cases:** * Set up new channels for teams or projects * Create channels as part of workspace onboarding * Add channels for new request categories **Example rule:** When a user requests a new channel for their team, use @Create Channel to create it with the specified name and an appropriate emoji. Confirm the channel was created and share its details. Updates an existing channel's name or emoji. **Tool name:** `@Update Channel` **Common use cases:** * Rename channels to reflect updated team or project names * Change a channel's emoji icon **Example rule:** When a user asks to rename a channel or change its emoji, use @List Channels to find the channel ID, then use @Update Channel to apply the changes. Confirm the update to the user. Retrieves all forms available in the workspace. Returns form names, IDs, descriptions, and whether they have custom fields enabled. Supports optional text search to filter by name or description. **Tool name:** `@List Forms` **Common use cases:** * Help users find the right form for their request * Look up form IDs before creating tickets * Provide an overview of available forms **Example rule:** When a user is unsure which form to use for their request, use @List Forms to retrieve the available forms. Recommend the most appropriate form based on the user's description of their issue. Retrieves the custom fields defined on a specific form, including field labels, types, required status, and available options for select fields. Use this before creating tickets with custom field values. **Tool name:** `@List Custom Fields` **Input:** Requires a form ID **Common use cases:** * Discover what fields a form requires before creating a ticket * Validate user-provided values against available options for select fields * Understand form structure to collect the right information from users **Example rule:** Before creating a ticket with a specific form, use @List Custom Fields to get the form's fields. Ask the user for any required fields that haven't been provided, then create the ticket with the correct field values. Retrieves users in the workspace with optional search filtering by name or email. Returns user IDs, names, and email addresses. Use this to find user IDs for assigning tickets, setting requesters, or adding followers. **Tool name:** `@List Users` **Common use cases:** * Find user IDs for ticket assignment or requester fields * Search for team members by name or email * Discover workspace members for collaboration **Example rule:** When a user asks to assign a ticket to someone, use @List Users to search for the person by name. Then use @Update Ticket to set the assignee. Confirm the assignment to the user. Retrieves a specific user's details by their ID, including first name, last name, and email address. **Tool name:** `@Get User By ID` **Common use cases:** * Look up user details when you have a user ID from another tool's output * Resolve user IDs from ticket data into readable names and emails * Verify user information before taking actions on their behalf **Example rule:** When reviewing ticket details that include a user ID for the assignee or requester, use @Get User By ID to retrieve their name and email. Include this information when summarizing the ticket for the user. Searches your organization's internal knowledge base documents using hybrid retrieval (semantic and keyword matching). Returns relevant document chunks from HR policies, IT procedures, benefits information, onboarding guides, and other ingested content. **Tool name:** `@Search Knowledge Base` **Access scoping:** Results are scoped based on the user's workspace role. Admins and members see all knowledge bases, while guests see only global knowledge bases and those linked to their associated channels. **Common use cases:** * Answer questions about internal company policies and procedures * Find IT documentation and troubleshooting guides * Look up HR benefits, leave policies, or onboarding information * Search for internal process documentation before escalating **Example rule:** When a user asks about company policies, benefits, or internal procedures, use @Search Knowledge Base to find relevant documentation. Summarize the key points and cite the source document. If no results are found, let the user know and offer to create a support ticket. ### Third-party integration tools Additional tools become available when you install and connect integrations to your workspace. Each integration provides specialized tools for its platform. Integration tools require the corresponding integration to be installed and connected to your workspace. If an integration is disconnected, tools for that integration will show a warning indicator. **Integrations with agent tool support:** * [Fleet](/integrations/fleet/agent-tools) * [HubSpot](/integrations/hubspot/agent-tools) * [Iru](/integrations/iru/agent-tools) * [Jamf Pro](/integrations/jamf/agent-tools) * [Microsoft Intune](/integrations/intune/agent-tools) * [Okta](/integrations/okta/agent-tools) Review the [Integrations page](/integrations/overview) to see all available integrations ### Tool execution policies Each tool referenced in a rule can be gated with an **execution policy** that controls what happens before the agent invokes it. Policies are scoped per rule, so the same tool can run automatically in one rule and require approval in another. Set the policy from a rule's tool list. Each tool shows an **Execution Policy** row with three modes: | Mode | Behavior | Best for | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | Auto-execute | The tool runs immediately when the agent invokes it. No approval or confirmation step. | Read-only lookups and low-risk actions where speed matters. | | Requires confirmation | The agent describes the action it intends to take and waits for the requester to confirm before running the tool. No approval round is created. | A safety net for admins self-servicing write actions, where you want a final "Should I proceed?" prompt before the change happens. | | Requires approval | The agent buffers the tool call, opens an approval round on the ticket, and only runs the tool after every required approval is granted. | High-impact actions like provisioning access, creating groups, or modifying production data. | **Defaults:** * Read tools (such as lookups and searches) default to **Auto-execute**. * Write and delete tools (such as create, update, add member, deactivate) default to **Requires confirmation** so admins are prompted before changes are made. #### Choose approvers When you select **Requires approval**, an **Approvers** field appears for that tool. Pick one of: * **Workspace Admins (default)** — any workspace admin can approve. No template needed. * **An [approval template](/documentation/tickets/approvals/templates)** — uses the template's rounds, policies (any-of / all-of), and approver lists. Choose this when you need named approvers, user groups, role-based approvers like the requester's manager, or multiple sequential rounds. * **Create approval template** — opens the template editor in-place. The new template is selected on the tool as soon as you save it. Approvers are notified by Slack DM when an approval round opens. The agent will not execute the gated tool — or any other approval-gated tool it batched alongside it in the same plan — until the round clears. #### Batched approvals When a single agent run plans multiple approval-gated tool calls, Ravenna does not open one approval round per tool. Instead, after the agent finishes reasoning it groups buffered calls by approver set and opens **one parallel approval round per group**. Once every round clears, the agent re-runs and executes the buffered calls with the originally planned inputs. This avoids forcing approvers through several sequential prompts for a single user request. #### Example: gate a sensitive write tool The rule below uses Google Workspace tools to add a user to a group. Configure the rule's tool list so that `List Google Groups` stays on **Auto-execute** (it only reads) while `Add member to Google Group` is set to **Requires approval** with an "IT leads" approval template. When a user requests to be added to a Google Group, use `@List Google Groups` to find the matching group, then use `@Add member to Google Group` to add them. Confirm to the user that an approval request has been sent and they will be notified once it clears. With this configuration, the lookup runs immediately, but the membership change waits for an approval round. If the same `Add member to Google Group` tool is used in a different rule (for example, a self-service onboarding rule for direct reports of a manager), you can set a different policy on that rule without affecting this one. Execution policies are set per rule, not per tool globally. If a tool is referenced in multiple rules, configure the policy in each rule based on the risk of that specific scenario. ### Best practices * Reference tools in rules using @ mentions to define when and how the agent should use them * Provide context about what to do with tool results (analyze, summarize, troubleshoot) * Combine multiple tool actions for complex multi-step processes * Use Ravenna tools for ticket management and approval workflows * Use integration tools for platform-specific data retrieval and actions * Test tool-based rules thoroughly to ensure correct data retrieval and analysis * Monitor agent logs to identify tool usage patterns and opportunities for optimization ## Configuration model An agent's behavior is determined by four configuration layers that work together: 1. **Escalation instructions** set the fallback strategy. They define what the agent does when it cannot resolve a request. This is the safety net. 2. **Rules** define scenario-specific behavior. Each rule describes a trigger condition and an action, referencing Ravenna resources with `@` mentions. 3. **Knowledge** provides searchable content for answering questions. The agent retrieves from connected knowledge folders. 4. **Tools** extend capabilities with actions from built-in Ravenna features and third-party integrations. Processing order: when a user sends a message, the agent evaluates rules to find the best match, checks connected knowledge for relevant content, and executes tool calls as needed. If it cannot resolve the request, it falls back to escalation instructions. *** ## Resource access model Agents operate on an explicit-access model. They do not have automatic access to all workspace resources. Access is granted through two mechanisms: * **`@` mentions in rules or escalation instructions** grant access to forms, tools, knowledge bases, categories, tags, and statuses. If a form is not referenced in any rule, the agent cannot use it. * **Knowledge configuration** grants access to specific knowledge folders via the agent's settings. This means: * A form must be `@`-mentioned in at least one rule for the agent to create tickets of that type. * Tools are referenced with `@` in rules to specify when they should be used. * Knowledge folders are selected in the agent's knowledge configuration. Agents cannot trigger workflows. Hand off to a workflow through ticket state instead — for example, submit a form, set a category, or change a tag or status, and configure a workflow to fire on that ticket event. *** ## Rule-writing patterns ### Effective rule structure A well-written rule has three parts: 1. **Trigger condition** describes when the rule activates. Be specific about the scenarios, keywords, or kinds of request. 2. **Action sequence** describes what the agent should do, referencing resources with `@` mentions. For multi-step processes, use numbered steps. 3. **Outcome definition** tells the agent what to communicate back to the user after completing the action. ### Multi-resource rules A single rule can reference multiple resources. Common combinations: * **Knowledge + form:** Check `@Knowledge Base` first. If the answer resolves the question, respond with it. If not, create a ticket with `@Form Name`. * **Tool + tool:** Use `@Look up device with Fleet` to get device info, then `@Run query with Fleet` to run diagnostics. Analyze results before responding. * **Form + workflow handoff:** Collect information via `@Form Name` and submit it on the ticket. A workflow triggered by that form submission handles the backend processing. * **Application + access levels:** Use `@List Applications` to find the app, then `@List Access Levels` to determine available permission tiers before creating a request. ### Rule design recommendations * **One scenario per rule.** A rule that handles password resets, software access, and hardware issues is too broad. Split into three rules. * **Include fallback behavior.** Tell the agent what to do if the primary action fails or does not apply. For example: "If no matching article is found, create a support ticket." * **Specify user communication.** Tell the agent what to say to the user at each step: confirmation messages, expected timelines, next steps. * **Avoid overlapping triggers.** The agent selects only the single best matching rule per request. If two rules have similar triggers, the agent picks the most specific one. Distinct trigger conditions produce more predictable behavior. ### Channel awareness Each turn, the agent identifies which channel a message arrived on: a Slack channel, direct message, the Portal, email, or an external ticketing integration such as Jira. This context is automatic and requires no rule configuration. When a workspace connects a published agent to its portal, that agent powers the portal chat: it answers from knowledge, creates tickets, and routes them to the right team. See the [Portal](/documentation/platform/portal#chat-with-the-ai-agent). Channel awareness prevents **circular redirects**. If a rule or knowledge base article tells users to "post in `#it-help`" and the user is already messaging from `#it-help`, the agent recognizes the redirect points at their current location. Instead of echoing the instruction back, the agent reads the article as a script: it collects the inputs the human responder will need, then escalates the ticket. The full conversation becomes the handoff context for the assignee. For redirects to a **different** channel (for example, a user in `#general` who needs to post in `#it-help`), the agent relays the instruction verbatim so the user knows where to go next. The agent applies channel-aware self-reference handling when it can identify a specific end-user channel: * Slack channels (channel name known) * External ticketing integrations such as Jira, where the project or system is known Redirects from direct messages, the Portal, email, and automated sources are always treated as legitimate cross-channel advice and relayed to the user. **Rule or KB article:** > For laptop replacements, post in `#it-help` with your asset tag, preferred model, and shipping address. **User messages from `#it-help`:** > My laptop screen is cracked, can I get a replacement? **Agent behavior:** Instead of repeating "post in `#it-help`," the agent asks for the asset tag, preferred model, and shipping address one item at a time, then publishes a ticket with the collected information for a human responder. When a ticket spans multiple channels (for example, a user opens a request in Slack and replies later by email), the agent treats follow-ups as continuations of the same ticket. It carries forward what the user already provided and does not redirect them back to the original channel. *** ## Escalation design Default escalation behavior (when no custom instructions are set): * Escalate only when knowledge and tools cannot resolve the request * Avoid excessive clarifying questions before escalating * Create a ticket and inform the user that a human agent will take over * Stop attempting to resolve the issue after escalation Custom escalation instructions override this default. They can: * Reference specific knowledge bases to check before escalating * Create tickets with specific forms when escalating * Set a category, tag, or status so a downstream workflow can pick up the ticket * Define escalation criteria for specific kinds of request * Name a specific person to assign the ticket to on handoff ### Assignment on escalation When the agent publishes a ticket for human handoff, Ravenna picks the new assignee in this order: 1. **A user named in your rule or escalation instructions.** If a rule says "after escalation, assign to @Jane," the agent passes that user as the assignee. Invalid or unknown user IDs are logged as warnings and ignored, then the agent falls through to the next step. 2. **The channel's first auto-assignee**, if one is configured. 3. **Unassigned**, ready for the team to pick up manually. The agent owner (the [Working on it](/documentation/tickets/roles#working-on-it-agent-owner) chip) is cleared automatically when the ticket publishes, so the human assignee always reflects the current owner. The agent does not mention who the ticket was assigned to in its handoff message to the requester. The user only sees confirmation that a human will follow up. **Example rule with a named assignee:** When a user asks for help with billing, collect the invoice number and any error message they're seeing, then escalate. After publishing the ticket, assign it to `@Jane Doe` so she can follow up with the requester. *** ## Tool selection guidance ### Built-in Ravenna tools | Tool | Purpose | When to use | | --------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | | Create Ticket | Creates tickets with specified properties | Ticket creation from conversations, form-based requests | | Update Ticket | Modifies existing ticket properties | Adding context, changing priority, updating fields mid-conversation | | Add Approver | Adds approval requirement to a ticket | Setting up approval flows conversationally | | Approve Ticket | Approves a ticket on behalf of the requesting user | Conversational approvals (requires the user to be an approver or admin) | | Approve Request | Records the speaking user's approval on the active approval round | Approvers replying "approved" in Slack, reporting how many sign-offs remain | | Decline Request | Records the speaking user's decline, with an optional reason | Approvers rejecting a request and explaining why | | List Applications | Retrieves available applications | Software access requests, application discovery | | List Access Levels | Retrieves permission tiers for an application | Populating access level fields, validating requested levels | | Mention User | Mentions a user with platform-correct formatting | Looping in team members, notifying specific users | | User Lookup | Searches for users by name or email | Resolving names to user IDs for form fields | | Group Lookup | Searches for user groups by name, description, and metadata | Resolving group names to IDs for user group selection fields, respecting workspace visibility and field constraints | | Web Search | Searches the web for current information | Questions not covered by the knowledge base | | Set Category | Assigns a category to the current ticket | Ticket triage, category-based routing and workflow triggers | | List Tags | Retrieves all available workspace tags | Discovering valid tags before applying them to tickets | | List Categories | Retrieves all available workspace categories | Discovering valid categories before assigning them | | List Statuses | Retrieves all available ticket statuses | Discovering valid statuses before updating tickets | | List Tickets | Searches and filters tickets by text and properties | Finding tickets by criteria, reporting, triage | | Get Ticket Info | Retrieves detailed information about a specific ticket | Looking up ticket status, details, and context | | Get Ticket Messages | Retrieves conversation history for a ticket | Reviewing discussion threads, summarizing ticket activity | | List Channels | Retrieves all channels in the workspace | Discovering channels, finding channel IDs for routing | | Get Channel Info | Retrieves details about a specific channel | Looking up channel configuration and metadata | | Create Channel | Creates a new channel in the workspace | Setting up channels for teams or projects | | Update Channel | Updates a channel's name or emoji | Renaming channels, updating channel icons | | List Forms | Retrieves all forms in the workspace | Finding the right form for a request | | List Custom Fields | Retrieves custom fields for a specific form | Discovering required fields before creating tickets | | List Users | Lists and searches workspace users | Finding user IDs for assignment, requester fields | | Get User By ID | Retrieves user details by ID | Resolving user IDs to names and emails | | Search Knowledge Base | Searches internal knowledge base documents | Answering questions about company policies and procedures | ### Tool chaining patterns Tools can be chained within a single rule to build multi-step flows: * **Application access request:** List Applications, then List Access Levels, then Create Ticket with pre-filled fields. * **Ticket creation with forms:** List Forms to find the form, List Custom Fields to get required fields, then Create Ticket with custom field values. * **Ticket investigation:** Get Ticket Info for details, then Get Ticket Messages for conversation history, then summarize findings. * **Ticket reassignment:** List Users to find the target user, then Update Ticket to set the assignee. * **Group-based requests:** Group Lookup to resolve a team name (with form and field context for allowlist-aware results), then Create Ticket with the group ID in user group selection fields. * **Knowledge-first resolution:** Search Knowledge Base for answers. If no results, create a support ticket. * **Device troubleshooting:** Look up device with Fleet, then Run query with Fleet, then analyze and respond. * **CRM lookup:** Search contacts with HubSpot, then List deals with HubSpot, then summarize findings. ### User Lookup behavior * Fuzzy matches against first name, last name, and email. * Not needed when the user is `@`-mentioned in Slack, because Slack metadata already includes the Ravenna user ID. * Required when a user is referenced by name only (e.g., "my manager Sarah Chen"). ### Group Lookup behavior * Searches across group name, description, email, and other metadata fields from integrations. Each word in the query must match somewhere across the group's searchable fields. * Scoped to the current workspace. Only groups that are visible in the workspace appear in results. * When the agent calls Group Lookup for a form field, it passes the form ID and field ID so results automatically respect any [allowlist or source constraints](/documentation/platform/groups) configured on the field. * When exactly one group matches, the agent uses the group ID to prefill the user group selection field. * When multiple groups match, the agent presents the options and asks the user to choose. * When no groups match, the agent asks the user to try a different search term. *** ## Tool execution policies Tools referenced in a rule can be wrapped in an **execution policy** that defines what happens before the tool runs in that rule's context. Policies are stored on the rule (under `definition.toolExecutionPolicies`, keyed by tool key), so the same tool can have different gating behavior in different rules. ### Modes | Mode | Runtime behavior | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Auto-execute | The tool runs as soon as the LLM emits a call. | | Requires confirmation | The agent posts a description of the pending action to the requester and waits for an in-conversation confirmation before executing. No approval round is created. | | Requires approval | The agent buffers the call instead of running it. After the LLM loop completes, all buffered calls are partitioned by approver set and a parallel approval round is opened for each partition. The agent only re-runs and executes the buffered calls once every round clears. | ### Defaults * Read-classified tools default to **Auto-execute**. * Write- and delete-classified tools default to **Requires confirmation**. Admins can override either default per rule. ### Approver selection When **Requires approval** is set, approvers are sourced from one of two places: * **Workspace admins (default).** No approval template is attached. Any workspace admin can approve. * **An [approval template](/documentation/tickets/approvals/templates).** The template's rounds, policies (any-of / all-of), user lists, group lists, and role-based approvers (for example, the requester's manager) are used to create the approval round. ### Batch approval gate The approval gate is plan-level, not call-level. When the LLM produces a plan that contains multiple approval-gated tool calls, those calls are accumulated in a tool execution buffer. After the loop ends, a single batch gate fires: calls are grouped by `approvalTemplateId`, and one parallel approval round is created per group. The agent re-triggers and replays the buffered inputs only when every round has cleared. This collapses what would otherwise be several sequential approval cycles into a single parallel one. ### Confirmation vs approval * **Confirmation** is an in-conversation prompt to the requester. Use it as a soft guardrail when the requester is also the person authorized to take the action. * **Approval** opens a formal approval round with separate approvers. Use it when someone other than the requester must authorize the action. The two modes are mutually exclusive on a given tool within a given rule. *** ## Workspace vs agent-level rules | Aspect | Workspace-level | Agent-specific | | -------- | ----------------------------------------------------- | -------------------------------------------------------- | | Scope | Shared across multiple agents | Single agent only | | Editing | Centralized. Changes propagate to all attached agents | Edited per agent | | Best for | Common scenarios (password resets, software access) | Agent-specific behavior for a particular channel or team | A workspace-level rule cannot be deleted while it is attached to any agent. Remove it from all agents first. ### Duplicating vs attaching * **Attach** a workspace-level rule when multiple agents should share identical behavior. Edits propagate to all agents using that rule. * **Duplicate** a rule when you need an independent variation. The copy can be modified without affecting the original, and changes to the original do not propagate to the copy. *** ## Constraints * **Form access requires rule reference.** The agent cannot use a form unless it is `@`-mentioned in at least one rule. * **Only Published forms are surfaced.** Draft and Archived forms are filtered out at runtime, even if they are `@`-mentioned in a rule. The agent treats them as unavailable and continues with other rules or escalates. Publish the form to make it usable. * **Agents cannot trigger workflows.** Hand off through ticket state (form submitted, category assigned, tags changed, status changed) and let a workflow fire on that event. * **Tool availability depends on integrations.** Integration tools require the corresponding integration to be installed and connected. Disconnected integrations make their tools unavailable. * **Explicit tool opt-in bypasses context-presence gates.** Tools attached to the agent or `@`-mentioned in a matched rule are surfaced even when supporting context (forms, categories) is empty. Knowledge lookup is the exception — it remains scoped to attached knowledge folders or `@`-mentioned knowledge resources. See [Tool availability and explicit opt-in](#tool-availability-and-explicit-opt-in). * **Single rule selection.** The agent selects only the single best matching rule per request, preferring the most specific match. Predictability improves when rules have distinct, non-overlapping trigger conditions. * **Knowledge is scoped to connected folders.** The agent cannot search knowledge folders that are not explicitly connected to it. * **Workspace-level rule deletion is blocked** while the rule is attached to any agent. # Customize Source: https://docs.ravenna.ai/documentation/automate/agents/customize Customize agent personality, Slack response behavior, auto-respond settings, and conversational form filling to match your team's voice and workflow. Define how your agent presents itself and communicates with users through personality settings, Slack behavior configuration, and auto-respond options. *** ## Personality By default, agents use a built-in communication style that produces direct, professional responses without filler or pleasantries. Setting a custom prompt overrides these defaults entirely. Provide a custom prompt to define your agent's personality, tone, and communication style. This prompt guides how the agent interacts with users. When you set a custom prompt, the **Response length**, **Tone**, and **Emojis** settings below are disabled. Your custom prompt must specify all personality characteristics including verbosity, tone, and emoji usage. The agent will not reference the standard settings. **Example prompts:** **IT Support Agent:** You are a helpful IT support agent. Be professional and technical but friendly. Keep responses concise and to the point. Use a business tone with minimal emojis. When explaining technical concepts, use clear language that non-technical users can understand. Always be patient and empathetic with frustrated users. **HR Agent:** You are a compassionate HR assistant. Use a warm, supportive tone with moderate emoji usage to create a welcoming atmosphere. Keep responses balanced in length, providing enough detail to be helpful while respecting people's time. Be empathetic and understanding, especially when handling sensitive topics like benefits, time off, or workplace concerns. **RevOps Agent:** You are a strategic Revenue Operations assistant. Communicate in a business-casual tone that's professional yet approachable. Use verbose responses when explaining complex processes or data, but stay concise for quick questions. Include minimal emojis to maintain professionalism. Focus on being clear, data-driven, and solution-oriented in your communication. Focus on the agent's character and manner of speaking. Avoid including instructions about tools or processes, which belong in rules. Select the desired length of the agent's responses: Concise, Balanced, or Verbose. This setting is ignored if a custom prompt is configured. Choose the tone of the agent's communication: Business, Casual, or Humorous. This setting is ignored if a custom prompt is configured. Set whether the agent should use emojis in its responses and how often: None, Minimal, Moderate, or High. This setting is ignored if a custom prompt is configured. *** ## Slack behavior Configure how your agent responds in Slack channels and threads. Define how the agent responds to messages in Slack channels: * **Respond to all messages**: The agent replies to every message in the channel * **Respond to mentions only**: The agent only replies when directly mentioned * **Respond to requests only**: The agent only replies to messages detected as requests for assistance Define how the agent responds to messages in a Slack thread: * **Respond to all messages**: The agent replies to every message in the thread * **Respond to mentions only**: The agent only replies when directly mentioned * **Smart (classify intent)**: The agent uses an AI classifier to determine whether a message is directed at it before responding. Side-conversations, acknowledgments, and human-to-human exchanges are skipped. When the agent has asked a question (for example, while collecting a form field) and the user replies with an `@mention` such as a manager's name, the classifier treats the message as an answer to the agent rather than a side-conversation. **Default:** Smart (classify intent). Channel and threaded message settings do not apply to Slack direct messages (DMs) with the agent. Since a DM is a private 1:1 conversation, the agent always responds to every message in a DM, including replies in DM threads. Let the agent keep working a ticket after it has been published (escalated to humans) without needing an `@mention` on every message. **Default:** Disabled When disabled (the default), the agent stays in its restricted post-publish mode on a published ticket. It can still update ticket fields when a message explicitly `@mentions` it, but it does not respond to conversation on its own. When enabled, the agent treats messages on a published ticket the same way it treats messages on an open one. It applies the normal Channel messages and Threaded messages gating and can respond, run rules, and take actions without being mentioned. Use this to unlock message-driven behavior after escalation, such as auto-closing a ticket when a teammate replies "resolved" or editing ticket fields on request. This setting only affects published tickets. Unpublished tickets are handled exactly the same either way. **How it interacts with Threaded messages:** * **Smart (recommended):** The classifier still decides whether each message is directed at the agent, so it holds back when a human is actively working the ticket and only steps in when a message looks like it needs the agent. * **Respond to mentions only:** The agent still waits for an `@mention` before replying, but the mentioned reply runs the full agent (rules, tools, responses) instead of the restricted post-publish mode. * **Respond to all messages:** This toggle is disabled in the UI while Threaded messages is set to Respond to all, because the agent would reply to every thread message including a teammate's own updates. If you switch Threaded messages to Respond to all while the toggle is on, Ravenna turns the toggle off for you. Available in both the Slack and Microsoft Teams integrations. The agent reads files that users share in Slack as part of the conversation. When a user uploads a document with their message, the agent extracts the document's text and uses it to answer questions, fill forms, or route the ticket. **Supported file types:** * PDF documents * Images (screenshots, photos) * Text and document files shared in Slack **How it works:** * When the agent detects a file share, it briefly defers its response so Slack can finish processing the upload. This prevents the agent from replying before it can read the attachment. * The agent then extracts text from the file and treats its contents as additional context for the message. * Extracted document content is used the same way as the user's typed message: for answering questions, prefilling form fields, and selecting rules. **Example use cases:** * A user pastes a screenshot of an error and asks "what's going on?" The agent reads the screenshot and references it in its answer. * A user attaches a vendor invoice or contract PDF when filing a request. The agent extracts key fields to prefill the form. * A user shares an exported log file. The agent summarizes the file before creating the ticket. File contents are processed at message time and used as part of the agent's conversation context. They are not automatically added to your knowledge base. To make a document permanently searchable by the agent, ingest it into a [knowledge folder](/documentation/automate/knowledge/overview). ### Response elements Configure UI elements that appear in the agent's Slack responses. These settings control visual components displayed alongside AI answers when the response includes citations from your knowledge base. Display the source link in agent responses. When enabled, users see links to the knowledge base articles or documents that the AI used to generate its answer. **Default:** Enabled This helps users verify information and explore related documentation. Display thumbs up and down feedback buttons below AI responses. When enabled, users can indicate whether the response was helpful. **Default:** Enabled Feedback data helps you identify knowledge gaps and improve your documentation. Display a button that allows users to create a support ticket directly from the AI response. This is useful when the AI answer doesn't fully resolve the user's question and they need human assistance. **Default:** Disabled The create ticket button only appears when the ticket has not already been published. ### Create ticket on negative feedback Automatically create a support ticket when users react with thumbs down to an agent response. **Enabled by default** to ensure negative feedback receives timely follow-up. This setting only appears when **Show feedback buttons** is enabled. *** ## Auto-respond Enable automatic AI responses for tickets created from email and integration sources (Jira, Linear, GitHub). When enabled, the agent automatically responds to new tickets using its assigned knowledge bases. Enable automatic responses to tickets created from inbound emails. The agent analyzes the email content and provides a response based on its knowledge bases. Enable automatic responses to tickets created from integrations such as Jira, Linear, and GitHub. The agent analyzes the ticket content and provides a response based on its knowledge bases. Set a delay (0-300 seconds) before the agent responds. This allows time for additional context to be added to the ticket before the AI responds. Options include: * Immediate (0 seconds) * 5 seconds * 10 seconds * 30 seconds * 1 minute * 2 minutes * 5 minutes Enable automatic ticket creation when all required form fields are pre-filled by the agent, without requiring user review. **Default:** Enabled When enabled (default), the agent bypasses the form review step and creates the ticket immediately if all required fields have been provided. When disabled, users are shown a pre-filled form to review and submit manually. If some required fields are missing, the form is still shown to the user with valid prefills so they can complete the remaining fields manually. Enable this setting when you want a faster, more streamlined experience and trust the agent to accurately fill in form fields based on the conversation context. Auto-submit is disabled for private forms regardless of this setting. Private forms always display the form UI so users can enter sensitive information directly. Prefilled values are validated before auto-submit. If the agent makes a mistake, it retries with corrected values instead of silently dropping the field. If the agent cannot provide a definitive answer, the ticket will be tagged with `ai-unresolved` for human follow-up. *** ## Conversational form filling Enable conversational form filling to let the agent collect form field values through natural conversation rather than presenting a form UI. The agent asks for each field one at a time, then presents the completed form for review once all required values are collected. Toggle this setting on to switch forms from the standard form to conversational collection. The agent prompts users for each field individually in chat, then presents the completed form for review. **Default:** Disabled Set the maximum number of fields a form can have to use conversational mode. Forms with more fields than this threshold will display the standard form instead. **Default:** 3 fields Use a lower threshold for complex forms where users benefit from seeing all fields at once. Increase the threshold for simple forms with few required fields. The threshold is compared against the maximum number of fields a single user path can reveal, not the raw total. For forms with conditional (dependent) fields, only the longest visible branch counts. For example, take a Laptop Request form with 10 declared fields where any one user only ever sees 6 — top-level fields plus a single Mac or Windows branch. Ravenna treats it as a 6-field form for threshold purposes. This keeps branchy forms eligible for conversational mode even when the total field count is large. If a form exceeds the threshold, the agent falls back to presenting the standard form regardless of the conversational form filling setting. ### How conversational form filling works 1. User makes a request that triggers a form (for example, reporting an issue or requesting access) 2. Agent identifies the required form fields and checks whether the form qualifies for conversational mode (field count is at or below the threshold) 3. Agent extracts any field values already mentioned in the conversation 4. For remaining required fields, the agent asks for each value one at a time 5. For forms with conditional fields, dependent fields are skipped until their parent field has a matching value 6. User provides values through natural language responses 7. Once all required fields are collected, the agent presents the form for review (or auto-submits if auto-submit is enabled) Private forms always use the standard form UI regardless of conversational form filling settings. This ensures sensitive information is collected through the secure form interface rather than in a channel conversation. ### Which mode to use Best for straightforward forms with few required fields, like a password reset that only needs a username and urgency level. Best for forms where users benefit from seeing all fields at once, such as access requests with multiple approvers or file attachments. When forms include user selection fields, the agent uses [User Lookup](/documentation/automate/agents/configure#user-lookup) to resolve names to user IDs during conversational collection. For user group selection fields, the agent uses [Group Lookup](/documentation/automate/agents/configure#group-lookup) to resolve group names to IDs. For DATE fields, the agent resolves relative expressions like "tomorrow", "next Monday", or "in 2 weeks" to concrete `YYYY-MM-DD` values automatically. Dates are resolved in UTC, so for requests near midnight the resolved day may be off by one. ## Personality model Agent personality controls the communication style, not the behavior. Personality is separate from rules. ### Default communication style All agents have a built-in communication style that applies when no custom prompt is set: * Responses are direct and complete, without preamble, closers, or sign-offs * The agent does not echo or paraphrase the user's question before answering * Responses avoid sycophantic openers ("Certainly!", "Of course!", "Great question"), filler phrases ("It's worth noting", "utilize", "leverage", "delve"), stiff transitions ("Additionally", "Furthermore", "Moreover"), canned closers ("Hope this helps!", "Feel free to..."), and unprompted follow-up invitations Formatting (bullets, headers, and lists) is unrestricted. A custom prompt overrides these defaults entirely. ### Configuration modes Two configuration modes exist: 1. **Structured settings** (Response length, Tone, Emojis): Simple preset values. Response length options are Concise, Balanced, or Verbose. Tone options are Business, Casual, or Humorous. Emoji options are None, Minimal, Moderate, or High. 2. **Custom prompt**: A free-text personality prompt that overrides all structured settings. When a custom prompt is set, the structured settings are completely ignored. **Key distinction:** Personality prompts define how the agent communicates (tone, verbosity, style). Rules define what the agent does (actions, tools, resource references). Keep these separate. Do not include behavioral instructions in the personality prompt, and do not include personality guidance in rules. *** ## Slack behavior model ### Channel response modes The agent's response behavior in Slack channels is set to one of three modes: | Mode | Behavior | Best for | | ------------------------ | -------------------------------------------------------------- | ---------------------------------------------------------------- | | Respond to all messages | Agent replies to every message in the channel | Dedicated support channels with low noise | | Respond to mentions only | Agent replies only when directly @mentioned | Channels with mixed conversation and support requests | | Respond to requests only | Agent replies only to messages detected as assistance requests | General channels where the agent should stay quiet unless needed | ### Thread response modes Thread behavior has three modes: | Mode | Behavior | Best for | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | | Respond to all messages | Agent replies to every message in the thread | Dedicated support threads where all messages need a response | | Respond to mentions only | Agent replies only when directly @mentioned in the thread | Threads where humans and agents collaborate | | Smart (classify intent) | Agent uses an AI classifier to determine whether each message is directed at it before responding. Direct @mentions always bypass the classifier, and when the agent is mid-conversation (for example, waiting on a form answer), `@mention`-style replies are treated as answers rather than side-conversations. Default. | Threads with mixed human-to-human and human-to-agent conversation | ### Respond after escalation An opt-in per-agent setting that controls whether an agent keeps engaging on a ticket after it has been published (escalated to humans). Available on Slack and Microsoft Teams. * **Off (default):** On a published ticket, the agent runs in the restricted post-publish mode. It can update ticket fields when an `@mention` explicitly asks it to, but it does not respond to conversation on its own. * **On:** On a published ticket, the agent applies the normal Channel messages and Threaded messages gating and can respond, run rules, and take actions without being `@mentioned`. Unpublished ticket behavior is unaffected either way. Interaction with Threaded messages: * With **Smart**, the classifier still holds the agent back when a human is on the ticket, so the toggle is safe to leave on. This is the recommended pairing. * With **Respond to mentions only**, the agent still waits for an `@mention` before replying, but the mentioned reply runs the full agent instead of mutation-only mode. * With **Respond to all messages**, the toggle is disabled in the UI. Switching Threaded messages to Respond to all while the toggle is on cascades the toggle off. ### Response elements Three optional UI elements appear alongside agent responses in Slack: * **Source links** (default: enabled): Shows links to knowledge base articles used to generate the answer. * **Feedback buttons** (default: enabled): Thumbs up/down buttons for user feedback. When enabled, negative feedback can optionally auto-create a support ticket. * **Create ticket button** (default: disabled): Allows users to create a ticket directly from the response. Only appears when a ticket has not already been published. *** ## Auto-respond model Auto-respond enables the agent to automatically reply to tickets created from non-Slack sources: * **Email auto-respond**: Replies to tickets created from inbound emails. * **Integration auto-respond**: Replies to tickets created from Jira, Linear, GitHub, and other connected integrations. Configuration options: * **Response delay** (0 to 300 seconds): Delays the agent's response to allow additional context to be added to the ticket first. Available presets: 0s, 5s, 10s, 30s, 1m, 2m, 5m. * **Auto-submit form**: When enabled (default), the agent automatically submits the ticket if all required form fields are pre-filled. Prefilled values are validated before submission; if the agent makes a mistake it retries with corrected values. When disabled, the user sees a pre-filled form for review. If required fields are missing, the form is shown to the user with valid prefills so they can complete it. Auto-submit is always disabled for private forms. If the agent cannot provide a definitive answer to an auto-responded ticket, the ticket is tagged with `ai-unresolved` for human follow-up. *** ## Conversational form filling Conversational form filling changes how the agent collects structured data. Instead of presenting a form UI, the agent asks for each field value through natural conversation. ### Activation logic Conversational form filling activates when all four conditions are met: 1. The setting is enabled on the agent. 2. A rule triggers a form. 3. The form's effective field count is at or below the configured field threshold (default: 3). The effective count is the maximum number of fields a single user path can reveal — for forms with conditional (dependent) fields, only the longest visible branch counts, not the raw total. 4. The form is not private. Private forms always use the standard form UI to protect sensitive data. If the form exceeds the threshold or is private, the agent falls back to the standard form UI regardless of the setting. ### Collection sequence 1. The agent identifies all required fields on the triggered form. 2. The agent extracts any field values already mentioned in the conversation. 3. For remaining required fields, the agent asks the user for each value one at a time. For forms with conditional fields, dependent fields are skipped until their parent field has a matching value. 4. For user selection fields, the agent uses User Lookup to resolve names to Ravenna user IDs. 5. For user group selection fields, the agent uses Group Lookup to resolve group names to IDs, respecting any allowlist or source constraints configured on the field. 6. Once all required fields are collected, the agent presents the form for review or auto-submits if auto-submit is enabled. ### When to use each mode | Mode | Best for | Limitations | | -------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | Conversational | Simple forms with few fields (password reset, basic requests) | Not suitable for forms with many fields, file attachments, or complex multi-select options. Always disabled for private forms. | | Standard form | Complex forms, forms with file uploads, forms where users benefit from seeing all fields at once, private forms | Interrupts the conversational flow | *** ## Constraints and gotchas * **Custom prompt overrides all structured settings.** When a custom prompt is set, Response length, Tone, and Emojis settings are completely ignored. The custom prompt must specify all personality characteristics. * **Personality is not behavior.** Keep personality prompts focused on communication style. Tool usage, form selection, and workflow triggers belong in rules, not personality. * **Channel behavior applies per agent, not per channel.** The Slack response mode is set on the agent and applies to all channels the agent is deployed to. * **Form threshold is a hard cutoff.** If a form's effective field count exceeds the threshold, conversational mode does not activate. There is no partial conversational collection. The effective count is the maximum number of fields a single user path can reveal, so deep dependent-field branches do not push otherwise simple forms over the threshold. * **Auto-submit bypasses user review.** Auto-submit form is enabled by default. The agent creates the ticket immediately without showing the form when all required fields are prefilled. Prefilled values are validated before submission, so invalid values are corrected rather than silently dropped. Disable this setting if you want users to always review the form before submission. If required fields are missing, the form is shown to the user with valid prefills instead. * **Private forms always use the standard form UI.** Conversational form filling and auto-submit are both disabled for private forms regardless of agent settings. This ensures sensitive data is collected through the secure form interface. * **Conditional fields in conversational mode.** During conversational collection, the agent respects field dependencies from the form builder. Dependent fields are skipped until their parent field has a matching value. When using the standard form UI, field visibility is controlled by the form builder's built-in conditional logic. * **Relative dates resolve in UTC.** Expressions like "tomorrow" and "next Monday" are resolved to `YYYY-MM-DD` relative to UTC. Near midnight in the user's local time, the resolved date may be off by one day. * **Response delay applies to auto-respond only.** The delay setting affects email and integration auto-responses, not Slack conversations. * **Negative feedback auto-ticket requires feedback buttons.** The "create ticket on negative feedback" option only works when feedback buttons are enabled. # Deploy & monitor Source: https://docs.ravenna.ai/documentation/automate/agents/deploy-monitor Deploy AI agents to Slack channels, test them in a sandboxed Testing Mode, then monitor conversations, results, and feedback to improve responses. Deploy agents to channels and monitor their performance through conversation logs, result categorization, and feedback tracking. Before going live, validate rules, tools, and forms in **Testing Mode** — a sandboxed chat that runs the agent end-to-end without writing tickets or sending messages. *** ## Testing Mode Testing Mode is a sandboxed chat panel for trying your agent without touching production data. The agent runs end-to-end — matching rules, calling tools, and choosing responses — but any action that would write or change something is simulated. No tickets are created and no messages are sent to Slack or Teams. Use Testing Mode to: * Validate a new rule before exposing it to real users. * Check that the right form is presented for a given request. * Confirm knowledge sources are being cited correctly. * Inspect which tools the agent called and what it passed to them. ### Open Testing Mode Navigate to **Agents** in the sidebar and select the agent you want to test. Use the chat panel on the agent page. A yellow **Testing Mode** banner confirms the session is sandboxed. Type a request a real user might send, then submit. The agent responds with the same rules, tools, and knowledge it would use in production. ### Forms and submissions When the agent presents a form, fill it out and submit it from within the chat. The values flow back to the agent so it can continue the turn, just like in production. Form submissions and ticket publishes appear as inline cards so you can verify what would have been created. After a terminal action (publishing a ticket or submitting a form), the session is frozen to mirror real-world behavior. Click **Start new chat** to reset and continue testing. ### Debug each turn Every agent response includes a collapsible **Debug** disclosure below the message. Expand it to inspect: * **Matched rules** — which rules fired for the turn and the reasoning behind the match. * **Tool calls** — every tool the agent invoked, with the input it sent and the output it received. * **Response type** — the classification the agent chose (KB answer, Chat, Asked for info, or Escalated). Use the debug view to diagnose unexpected behavior — for example, the wrong rule matching, a tool being called with bad inputs, or the agent escalating when it had enough knowledge to answer. Testing Mode sessions are client-owned and not saved to **Chat Logs**. To capture a regression for later review, copy the relevant inputs and outputs from the Debug disclosure before resetting the session. *** ## Connections Select which channels the agent should be deployed to. You can add or remove channels at any time after deployment. ### Deploy agents Open your agent's settings page. Locate the **Connections** section. Click **Add Channel** and select the channels where the agent should be active. Save your connection settings to deploy the agent. Agents can be deployed to multiple channels simultaneously. Each channel operates independently with the same agent configuration. Learn about [setting up and managing channels](/documentation/tickets/channels) *** ## Chat logs All interactions between users and the agent are logged and can be reviewed in the Chat Logs section. Monitor agent performance, review conversations, identify knowledge gaps, and track response quality. ### View conversations Access all conversations your agent participates in from the **Chat Logs** tab on the agent's page. Each conversation shows: * **Timestamp**: When the conversation started * **Requester**: User who initiated the conversation * **Channel**: Where the conversation took place * **Agent result**: How the agent categorized the conversation outcome * **Message count**: Number of messages exchanged * **Feedback**: Thumbs up or down reactions received ### Agent results Agent results categorize how the agent ended each conversation. This helps you understand agent behavior patterns and identify areas for improvement. The agent successfully answered the user's question using knowledge base articles or direct information. This indicates the agent found relevant documentation and provided a complete answer. The agent asked the user for clarification or additional information. This occurs when the initial request lacks sufficient detail for the agent to proceed. The agent created a ticket for the request. This happens when the agent escalates to human assistance or when the request requires a structured form submission. The agent provided help or guidance information. This typically occurs when users ask about the agent's capabilities or how to use the system. The agent could not find relevant information to answer the question. This indicates a potential knowledge gap in your documentation or a request outside the agent's scope. The agent engaged in conversational interaction without a specific categorizable outcome. This includes general conversation or exploratory questions. The agent initiated a form-based request process. This occurs when a rule or escalation instruction explicitly directs the agent to show a form. Forms are only shown when rules specifically require them, not based on the agent's judgment about structured information needs. The agent prompted the user to fill in a specific field on a form. This occurs while the agent is collecting structured information one field at a time during a form-based request. The agent detected sensitive information (passwords, API keys, tokens, or credentials) in its response and delivered it as a private DM to the requester instead of in the shared channel. Other participants see a placeholder message indicating a private message was sent. The agent encountered an error during processing. This indicates a technical issue that prevented the agent from completing its response. The agent created a custom ticket type. This occurs when the agent uses a specialized form or ticket template. The conversation was not published or remained in draft state. This typically happens when the agent prepared a response but it was not sent. ### Feedback tracking Track user reactions to agent responses through thumbs up and thumbs down feedback. This data helps identify knowledge gaps and improve agent effectiveness. **View feedback summary:** * Total positive reactions * Total negative reactions * Feedback rate (percentage of responses receiving feedback) * Trending issues (frequent negative feedback patterns) **Filter by feedback:** * View all conversations with positive feedback * View all conversations with negative feedback * View conversations without feedback When **Create ticket on negative feedback** is enabled in agent settings, thumbs down reactions automatically create support tickets for human follow-up. ### Filter chat logs Use the **Filters** button above the chat log list to narrow down conversations. Filters use AND logic, so a conversation must match every active filter to appear. Filter by the result type the agent returned, such as Answered, Clarification, Ticket Created, Missing Knowledge, or Error. Use this to isolate conversations by outcome — for example, view every "Missing Knowledge" result to find knowledge gaps, or every "Error" result to investigate technical issues. Filter conversations by the properties of the ticket the conversation produced. The **Tickets** folder groups all ticket-level filters in one place. Available filters include: * **Title** — filter by keywords in the ticket title * **Description** — filter by keywords in the ticket description * **Status** — filter by ticket status (open, in progress, resolved, closed, or any custom status) * **Priority** — filter by ticket priority * **Assignee**, **Requester**, **Followers** — filter by people on the ticket * **Channel** — filter by the channel the ticket lives in * **Form** — filter by the form used to create the ticket * **Tags**, **Category**, **Ticket Type** — filter by ticket organization attributes * **Custom fields** — filter by any custom field defined on your forms * **Created at**, **Updated at**, **Due date** — filter by date ranges The **Title** and **Description** filters perform substring matches against the ticket's title and description text. Use them to locate conversations tied to tickets about a specific topic — for example, every chat log that produced a ticket with "VPN" in the title. Combine filters to investigate specific patterns. For example: * **Find unresolved escalations**: filter by **Agent Response** = `Ticket Created` and **Tickets → Status** = `open` to surface every escalated ticket still waiting for a human. * **Audit a single team's load**: filter by **Tickets → Channel** = `IT` to see only chat logs that produced tickets in the IT channel. * **Investigate a custom workflow**: filter by **Tickets → Form** = `Access Request` to review every conversation that created an access request. * **Search by topic**: filter by **Tickets → Title** contains `password reset` to find every chat log whose ticket title mentions password resets, or use **Tickets → Description** to match keywords inside the ticket body. Ticket filters apply only to conversations that produced a ticket. Conversations the agent answered directly from the knowledge base will not appear when a ticket-level filter is active. To review knowledge-only conversations, filter by **Agent Response** = `Answered` instead. ### Explain a conversation with Copilot Use **Explain** to ask Copilot why the agent answered, asked, or escalated the way it did. Copilot inspects the run evidence — the response classification, the matched rule and its reasoning, the tools the agent called, the agent's configuration, and any cited documents — and gives a grounded explanation rather than a guess. **Open Explain in two ways:** * **Explain the whole conversation**: open a chat log and select the **Explain** button at the top of the panel. Copilot walks through every turn and the overall outcome. * **Explain a single response**: hover an agent reply in the chat log and select **Explain** on that message. Copilot scopes the explanation to just that turn. **What Copilot covers on the first reply:** * **Outcome** — the overall classification and the single reason the conversation landed there. * **What happened, turn by turn** — one bullet per agent reply, with the classification and a short description of what the agent did. * **Verification** — for Missing Knowledge or escalations, Copilot re-runs a knowledge search to check whether the gap is a real content gap or a retrieval miss. It also notes when a matched rule narrowed the agent's knowledge lookup to specific documents or folders, which can make an escalation correct even though relevant content exists elsewhere. * **Takeaway** — what this means for you, such as whether the escalation was justified or whether a rule or knowledge gap may need attention. Follow-up questions stay conversational and answer only what you ask. Copilot reuses the run context it already loaded instead of restating the full breakdown. Explain is read-only — it analyzes and recommends, but it cannot edit agents, rules, or knowledge from inside the chat. When you ask Copilot to make a change (for example "update this rule" or "fix the escalation instructions"), it surfaces a one-click button that carries the conversation into the full Copilot panel, which has the tools to apply the change. ### Analyze conversations Use chat logs to: Review conversations with "Missing Knowledge" results to discover missing documentation. Add these topics to your knowledge base to improve future responses. Analyze conversations where the agent asked for clarification or created tickets unnecessarily. Update rules to handle these scenarios more effectively. Track how often the agent escalates to human assistance. High escalation rates may indicate unclear instructions or insufficient knowledge base coverage. Compare agent results over time to measure improvement. Track metrics like answer rate, escalation rate, and feedback trends. After updating agent configuration, rules, or knowledge base content, review chat logs to confirm improvements in agent responses. *** ## Best practices Check chat logs weekly to stay informed about agent performance and identify emerging issues early. Review negative feedback promptly to understand user frustrations and address gaps in agent capabilities or knowledge base content. Monitor agent result distribution over time. Sudden changes in result patterns may indicate issues with agent configuration, knowledge base updates, or changing user needs. Use chat log insights to continuously improve agent configuration, rules, escalation instructions, and knowledge base content. Establish target metrics for agent performance: * Minimum answer rate (percentage of "Answered" results) * Maximum escalation rate (percentage of "Ticket Created" results) * Target feedback rate (percentage of responses receiving feedback) * Minimum positive feedback ratio (positive reactions vs negative reactions) ## Deployment model Agents are deployed to channels. Key behaviors: * An agent can be deployed to multiple channels simultaneously. * Each channel can have at most one agent. * All channels sharing an agent use the same configuration (rules, knowledge, escalation instructions, personality). * Adding or removing channel connections takes effect immediately. *** ## Result type reference Every agent conversation is classified with a result type. These types indicate what the agent did and help diagnose performance issues. | Result type | What happened | Diagnostic signal | | ----------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | Answered | Agent answered using knowledge base content | Successful resolution. High rate indicates good knowledge coverage. | | Clarification | Agent asked for clarification | May indicate vague user requests or rules that need more specific triggers. | | Ticket Created | Agent created a ticket or escalated | Expected for requests requiring human help. High rate may indicate knowledge gaps or overly aggressive escalation. | | Help | Agent explained its own capabilities | Users are unsure what the agent can do. Consider updating channel messaging or agent introduction. | | Missing Knowledge | Agent could not find relevant information | Knowledge gap. Add documentation covering this topic. | | Conversational | General conversation without a specific outcome | Casual interaction. Not necessarily a problem. | | Form Response | Agent presented a form based on a rule | Expected when rules direct form creation. | | Form Field | Agent prompted the user to fill a specific form field | Expected during multi-step form intake. | | Sensitive | Agent detected and handled sensitive information | Security measure activated. Review to confirm correct detection. | | Error | Agent encountered a processing error | Technical issue. Investigate logs for root cause. | | Custom Ticket | Agent created a ticket with a specialized form | Expected for custom form workflows. | | Unpublished | Response was prepared but not sent | May indicate a system issue or interrupted conversation. | *** ## Feedback signals User feedback (thumbs up/down) provides direct signal about response quality: * **Positive feedback** indicates the response was helpful and accurate. * **Negative feedback** indicates a problem. Common causes: incorrect information, missing information, wrong form selected, unhelpful response, or the agent should have escalated instead. When "Create ticket on negative feedback" is enabled (default), negative reactions automatically generate a support ticket for human review. This creates a built-in feedback loop. **Feedback rate** (percentage of responses receiving any feedback) indicates user engagement. Very low feedback rates may mean users are not aware of the feedback mechanism or do not find it convenient. *** ## Debugging patterns ### High "Missing Knowledge" rate The agent frequently cannot find relevant information. * **Likely cause:** Knowledge base gaps. The topics users ask about are not covered in connected knowledge folders. * **Fix:** Review "Missing Knowledge" conversations to identify missing topics. Add documentation to the knowledge base. Verify the correct knowledge folders are connected to the agent. ### High escalation rate The agent creates tickets or escalates to humans more often than expected. * **Likely causes:** Escalation instructions are too aggressive, rules do not cover common scenarios, or knowledge base coverage is insufficient. * **Fix:** Review "Ticket Created" conversations. If the agent could have answered from knowledge, add or improve knowledge content. If the agent escalated due to unclear rules, refine rule trigger conditions. If escalation instructions tell the agent to escalate too eagerly, adjust the thresholds. ### Frequent "ask user" responses The agent asks for clarification too often. * **Likely cause:** Rules lack specificity, so the agent cannot determine intent from the initial message. Alternatively, users are sending very short or ambiguous requests. * **Fix:** Make rule trigger conditions more specific. Add examples of common phrasings to rules. Consider whether conversational form filling might help collect structured data. ### Negative feedback on knowledge answers Users give thumbs down on answers that cite knowledge base articles. * **Likely causes:** Knowledge base content is outdated, inaccurate, or insufficient. The agent may also be citing the wrong article. * **Fix:** Review the cited articles for accuracy. Update or remove outdated content. Check if the agent's knowledge folder connections are correct. ### Wrong form selected The agent presents the wrong form for a user's request. * **Likely cause:** Rule trigger conditions overlap, causing the agent to match the wrong rule. Or a rule's trigger condition is too broad. * **Fix:** Make trigger conditions more distinct across rules. Ensure each form-related rule has specific, non-overlapping trigger criteria. *** ## Upgrade an agent Agents are versioned. When a newer agent version is available, the **Upgrade** action appears on each agent that's still on an older version — both in the agents list (row actions) and in the header of the agent's settings page. Upgrading creates a **new, upgraded copy** of the agent. The new copy is not connected to any channels or queues, so it doesn't respond anywhere until you connect it. Your current agent keeps running unchanged, which lets you review and test the upgrade before switching traffic over. ### When to upgrade * A newer agent version unlocks behavior or capabilities the older version doesn't support. * You want to consolidate on the current runtime so future improvements apply to your agent. * You'd like to retire an older agent but want to validate the upgraded copy in parallel first. ### Run the upgrade From the **Agents** list, open the row actions menu on an eligible agent and select **Upgrade**. You can also open the agent's settings page and click **Upgrade** in the header. The modal prefills a suggested name (the original name with an "Upgraded" suffix). Edit it if you'd like a different name for the new copy. The **Rules** section lists every rule attached to the agent and how it will be carried over: * **Unchanged** — the same rule is re-attached to the upgraded agent. Edits to the rule continue to affect both agents. * **Migrated** — a new copy of the rule is created on the upgraded agent because it needs changes to work on the new version. The original rule stays as-is on the original agent. The **Tool changes** section lists tools that don't exist in the new version but have a known equivalent (or are safe to remove). These are handled for you. Rules affected by an automatic change are flagged for review on the upgraded agent. The **Choose replacements** section appears when one or more tools used by the agent aren't available in the new version and don't have a known equivalent. For each one, pick a replacement tool from the list or select **Remove (no replacement)** to drop it. You can't complete the upgrade until every unavailable tool has a decision. Click **Upgrade**. Ravenna creates the upgraded copy and opens it so you can review the configuration. Add the upgraded agent to the channels and queues you want it to handle, then remove those connections from the original agent when you're ready to cut over. Only one upgraded copy of a given agent can exist at a time. If an upgraded copy already exists, finish reviewing or delete it before starting another upgrade. *** ## Optimization recommendations * **Track result distribution weekly.** A sudden shift in result types (e.g., spike in "Missing Knowledge" or "Error") signals a configuration or content issue that needs investigation. * **Review negative feedback conversations first.** These are the highest-signal data points for improving agent quality. * **Use "Answered" rate as a primary metric.** This directly measures how often the agent successfully resolves requests without human intervention. * **Monitor escalation rate as a secondary metric.** Some escalation is expected and healthy. The goal is not zero escalation, but appropriate escalation. * **After making changes, compare before and after.** Check whether rule updates, knowledge additions, or escalation instruction changes actually improved the result distribution. # Agents Source: https://docs.ravenna.ai/documentation/automate/agents/overview Deploy custom AI agents to Slack channels and triage flows to answer questions, classify tickets, and resolve common requests automatically. ![Overview](https://d1kzozfjh72w00.cloudfront.net/documentation/screenshots/platform/agents/hero.webp) Deploy custom AI agents into your channels to automate support requests, answer questions, and route tickets. Configure agents using natural language prompts to define behavior, integrate with external tools, and access your knowledge base. Agents handle instant responses, intelligent ticket routing, and workflow automation across Slack, email, and integrated systems. ## What agents can do Use your knowledge base to respond to questions with accurate, sourced answers Create tickets with specific forms, collecting structured information from users Run actions through integrated tools like Fleet, HubSpot, Okta, and Jamf Route tickets to the right team and escalate complex requests to human agents Work in Slack, email, and integrated systems like Jira, Linear, and GitHub Automatically send passwords, API keys, and credentials as private DMs instead of in shared channels Detect where each message arrived from and avoid telling users to post in a channel they're already in ## How agents learn Define agent behavior through natural language rules, connect knowledge folders for accurate answers, configure escalation instructions for handling complex requests, and integrate external tools for specialized actions. *** ## Agents vs workflows Agents and workflows both automate work, but they fit different situations. | | Agents | Workflows | | ---------------------- | ------------------------------- | -------------------------------------- | | **How they run** | Conversational, real-time | Background automation | | **What starts them** | User messages | Events, schedules, or manual triggers | | **How you build them** | Natural language rules | Visual builder with steps and branches | | **User interaction** | Interactive dialogue with users | No interaction during execution | ### Using both together Agents and workflows both automate work, but they run independently. Agents handle the conversation (collecting information, answering questions, classifying, submitting forms). Workflows handle event-driven backend processing (provisioning, approvals, external system sync). Agents cannot trigger workflows directly. Hand off through ticket state instead: have the agent submit a form, set a category, apply a tag, or change the status, and configure a workflow to fire on that ticket event. Learn more about [workflows](/documentation/automate/workflows/overview) *** ## Getting started Follow the step-by-step guide to create, configure, and deploy an AI agent Create agents from the **Agents** page in your workspace. Each agent requires rules that define its behavior, knowledge sources for answering questions, and channels for deployment. ## System overview An agent is a conversational AI assistant deployed to one or more channels. It processes user messages in real time and responds using four capability layers: 1. **Rules** define behavior for specific scenarios using natural language instructions. Each rule tells the agent when to activate and what to do, referencing Ravenna resources with `@` mentions. 2. **Knowledge** provides the agent with searchable documentation. The agent retrieves relevant articles to answer questions with sourced responses. 3. **Escalation instructions** define fallback behavior when the agent cannot resolve a request. Without custom instructions, the agent follows default escalation logic. 4. **Tools** extend the agent with actions from built-in Ravenna capabilities and third-party integrations (Fleet, HubSpot, Jamf, etc.). These layers compose together: a single conversation may involve checking knowledge, executing a tool action, filling a form via a rule, and escalating if the result is insufficient. *** ## Agents vs workflows | | Agents | Workflows | | -------------------- | ------------------------------------------------------------ | ---------------------------------------------------------- | | **Execution** | Conversational, real-time, synchronous | Background, asynchronous | | **State** | Stateless single-turn responses within a conversation thread | Multi-step with wait states, approvals, delays | | **Triggers** | User messages in connected channels | Events and schedules | | **Branching** | Linear rule matching based on user intent | Conditional paths, parallel execution, converging branches | | **External systems** | Tool calls within conversation | Native integration actions, HTTP requests | **Use agents when you need:** conversational information gathering, interactive dialogue, real-time question answering, simple ticket creation, single-action tool calls. **Use workflows when you need:** approval gates, parallel execution across systems, scheduled automation, wait states (for messages, approvals, inactivity), multi-step orchestration with error handling. *** ## Agent-workflow integration Agents cannot trigger workflows directly. To hand off from a conversation to a workflow, use ticket state as the bridge: * **Submit a form.** The agent collects details with `@Form Name` and submits it on the ticket. Configure a Form Submitted workflow to run the backend processing. * **Set a category.** The agent classifies the request with `@Set Category`. Configure a Category Assigned workflow to route or automate from there. * **Apply a tag or change status.** The agent uses `@Set Tags` or `@Set Status`. Configure a Tags Changed or Status Changed workflow to react. * **Publish a ticket.** The agent creates a ticket in the appropriate queue. Configure a Ticket Created workflow (filtered by queue, category, or form) to take it from there. The agent handles the conversation; a workflow triggered by the resulting ticket event handles the execution. *** ## Common patterns **IT support agent:** Rules for password resets, software access requests, and hardware issues. Each rule references a specific form via `@Form Name`. Knowledge folders provide self-service answers. Tools like Fleet or Jamf enable device lookups during conversation. Escalation instructions route unresolvable issues to human agents. **HR support agent:** Rules for benefits questions, time-off requests, and onboarding. Knowledge folders cover policy documents. Forms collect structured request data. Workflows handle multi-step processes like onboarding provisioning. **Multi-tool lookup:** A single rule can chain multiple tool calls. For example: use `@Look up device with Fleet` to get device info, then `@Run query with Fleet` to check diagnostics, then analyze results and provide troubleshooting steps. The agent executes tools sequentially within the conversation. **Agent-to-workflow handoff:** The agent collects information conversationally (application name, business justification, manager name) and submits `@Form - Software Access Request` on the ticket. A Form Submitted workflow then handles approval routing, provisioning, and notification steps that require background execution. *** ## Constraints and gotchas * **One agent per channel.** Each channel can have at most one agent assigned. The same agent can be deployed to multiple channels. * **Explicit resource access.** Agents do not automatically have access to all forms, workflows, or tools. Resources must be granted via `@` mentions in rules or through the knowledge configuration. * **Single rule selection.** The agent selects only the single best matching rule per request, preferring the most specific match over broader ones. Keep rules distinct for predictable behavior. * **Knowledge scope.** The agent only searches knowledge folders explicitly connected to it. It cannot access knowledge from other agents or unconnected folders. * **Tool availability.** Integration tools require the corresponding integration to be installed and connected. If an integration is disconnected, its tools become unavailable. * **Channel behavior modes.** Slack response behavior (all messages, mentions only, requests only) is configured per agent and applies to all channels that agent is deployed to. # AI trust & privacy Source: https://docs.ravenna.ai/documentation/automate/agents/trust-privacy How Ravenna AI agents handle your data: encryption, model provider policies, training opt-outs, audit logs, and admin controls over AI features. Ravenna AI agents process your data to answer questions, analyze tickets, and automate workflows. All AI processing uses enterprise-grade security with no training on your data. All data encrypted in transit and at rest. AI model providers (Anthropic, OpenAI) do not train on your data or retain prompts and responses. SOC 2 Type II certified. Workspace admins control which channels have AI agents, restrict knowledge base access, and review AI usage logs. Users can request AI not respond to their messages. AI responses cite knowledge base sources. Conversation logs help you monitor quality and accuracy. Clear limitations documented to set appropriate expectations. *** ## Understanding AI processing ### How Ravenna uses AI AI features automate support tasks and provide intelligent assistance: * **Answer questions** using your knowledge base articles and documentation * **Create tickets** with pre-filled forms based on conversation context * **Trigger workflows** to automate approval processes and provisioning * **Classify requests** to route tickets to appropriate teams * **Generate insights** from ticket patterns and trends * **Execute tool actions** through integrated services like Fleet or HubSpot ### What data is processed AI features process data necessary to provide intelligent responses: **Ticket data:** * Ticket titles, descriptions, and comments * Ticket metadata (status, priority, assignee) * Historical ticket patterns and resolution data **Knowledge base content:** * Articles and documentation you've connected to agents * Document metadata and structure **Conversation data:** * User messages in connected Slack channels * Message context and thread history * User mentions and reactions **Integration data:** * Tool execution results from connected integrations * External system data accessed through tool actions Only data explicitly connected to agents (through knowledge bases, channels, or tool permissions) is processed by AI. Agents cannot access data outside their configured scope. ### Data flow AI processing follows a secure data flow: 1. **User sends message** in Slack or creates ticket 2. **Agent retrieves context** from configured knowledge bases and conversation history 3. **Data sent to AI model** (Anthropic Claude, OpenAI, or Google Vertex AI) with relevant context 4. **Model generates response** using provided context without accessing external data 5. **Response delivered** to user with citations to knowledge base sources 6. **Conversation logged** in Ravenna for monitoring and debugging AI models process data in real-time and do not retain your data after generating responses. All API calls use encrypted connections. ### Sensitive information handling When an agent's response contains sensitive information like passwords, API keys, tokens, or credentials, the agent automatically sends that content as a private direct message instead of posting it in the shared channel. The shared channel displays a placeholder message indicating that a private message was sent. Other participants in the thread do not see the sensitive content. The requester receives an ephemeral DM in Slack containing the actual sensitive information. This keeps credentials and secrets visible only to the person who requested them. Ephemeral secret DMs are Slack-only today. The Microsoft Teams integration does not deliver secrets via DM in the current beta. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview) for beta limitations. Agents send private messages in two situations: * **Automatic detection:** The agent recognizes that its response contains passwords, API keys, tokens, connection strings, or other secrets from your knowledge base * **User request:** The user explicitly asks for a private or DM response You can also configure agents to send private messages for specific scenarios using rules. *** ## Data protection ### Security measures All data encrypted in transit using TLS 1.3 and at rest using AES-256 encryption Role-based permissions control AI feature access at workspace and channel levels Complete audit trail of AI interactions, tool executions, and configuration changes SOC 2 Type II certified with GDPR and CCPA compliance measures ### Data retention **Conversation logs:** * Stored in Ravenna for debugging and quality monitoring * Retained according to your organization's data retention policy * Can be exported or deleted upon request **AI model provider data:** * Prompts and responses not retained by model providers * No training on your data by Anthropic, OpenAI, or Google * API calls processed in real-time without storage **Knowledge base content:** * Stored in Ravenna and synchronized with connected sources * Not sent to AI models unless explicitly referenced by agents * Removed when knowledge base connection is deleted ### Data processing agreements Ravenna maintains Data Processing Agreements (DPAs) with AI model providers: * **Anthropic** (Claude AI models) * **OpenAI** (GPT models) * **Google** (Vertex AI) These agreements ensure data is processed securely and in compliance with privacy regulations including GDPR, CCPA, and other regional requirements. DPAs specify that providers do not train models on your data or retain data after processing. Review the full [Ravenna Privacy Policy](https://ravenna.ai/privacy) for complete details on data handling and compliance *** ## Control & permissions Configure AI features at multiple levels to control data access and agent behavior. Workspace admins control AI features for the entire workspace: * Enable or disable AI agents globally * Configure which channels have AI agents deployed * Restrict knowledge base access to specific agents * Review AI usage logs and conversation history * Configure auto-respond settings for email and integration tickets * Manage tool permissions for agent integrations Each channel can have independent AI configuration: * Deploy specific agent or no agent * Connect distinct knowledge base folders * Configure custom escalation instructions * Set channel-specific response behavior * Control which rules apply to the agent Individual users have privacy controls: * See which AI features are active in their channels * Request AI not respond to their messages * Provide feedback on AI responses (thumbs up/down) * Request data deletion for their conversations * View AI response sources and citations Changes to agent configuration, knowledge base connections, and permissions are logged in audit trails accessible to workspace admins. *** ## Responsible AI usage ### Limitations AI agents have limitations you should understand before deployment: **Known limitations:** * May generate incorrect information or hallucinate facts not present in knowledge bases * Cannot access real-time external data without configured tool integrations * Limited by quality and completeness of connected knowledge base content * Cannot perform actions requiring human judgment, compliance review, or legal interpretation * May misinterpret ambiguous requests or questions lacking sufficient context * Cannot guarantee 100% accuracy even when citing knowledge base sources Configure escalation instructions to route complex, sensitive, or ambiguous requests to human agents. Monitor chat logs to identify patterns requiring improved knowledge base content or rule refinement. ### Best practices Audit connected knowledge bases to ensure they don't contain sensitive information you don't want AI to access. Remove outdated or incorrect documentation that could lead to wrong answers. Keep knowledge base content current and accurate. Configure agents to escalate sensitive requests (HR issues, security incidents, legal questions) to humans. Define escalation criteria in agent instructions. Test escalation behavior before full deployment. Review conversation logs regularly to assess response quality. Track negative feedback patterns to identify knowledge gaps. Use agent results to measure performance and identify improvement opportunities. Deploy agents to small channels or pilot groups initially. Expand gradually as you validate response quality and refine configuration. Test thoroughly before enabling auto-respond features. Train your team on AI capabilities and limitations. Set appropriate expectations about what agents can and cannot do. Provide clear guidance on when to request human assistance. Keep documentation current and comprehensive. Add articles addressing questions that generate "Not found response" results. Update content when product features or policies change. *** ## Support & compliance ### Contact information For questions about AI trust, privacy, or data processing: * **Privacy inquiries**: [privacy@ravenna.ai](mailto:privacy@ravenna.ai) * **Security questions**: Contact your account manager * **Data processing agreements**: Request through your account manager * **Privacy policy**: [ravenna.ai/privacy](https://ravenna.ai/privacy) ### Compliance resources * **SOC 2 Type II report**: Available upon request through your account manager * **Data Processing Addendum (DPA)**: Contact your account manager * **Subprocessor list**: Available upon request through your account manager * **GDPR compliance documentation**: Contact [privacy@ravenna.ai](mailto:privacy@ravenna.ai) ### Data subject requests Users can exercise data privacy rights: * **Access**: Request copy of data processed by AI features * **Deletion**: Request removal of conversation logs and AI-processed data * **Correction**: Request updates to inaccurate information * **Restriction**: Request limits on AI data processing Submit data subject requests to [privacy@ravenna.ai](mailto:privacy@ravenna.ai) with required identification and specifics about the request. # Build automations Source: https://docs.ravenna.ai/documentation/automate/copilot/build-automations Use Copilot to build, edit, validate, and debug Ravenna workflows in plain language with full context about triggers, conditions, and run history. Automations handle repetitive work for you. Instead of manually triaging every ticket, sending the same follow-up messages, or routing requests to the right team, you describe what should happen and Copilot builds a workflow that runs automatically. Describe the automation you want in plain language. Copilot first returns a plan describing the workflow it intends to build and waits for your approval before creating anything. Once you approve, it builds the workflow with the triggers, conditions, approval steps, and multi-step logic you described. When you open Copilot from a workflow page, it automatically has context about that workflow's setup and run history. ### How the plan-and-approve flow works Every workflow build goes through the same two steps. 1. **Copilot returns a plan.** For any request to build a workflow, Copilot summarizes the workflow it intends to create (the trigger, the steps, and any approval or branching logic) and asks whether to build it, adjust it, or cancel. Nothing is created yet. 2. **You approve, and Copilot builds it.** After you confirm, Copilot creates the workflow, configures each step, and validates it. Phrasing your request as an imperative like `Build a workflow that...` does not skip the plan step — that is just how the request is phrased. To have Copilot build without the approval round-trip, give explicit standing approval in the same message, for example `go ahead and build it, no need to confirm` or `create and configure it end-to-end without asking`. Standing approval still does not skip disclosure when part of your request is unsupported (see [Requests with unsupported parts](#requests-with-unsupported-parts)). Building and editing workflows is available to all workspace members. If you cannot access a workflow, check with your workspace admin. *** ## Create workflows Tell Copilot what you want to automate and it generates the workflow with the right trigger, steps, and settings. You can describe a complete workflow in a single message or build it up step by step. ### What Copilot supports * **Triggers with filters**: Choose the event that starts the workflow and narrow it to specific conditions (for example, only run when a ticket is created in the IT Support channel with high priority) * **Conditional branches**: Add steps that follow different paths depending on a condition. For example, check whether a user belongs to a group and take different actions based on the answer * **Approval steps**: Add approval gates where the workflow pauses and waits for someone to approve or deny before continuing * **Passing data between steps**: Use information from one step as input to a later step. For example, use the requester's email from the trigger to look up their manager, then send that manager a notification **Example prompts:** Create a workflow that sends a Slack message to #it-ops when a high priority ticket is created in the IT Support channel Build a workflow that assigns new tickets in the HR channel to the on-call HR specialist Set up a workflow that closes tickets automatically when they have been in Resolved status for 7 days ### Walkthrough: building a simple notification workflow Start with a straightforward workflow to see how the process works before adding complexity. Create a workflow that sends a Slack message to #it-ops when a high priority ticket is created in the IT Support channel Copilot describes the workflow it intends to build — a "Ticket Created" trigger filtered to the IT Support channel and high priority, followed by a "Send Slack Message" step targeting #it-ops — and offers **Build it**, **Adjust the plan**, or **Cancel**. Nothing is created yet. Click **Build it** (or reply with your approval). Copilot then creates the workflow, configures each step's inputs, and validates it. Copilot shows the completed workflow as an interactive card. Click through to the workflow editor to review and publish it. Copilot cannot publish or activate workflows directly. After Copilot builds a workflow, you must open the workflow editor to publish it. ### Walkthrough: building a workflow with conditional branching You can describe workflows with "if this, then that" logic and Copilot sets up the branching for you. Tell Copilot what you want the workflow to do, including the conditions and what should happen in each case. Create a workflow that runs when a ticket is created. Check if the requester is in the "all-employees" Google group. If they are not a member, add them to the group and post a ticket note confirming they were added. If they are already a member, post a note saying no action was needed. Copilot describes the workflow it intends to build: * A "Ticket Created" trigger * A "Check Google Group Membership" step * Two paths: one for members already in the group (posts a note) and one for non-members (adds them and posts a confirmation) It offers **Build it**, **Adjust the plan**, or **Cancel**. Nothing is created yet. Click **Build it**. Copilot creates the workflow, configures each step's inputs using information from earlier steps (like the requester's email from the trigger), and validates it. Copilot shows the completed workflow as an interactive card. Click that to navigate to the workflow and click through steps in the editor to review and make any final adjustments. ### Walkthrough: building a workflow with approval Create a workflow that runs when a Hardware Request ticket is created. If the request is for a MacBook Pro, add me as an approver. If I approve, assign the ticket to the procurement team. If I deny it, close the ticket and post a note explaining why. Copilot describes the workflow it intends to build: a condition that checks the hardware type, an approval step on the matching path, and separate actions for the approved and denied outcomes. It offers **Build it**, **Adjust the plan**, or **Cancel**. Click **Build it**. Copilot creates the workflow, configures all step inputs, and validates it. ### Walkthrough: scheduled Slack reports of ticket data Ask Copilot to send a recurring Slack report of live ticket data (for example, your open tickets each morning, or a team's backlog every Monday). Copilot builds a workflow with a cron-based schedule trigger, queries the tickets you describe, formats the results, and posts them to a Slack DM or channel. You can preview the message before turning the workflow on. Use this when you want raw ticket data on a recurring schedule. For AI-generated summaries of custom dashboard widgets, use [AI Briefs](/documentation/measure/ai-briefs) instead. **Example prompts:** DM me my top 5 open tickets by priority every weekday at 9 AM Every Monday at 8 AM, post a list of tickets in the IT Support channel that have been open for more than 7 days to #it-leads Send me a Slack DM at 5 PM every Friday with all tickets assigned to me that are still in progress Tell Copilot what tickets to include, how often to send them, when to send them, and where to deliver the message. DM me my top 5 open tickets by priority every weekday at 9 AM Copilot describes the workflow it intends to build: * A **schedule trigger** using the cron expression that matches your cadence (for example, weekdays at 9 AM) * A **query tickets** step with the filters you described (assignee, status, priority, channel, age) * A **send Slack message** step targeting the DM or channel you named, with the ticket list formatted for Slack It offers **Build it**, **Adjust the plan**, or **Cancel**. Click **Build it**. Copilot creates the workflow, configures step inputs, wires the ticket query output into the Slack message, and validates it. Copilot runs a dry run against your current ticket data and shows you the exact Slack message the workflow would send. Review the formatting, the ticket selection, and the delivery target. If the preview looks wrong, ask Copilot to adjust it — for example, `Include the requester name`, `Sort by created date instead`, `Send it to #it-leads instead of DMing me`, or `Change the schedule to every weekday at 8 AM`. Once the preview looks right, open the workflow editor to publish it. The workflow then runs on the schedule you set and posts the report to Slack automatically. The Ravenna Slack app must be installed in your workspace, and for channel delivery the Ravenna bot must be a member of the target channel. ### Requests with unsupported parts Some outcomes are configured elsewhere in Ravenna and no workflow step can produce them. When your request mixes a buildable workflow with one of these, Copilot returns a plan for the buildable part and, in the same message, names each unsupported part and where to configure it instead. It does not silently drop the unsupported part, and it does not decline the whole request. Outcomes Copilot cannot build into a workflow: * **SLA policies, response and resolution targets, and breach alerts.** A workflow can trigger on an SLA breach, but no workflow step creates, attaches, or edits an SLA policy — the SLA engine attaches policies to matching tickets automatically. To manage SLA policies from Copilot, ask Copilot directly instead of putting it in a workflow (see [Manage SLA policies](/documentation/automate/copilot/configure-workspace#sla-policies)); you can also configure them in **Settings → SLAs**. * **Access levels, access policies, and entitlements.** Configure them in the Access Requests settings pages. Access Requests owns the eligibility, approval, provisioning, and revocation lifecycle end to end. * **Ticket categories and app activation.** Configure them in workspace settings. **Example: a mixed request.** When a Salesforce access request is submitted, require manager approval, provision the user in Salesforce, and enforce a 4-hour SLA on the ticket Copilot returns a plan for the buildable half — a workflow triggered on the access request that gates provisioning behind manager approval — and, in the same message, calls out that the 4-hour SLA cannot live inside the workflow. Copilot can still create the SLA policy for you (see [Manage SLA policies](/documentation/automate/copilot/configure-workspace#sla-policies)) or you can configure it in **Settings → SLAs**. You approve the plan, Copilot builds the workflow, and the SLA policy is created as a separate step. Standing approval like `go ahead, no need to confirm` skips the approval step for the buildable part but does not skip this disclosure. Copilot still names each unsupported part before building. *** ## Edit and organize workflows Update existing workflows by adding, removing, or changing steps. You can also adjust triggers, update conditions, and organize workflows into collections (folders). **What you can change:** * Add, remove, or reorder steps in an existing workflow * Update trigger events and filter conditions * Change step settings like message content, assignees, or channel targets * Move workflows between collections to keep them organized * Rename workflows and update their descriptions If you are not sure what actions you can add to a workflow, ask Copilot "What workflow actions are available?" and it lists every step type you can use, including integrations like Slack, Google Workspace, and email. **Example prompts:** Add an email notification step after the approval step in the New Hire Onboarding workflow Update the trigger so the IT Alerts workflow only runs for high priority tickets Create a workflow collection called "Notifications" for all alert-related workflows Move the "IT Alerts" workflow to the "Notifications" collection Remove the Slack notification step from the Offboarding workflow *** ## Validate workflows Before turning on a workflow, ask Copilot to check it for common problems like missing triggers, disconnected steps, or invalid references between steps. **Example prompts:** Check the New Hire Onboarding workflow for issues Is the IT Alerts workflow ready to turn on? *** ## Troubleshoot workflow runs When a workflow run fails or does something unexpected, Copilot can pull up the full run history, show you which steps succeeded, which failed, and what the error was. **Example prompts:** Why did the last run of the Onboarding workflow fail? Show me recent runs for the "IT Alerts" workflow *** ## Tips * **Start simple.** If you are new to workflows, begin with a single trigger and one or two steps. You can always ask Copilot to add more steps later. * **Describe the complete workflow in one message** when possible. Copilot handles triggers, branches, and step configuration all at once, which works better than adding pieces one at a time. * **Open Copilot from the workflow page** to give it automatic context about the workflow you are editing or troubleshooting. * **Validate before publishing.** Ask Copilot to check for issues before opening the workflow editor to publish it. * **Skip the plan approval when you don't need it.** Add explicit standing approval to your message (for example, `go ahead and build it end-to-end without asking`) and Copilot builds without the round-trip. A bare `Build a workflow that...` does not count — you have to say you don't want to confirm. Copilot still discloses any unsupported parts before building. * **Ask what actions are available.** If you are not sure what steps you can add, ask "What workflow actions are available?" and Copilot lists them, including available integrations. Learn more about [configuring your workspace](/documentation/automate/copilot/configure-workspace), [workflows](/documentation/automate/workflows/overview), [building workflows](/documentation/automate/workflows/publish), and [workflow collections](/documentation/automate/workflows/collections) # Configure your workspace Source: https://docs.ravenna.ai/documentation/automate/copilot/configure-workspace Use Copilot to set up agents, channels, forms, form fields, SLA policies, and outbound webhooks in your workspace using natural language instructions and chat-driven setup. Use Copilot to set up and manage the parts of your workspace that shape how employees submit requests and how AI responds to them. This includes AI agents, channels, forms, and form fields. These configuration tasks are available to all workspace members. If you cannot access a setting, check with your workspace admin. *** ## AI agents ### Create and configure agents Create new agents and configure how they behave, what they have access to, and how they respond in Slack. Control which channels and knowledge base documents the agent can access. Connecting an agent to specific channels limits it to tickets in those channels. Connecting it to knowledge bases determines what documentation it can reference when answering questions. Connect the IT Support Bot to the IT Support channel and the IT Knowledge Base Configure how the agent responds in Slack channels: * **Respond to all messages** or **only when mentioned** (@agent) * **Thread behavior**: How the agent handles ticket threads (respond when mentioned, always, or never) Set the HR Assistant to only respond when mentioned in the channel but always respond in ticket threads Configure how the agent collects feedback and handles unresolved issues: * **Thumbs up/down buttons** on agent responses * **Auto-create ticket on negative feedback** so unresolved issues get tracked * **Auto-respond** settings for email and integration tickets Turn on thumbs up/down feedback for the IT Support Bot and automatically create a ticket when someone gives negative feedback **Example prompts:** Create an IT Support Bot that responds to all messages in the #it-help Slack channel List all agents in the workspace Show me the settings for the HR Assistant agent #### Walkthrough: setting up a complete agent You can describe an entire agent setup in one message and Copilot creates everything at once. Include the name, purpose, Slack behavior, connected channels and knowledge bases, and any special instructions. Create a new agent called "IT Support Bot" with the description "Helps employees with IT issues." Set the custom prompt to "You are a helpful IT support assistant. Always ask clarifying questions before suggesting solutions." Set escalation instructions to "Create a high priority ticket if the user reports an account lockout or a security concern." Use a friendly tone with emojis. Connect it to the #it-help Slack channel, respond to all messages, and respond in ticket threads when mentioned. Connect it to the IT Support channel and the IT Knowledge Base. Copilot creates the agent with all the settings you specified and shows an interactive card with the agent details. After creating the agent, add rules to define how it handles specific types of requests (see the rules section below). Create a rule for password reset requests and attach it to IT Support Bot ### Agent rules Rules tell an agent how to handle specific types of requests. Each rule has three parts: * **Trigger**: A description of when the rule should kick in (for example, "when someone asks about resetting their password") * **Instruction**: What the agent should do when the rule matches (for example, "walk them through the self-service reset flow, then offer to create a ticket if they still need help") * **Examples**: Sample messages that would match this rule, which help the agent recognize similar requests Rules are not active until they are attached to an agent. You can share a single rule across multiple agents. When a message comes in, the agent evaluates all attached rules and selects the single best match. If multiple rules could apply, the agent picks the most specific one. **Example prompts:** Create a rule for password resets. Trigger: someone asks about resetting their password. Instruction: walk them through the self-service flow at okta.company.com/reset, then offer to create a ticket if that does not work. Examples: "I forgot my password", "How do I reset my login?", "I am locked out of my account." Attach it to the IT Support Bot. Update the PTO policy rule to also mention the company holiday calendar Attach the password reset rule to the IT Support Bot #### Tools and execution policies on rules When you create or update a rule, tell Copilot which integration tools or published [Foundry actions](/documentation/automate/foundry/using-actions) the agent should call when the rule fires. Copilot lists the available tools, wires the ones you select into the rule, and sets a per-tool [execution policy](/documentation/automate/agents/configure#tool-execution-policies): **auto-execute**, **requires confirmation**, or **requires approval**. Use the policy to gate write or destructive actions before they run. Tools wired this way are only available to the agent while the rule is active. Ask Copilot to "list the tools I can give an agent" if you are not sure what is available. Copilot only surfaces tools the workspace has connected. **Example prompts:** What tools can I wire into an agent rule? Update the "Add to Slack group" rule to give the agent the Slack "Add group members" tool, and require approval before it runs. Create a rule called "Deactivate Okta user" that triggers when a manager asks to offboard a teammate. Wire in the Okta "Deactivate user" tool and require approval from the IT leads template before it runs. Add my "Lookup employee" Foundry action to the New Hire Setup rule and let it auto-execute. ### Agent personality Configure how the agent communicates with employees. You can adjust the following settings: * **Custom prompt**: Instructions that shape the agent's behavior and knowledge * **Escalation instructions**: When and how the agent should escalate to a human * **Tone**: Business, friendly, casual, or professional * **Response length**: Concise, balanced, or detailed * **Emoji usage**: None, some, or lots * **Greeting**: The first message the agent sends when a conversation starts **Example prompts:** Update the IT Support Bot to use a professional tone with short responses and no emojis Set escalation instructions for the HR Assistant to immediately create an urgent ticket for any report involving harassment or discrimination Change the greeting for the IT Support Bot to "Hey! What can I help you with today?" You can also use Copilot to [build workflows](/documentation/automate/copilot/build-automations) that automate actions your agents trigger *** ## Channels Set up new channels to organize how employees submit requests. Copilot can also rename existing channels, change emojis, connect Slack request channels and forms, and toggle the ticketing-behavior settings on the channel's settings page. ### Create and rename channels **Example prompts:** Create a channel called "Facilities" with the 🏢 emoji Rename the "IT Help" channel to "IT Support" List all channels in the workspace ### Connect Slack channels Connect a Slack channel as a request channel so messages there feed the Ravenna channel. Copilot lists every Slack channel the Ravenna bot has been invited to, marks any that are already connected elsewhere, and invites the bot automatically when it connects. If the Slack channel you want does not appear, run `/invite @Ravenna` in that Slack channel and ask again. A Slack channel can be a request channel for only one Ravenna channel at a time. If Copilot reports it is already associated, ask Copilot to disconnect it from the other channel first. System channels (Portal, DM) cannot have Slack request channels. If your organization has more than one Slack workspace connected, tell Copilot which workspace to use. **Example prompts:** What Slack channels can I connect to Ravenna? Connect the #it-help Slack channel to the IT Support channel Disconnect #it-help from the IT Support channel ### Connect forms Attach one or more forms to a channel, or remove forms that no longer belong. Disconnecting a form removes it from the channel but does not delete the form itself. **Example prompts:** Add the Laptop Request and PTO Request forms to the IT Support channel Remove the PTO Request form from the IT Support channel ### Channel settings Ask Copilot to toggle any ticketing-behavior setting on the channel's settings page, including: * **Auto-create tickets**: create a ticket for every message in connected request channels * **Ignore internal members**: when auto-create is on, skip messages from workspace members * **Send all tickets to triage channel**: mirror this channel's tickets into the workspace triage channel * **Silent mode**: stop posting ticket mirrors into request channels * **Auto-tag** and **auto-tag create new**: extract tags from messages, and optionally let auto-tagging create new tags * **Emoji updates**, **user actions**, **user emojis**, **granular Slack notifications**, and **CSAT surveys** Some settings depend on others. Disabling auto-create tickets also disables ignore internal members. Disabling auto-tag also disables auto-tag create new. Enabling silent mode disables user actions and granular Slack notifications. Ask Copilot to enable the parent setting in the same request when you turn on a dependent one. **Example prompts:** Turn on auto-create tickets for the IT Support channel and ignore internal members Enable CSAT surveys and silent mode on the HR channel Show me the current settings for the IT Support channel *** ## Forms ### Create a form Create new forms to define how employees submit specific types of requests. After creating a form, add fields to collect the information you need. **Example prompts:** Add a form called "Laptop Request" to the IT Support channel Create a form called "PTO Request" with the description "Submit a time-off request for approval" ### Form fields Add fields to forms to collect structured information when employees submit tickets. Each field can be required or optional. **Supported field types:** * **Text**: Single-line text input * **Text area**: Multi-line text input * **Number**: Numeric input * **Date**: Date picker * **Time**: Time picker * **Boolean**: Checkbox (yes/no) * **Dropdown**: Single-select list of options * **Multi-select**: Choose one or more options from a list * **User select**: Pick a user from the workspace * **User multi-select**: Pick multiple users * **User group select**: Pick a user group * **Tag select**: Pick a tag * **File picker**: File upload * **Priority select**: Priority picker * **Duration**: Duration input * **Timezone select**: Timezone picker **Adding fields:** Add a required dropdown field called "Office Location" with options for NYC, Austin, SF, and London Add a required multi-select field called "Affected Systems" with options for Email, VPN, SSO, and Slack Add a text field called "Additional Details" to the Laptop Request form **Editing fields:** Update existing form fields to change their type, label, options, required status, or ordering. This is useful when a form evolves over time, for example, replacing a free-text field with a structured dropdown. What you can change: * Field label and description * Field type (for example, change text to dropdown, or dropdown to user select) * Options for dropdown and multi-select fields * Whether the field is required * Field ordering within the form * Conditional visibility (parent field and triggering values) * Allowed entities or source integration on entity-picker fields Change the "Office Location" field on the New Hire Setup form from text to a dropdown with options NYC, SF, Austin, and London Make the "Employee Name" field required on the New Hire Setup form Add "Chicago" and "Denver" as options to the "Office Location" dropdown **Removing fields:** Remove a field from a form when it is no longer needed. Removing a parent field also removes any child fields that depend on it, so Copilot asks for confirmation before deleting. Remove the "Old Manager Email" field from the New Hire Setup form Delete the "Preferred Shipping Address" field from the Laptop Request form ### Conditional fields Show or hide a field based on the value of another field on the same form. Use this to keep forms short when only some questions apply to a given request. A conditional field has a **parent** (the field whose value controls visibility) and optionally specific **triggering values** (the parent options that reveal the child). If you do not specify triggering values, the child appears whenever the parent has any value. Conditional fields can be nested — a grandchild can depend on a child that depends on a parent. Describe the relationship in plain language and Copilot wires it up. Create the parent field first so Copilot can reference it. On the IT Support form, show a "Device Type" dropdown with options Laptop, Monitor, and Keyboard only when "Category" is set to Hardware Add a "Reason for Extended Leave" text field to the PTO Request form that only appears when "Leave Type" is set to Medical or Bereavement Make the "Backup Contact" field on the New Hire Setup form a child of "Department" so it only shows for Engineering Remove the dependency on the "Reason for Extended Leave" field so it always shows on the PTO Request form ### Restrict entity-picker fields For fields that pick a user, group, application, or tag, you can restrict which options employees see. This keeps long lists manageable and prevents people from selecting the wrong entity. You can restrict picker fields two ways: * **Allowlist**: A specific set of users, groups, applications, or tags that the field will show. Everything else is hidden. * **Source**: Limit the picker to entities from a single integration, for example only groups from Okta or only users from Google Workspace. On the Access Request form, restrict the "Application" picker to Salesforce, Notion, and Figma On the New Hire Setup form, set the "Team" group picker to only show groups from Okta Clear the allowlist on the "Application" field so all apps are available ### Update a form Rename forms, update their descriptions, and change default settings like priority. **Example prompts:** Rename the "Laptop Request" form to "Equipment Request" Set the default priority for the "Security Incident" form to high Update the description of the "New Hire Setup" form to "Request equipment, access, and onboarding for a new team member" ### Archive or delete a form Retire a form you no longer use. Copilot archives by default, which hides the form from employees but preserves the tickets that were already submitted with it. Ask for permanent deletion only when you are sure — it cannot be undone, and it fails if the form is set as the default for its channel. Copilot always asks for confirmation before archiving or deleting a form. Archive the "Old Laptop Request" form Permanently delete the "Test Form" from the IT Support channel ### Walkthrough: setting up an intake form Build a complete intake form by creating the form first, then adding fields one at a time. Create a form called "New Hire Setup" in the IT Support channel with the description "Request equipment and access for a new team member" Add each field one at a time. Copilot creates them in the order you specify. Add a required text field called "Employee Name" to New Hire Setup Add a required dropdown field called "Department" with options for Engineering, Sales, Marketing, Finance, and People Ops Add a multi-select field called "Equipment Needed" with options for Laptop, Monitor, Keyboard, Mouse, and Headset Show me the fields on the New Hire Setup form *** ## SLA policies Ask Copilot to list, create, edit, and reorder SLA policies in your workspace. Creating, editing, or reordering SLAs is restricted to workspace admins; anyone can ask Copilot to list them. **What Copilot can do:** * List every SLA in the workspace, in priority order, with its targets, alerts, coverage, pause statuses, and business schedule * Create a new SLA with response, resolution, and close targets, alerts, ticket coverage, pause statuses, and an optional business schedule * Update an existing SLA's name, description, coverage, targets, alerts, pause statuses, or schedule * Reorder all SLAs to change which policy applies when several could match the same ticket Copilot does not delete SLA policies. Remove policies from **Settings → SLAs**. ### List and create SLAs **Example prompts:** What SLAs do we have configured? Create a VIP SLA that applies to tickets tagged "vip" with a 30-minute first response target, 4-hour resolution target, and an at-risk alert 15 minutes before the response target breaches Add a default SLA that applies to all tickets with an 8-hour first response and 24-hour resolution, paused while a ticket is Waiting on customer A new SLA joins at the lowest priority and applies to tickets created after it exists. It does not attach to tickets already open. ### Update an SLA When you change coverage, targets, alerts, or pause statuses, Copilot replaces the entire set for that field, so include every value you want to keep, not just the change. Editing an SLA resets when it takes effect: the new configuration applies to tickets created from that point on. **Example prompts:** Change the VIP SLA resolution target to 2 hours and keep the 30-minute first response target Switch the Default SLA off the 24/7 schedule and onto our Business Hours schedule ### Reorder SLAs by priority When several SLAs could apply to a ticket, the highest-priority one wins. Put narrow SLAs (like VIP or urgent) above broader ones — anything below an SLA that applies to every ticket never matches. Reordering must cover every SLA in the workspace at once; a partial list is rejected. Copilot pulls the current list, so you can describe the new order in natural language. **Example prompts:** Move the VIP SLA to the top priority Put the Urgent bugs SLA above the Default SLA Learn more about [SLAs](/documentation/automate/slas) *** ## Outbound webhooks Ask Copilot to list, create, and update the outbound webhooks that deliver workspace events to external HTTP endpoints. Managing webhooks through Copilot is restricted to workspace admins. **What Copilot can do:** * List every webhook with its URL, event subscriptions, active status, and whether a signing secret is set. Filter by name or URL, or by active and paused status. * Create a webhook with a name, destination URL, and the event types it should receive (**Ticket**, **Message**, or both, which is the default). You can also create it paused. * Update a webhook's name, URL, or event subscriptions, and pause or resume delivery. * Show a card to set or rotate a webhook's signing secret. Each URL can only be used by one webhook in the workspace. If you ask for a URL that another webhook already delivers to, Copilot reports the conflict and offers to reuse or update the existing webhook instead. Each webhook Copilot mentions appears as a card in the chat. The card shows the webhook's URL, event subscriptions, active status, and whether a secret key is set, and clicking it opens the webhook's detail page in settings. ### Set or rotate the signing secret Ravenna signs every delivery with the webhook's secret key and does not deliver events until one is set. Copilot never handles the secret itself. When you create a webhook, or ask Copilot to set or rotate a secret, the webhook card in chat opens a masked **Secret key** field. The value you enter there saves directly to the webhook and is never shared with Copilot, so do not paste a secret into the chat message box. After you save, the card confirms with **Secret key saved**. When rotating an existing secret, update the receiving endpoint to the new key. Copilot does not delete webhooks. Remove them from **Settings > Webhooks**. **Example prompts:** List all webhooks in the workspace Create a webhook called "PagerDuty sync" that sends ticket events to [https://example.com/hooks/ravenna](https://example.com/hooks/ravenna) Add message events to the PagerDuty sync webhook and keep ticket events Pause the PagerDuty sync webhook I need to rotate the secret key on the PagerDuty sync webhook Learn more about webhook payloads and settings in [Workspace settings](/documentation/platform/workspaces/settings#webhooks) *** ## Tips * **Describe the full agent in one message** when creating a new one. Include the name, Slack behavior, connected channels and knowledge bases, and personality all at once. * **Create rules with all three parts** (trigger, instruction, examples) for the best results. Examples help the agent recognize matching requests more accurately. * **Gate write tools on rules.** When wiring an integration or Foundry tool into a rule, ask Copilot to require confirmation for write actions and approval for sensitive or destructive ones. * **Create the form first, then add fields.** Copilot needs the form to exist before it can add fields to it. * **Test agents after configuring.** After setting up an agent and its rules, send it a message in Slack to make sure it responds as expected. Learn more about [everyday tasks](/documentation/automate/copilot/everyday-tasks), [building automations](/documentation/automate/copilot/build-automations), [AI agents](/documentation/automate/agents/overview), [agent rules](/documentation/automate/agents/configure), [channels](/documentation/tickets/channels), and [forms](/documentation/tickets/forms/overview) # Everyday tasks Source: https://docs.ravenna.ai/documentation/automate/copilot/everyday-tasks Use Copilot to search tickets, work ticket checklists, look up knowledge, summarize conversations, draft replies, chart analytics, and find users with natural language. Use Copilot for the tasks you do every day: finding tickets, looking up answers in your knowledge base, catching up on conversations, and drafting replies. Interactive ticket cards in Copilot *** ## Tickets ### Search and filter tickets Find tickets using natural language. Copilot understands what you mean even when your wording does not exactly match the ticket content, so you can describe what you are looking for in your own words. To detect duplicates of a specific ticket, use [Find duplicate tickets](#find-duplicate-tickets) instead. It is scoped to the same requester and ranks matches by similarity. **Supported filters:** * Priority, status, assignee, or requester * Channel or form * Tags and source (Slack, email, web) * Date ranges (created, updated, resolved, due date) When Copilot returns search results, it shows interactive ticket cards you can click to go directly to the ticket. It also displays the active filters so you can see exactly what criteria were applied. You can ask Copilot what ticket statuses or tags are available in your workspace if you are not sure what to filter by. For example, "What ticket statuses do we have?" or "Show me all tags." **Example prompts:** Show me open tickets in the IT Support channel assigned to me Find high priority HR tickets created in the last 7 days What tickets did the Benefits team resolve this week? ### View ticket details Get complete ticket information, including the conversation history, current status, priority, who it is assigned to, custom field values, and tags. Reference tickets by their ID, like `IT-4892` or `HR-2041`. **Example prompts:** Show me the details on IT-4892 What's the latest on HR-2041? Summarize the conversation on HOPS-1157 ### Find duplicate tickets Ask Copilot whether the same requester has already filed a ticket like this one. Copilot runs a same-requester similarity check on a source ticket and returns their other tickets that look like near-duplicates, ranked most similar first. Use it while triaging incoming work or before creating a new ticket for someone. Reference the source ticket by its display ID (like `IT-4892`) or open Copilot from the ticket page. You can ask Copilot to be stricter (return only near-identical matches) or looser (cast a wider net). **Example prompts:** Does IT-4892's requester have any other similar open tickets? Find likely duplicates of this ticket Show near-identical duplicates of HR-2041 from the same requester Duplicate detection is scoped to the ticket's requester, so it only finds other tickets they submitted. A ticket without a requester has no duplicates to find. ### Summarize and draft responses When you open Copilot from a ticket page, it can read the full conversation and help you work through it. **Summarize**: Ask Copilot to summarize a ticket's conversation to quickly understand what has happened, what decisions were made, and what still needs to be done. **Draft responses**: Ask Copilot to write a reply based on the conversation and your knowledge base. Copilot shows the draft as an interactive suggestion you can review, edit, and insert into the ticket. **Example prompts:** Summarize this ticket conversation What are the open action items on this ticket? Draft a reply explaining the next steps for this employee's laptop replacement Draft a response using what the knowledge base says about our VPN setup process ### Create and update tickets Create tickets by describing what you need. Set the channel, form, priority, and assignee. If the form has custom fields (like dropdowns or multi-select options), Copilot fills them in based on your description. Before creating a ticket, Copilot discovers the workspace's [forms](/documentation/tickets/forms/overview) and ticket attributes and picks the Published form that matches the request, then fills its fields and the workspace attributes from what you said. Copilot tells you which form it attached and, in one line, which values it inferred rather than heard directly, so you can correct anything that looks wrong. If a required field cannot be inferred and Copilot picked the form itself, it files the ticket without the form rather than guessing; if you named the form yourself, Copilot asks for the missing value instead of filing without it. Fields the ticket landed with no value for are surfaced so you can fill them in a follow-up. **Example prompts:** Create a ticket for a password reset in the IT Support channel and assign it to Jamie Lee File a high priority ticket about the VPN being down for the Austin office and tag it outage Escalate IT-4892 to high priority Assign HR-2041 to Jamie Lee and set the due date to next Friday **What you can update on a ticket:** * Title and description * Priority, status, and category * Assignee, requester, and followers * Tags and custom field values * Due date * Channel (move to a different channel) and form (change the ticket's form) * Parent ticket * Privacy settings You can also use Copilot to [create and manage forms and channels](/documentation/automate/copilot/configure-workspace) that define how tickets are submitted ### Work a ticket's checklist Copilot reads and edits the task checklist on a ticket, so you can run through an onboarding or offboarding list without switching to the Tasks panel. **What Copilot can do:** * Read the checklist, including headers, nested subtasks, assignees, and which template each item came from * Mark tasks complete or reopen them, one at a time or several in one request * Rename a task, reassign it, switch it between a task and a header, indent or outdent it, or reorder it * Find a task template by name and read its items before applying it * Apply a template to the ticket **Example prompts:** What's left on this ticket's checklist? Mark the laptop shipped and accounts created tasks as done Apply the Engineering Onboarding template to this ticket Assign the hardware tasks on this ticket to Jamie Lee Add a task to collect the badge and nest it under Offboarding Applying a template replaces the ticket's existing checklist. Copilot confirms with you first when the ticket already has tasks. Copilot cannot delete tasks, so remove items from the Tasks panel on the ticket. Learn more about [tasks and task templates](/documentation/tickets/tasks) ### Check SLA status When you ask about a ticket, Copilot also reports the SLA targets attached to it: the policy name, which clock each target measures (time to first response, resolution, or close), the configured threshold, the deadline, the at-risk alert time, whether the target is breached right now, and, for a running target, how long is left until it breaches (or how long it is overdue). Use it to answer "how long before this breaches?" or "which target did we miss?" without opening the ticket. A ticket with no SLA policy attached returns an empty list. **Example prompts:** What SLAs are on IT-4892? How long before HR-2041 breaches its first response SLA? Did HOPS-1157 miss its resolution target, and if so by how long? Learn more about [SLAs](/documentation/automate/slas) ### Check approval status When you ask about a ticket, Copilot also reports its approval state: the overall status, each round and its policy, who has approved or declined, any decline reason they gave, and who is still pending. Use it to answer "who is holding this up" without opening the ticket. **Example prompts:** Who still needs to approve IT-4892? Why was HR-2041 declined? Learn more about [approval rounds](/documentation/tickets/approvals/rounds) ### Save a ticket view Describe a filtered slice of the ticket table and Copilot saves it as a view in the workspace sidebar. Copilot shows the created view as an interactive card you can click to open it, and the sidebar's Views section refreshes right away. **What you can set on creation:** * Name and emoji icon * Visibility: shared with the workspace, or private to you * Status filters and other filters (priority, assignee, requester, channel, form, tags, source, created/updated/due date ranges) * Display mode: list, table, or Kanban * Grouping and sorting You can fine-tune columns and layout in the UI after Copilot creates the view. To change filters or move a view into a collection, edit it directly in the sidebar. **Example prompts:** Create a shared view called Unassigned Urgent with status Open and priority Urgent Save a private Kanban view of my open tickets grouped by status Make a view called Overdue HR with tickets in the HR channel past their due date, sorted by due date Learn more about [ticket views](/documentation/tickets/organize/views) *** ## Knowledge base ### Search your knowledge base Search your organization's internal knowledge base for answers about company policies, processes, and procedures. Copilot understands what you mean even when your wording does not exactly match the document content, so you can ask questions in your own words. It cites the source documents so you can verify the information. **Example prompts:** What is our PTO policy? How do I set up the VPN on a Mac? What are the steps for offboarding an employee? ### Walkthrough: answering a ticket using your knowledge base When you are working on a ticket, you can ask Copilot to find relevant information from the knowledge base and use it to draft a reply. Navigate to the ticket and open the Copilot side panel. Copilot automatically has context about the ticket's conversation. What does our knowledge base say about resetting two-factor authentication? Copilot returns relevant passages with source citations. Ask it to turn that into a response. Draft a reply to this employee explaining the 2FA reset process based on what you found *** ## Analytics and reporting Ask Copilot to count, chart, or trend data over tickets, ticket messages, knowledge base documents, or workflow runs. Copilot renders the chart in the conversation, then offers to save it to a dashboard as a reusable widget. ### Chart data on demand Describe the breakdown or trend you want. Copilot picks the right card type, a grouped metric for breakdowns and totals or a trend for time series, and renders it inline. **Example prompts:** Graph tickets by status How many high priority tickets did we get this month? Show ticket volume per day for the last 30 days Break down workflow runs by status this week ### Save a chart to a dashboard After Copilot renders a chart, it suggests **Add this to a dashboard** or **Create a new dashboard with this chart**. Pick an existing dashboard to keep related widgets together, or start a new one. **Example prompts:** Add this to my Support Overview dashboard Create a new dashboard called Weekly Ops Review with this chart ### Manage dashboards Ask Copilot to list, search, read, or update dashboards without leaving the conversation. Copilot can also create collections (folders that group related dashboards) and move dashboards between them. **Example prompts:** What dashboards do we have? Find dashboards with SLA in the name Show me the latest numbers from my SLA Compliance dashboard Change the date range on the Support Overview dashboard to the last 90 days Create a folder called Support Reporting and move Support Overview into it Move the AI Impact dashboard back to the top level Rename the AI Outcome widget on my AI Impact dashboard to Weekly resolution rate Saved widgets inherit each dashboard's default date range and time interval. Update the dashboard's view options to shift every widget on it at once. Learn more about [analytics dashboards](/documentation/measure/analytics) *** ## Users and channels Find information about people and Slack channels in your workspace. Search for users by name, get contact information, and look up user details for ticket assignments. **Example prompts:** Who is Jamie Lee? What's Priya Patel's email address? List Ravenna channels, the Slack channels already connected to them, and the Slack channels available to connect (any channel the Ravenna bot has been invited to across every connected Slack workspace). Copilot marks Slack channels that are already feeding another Ravenna channel so you know which are free. **Example prompts:** What Slack channels do we have? Which Slack channels can I connect to Ravenna? Tell me about the IT Support channel *** ## Get help with Ravenna Copilot can also search Ravenna's own product documentation to help you learn how features work or figure out how to do something in the platform. When Copilot finds relevant documentation, it shares links you can click to read the full article. **Example prompts:** How do I create a new form for time-off requests? How do I set up a triage channel in Slack? What workflow triggers are available? How do I connect a new integration? *** ## Tips * **Use Copilot from the ticket page** for summarization and drafting. It automatically has the full conversation. * **Ask naturally.** You do not need to use exact keywords when searching. "What's our vacation policy?" works just as well as searching for the exact document title. * **Reference tickets by ID** (like `IT-4892` or `HR-2041`) to go straight to the ticket you need. * **Check source citations.** Copilot cites which knowledge base documents it pulled from, so you can verify accuracy or share the source with the requester. Learn more about [using Copilot](/documentation/automate/copilot/using-copilot), [tickets](/documentation/tickets/channels), [knowledge base](/documentation/automate/knowledge/overview), and [users](/documentation/platform/roles-access) # Copilot Source: https://docs.ravenna.ai/documentation/automate/copilot/overview Use the AI assistant built into the Admin to manage tickets, look up knowledge, build workflows, configure agents, and more Copilot is an AI assistant built into the Admin. You can type requests in plain language and Copilot handles them for you, whether that means finding a ticket, drafting a reply, building an automation, or looking up a company policy. When Copilot takes an action or finds information, it shows interactive cards in the conversation (like tickets, workflows, or agents) that you can click to navigate directly to them. The Copilot side panel open in the Admin *** ## What you can do Open the panel, understand page context, and manage your conversation history. Search tickets, look up knowledge, summarize conversations, draft replies, and find users. Create workflows with conditions, approval gates, and multi-step logic using plain language. Set up AI agents, create channels and forms, write rules, and manage agent personality. *** ## If Copilot gets it wrong Copilot does its best to understand your requests, but it may occasionally misinterpret what you meant or take an action you did not expect. Here is how to handle it: * **Correct and retry.** If Copilot misunderstands, rephrase your request with more detail. For example, if "show me recent tickets" returns results from the wrong channel, try "show me tickets created this week in the IT Support channel." * **Undo changes.** If Copilot updates a ticket or workflow incorrectly, you can manually revert the change in the Admin. Copilot does not make changes that cannot be undone through the interface. * **Start a new conversation.** If the conversation gets off track, start a fresh session from the Copilot panel. Your previous conversations are saved in [session history](/documentation/automate/copilot/using-copilot#session-history) if you need to reference them. *** ## Tips * **Be specific in your requests.** "Create a workflow that sends a Slack message to #it-ops when a high priority ticket is created in the IT Support channel" works better than "make an automation for tickets." * **Use Copilot from the relevant page.** Opening Copilot from a ticket or workflow page gives it automatic context, so you do not need to explain what you are working on. * **Describe the full end state for complex setups.** When building workflows or configuring agents, describe the complete behavior you want rather than adding pieces one at a time. * **Reference existing resources by name.** When updating a workflow, agent, or channel, mention it by name so Copilot can find it directly. # Get started with Copilot Source: https://docs.ravenna.ai/documentation/automate/copilot/using-copilot Get started with Copilot: open the panel, use page context for tickets and workflows, and manage your conversation history across sessions. Learn how to open Copilot, work with page context, and manage your conversation history. Copilot is available to workspace admins and members. Workspace guests do not have access to Copilot. *** ## Open Copilot Copilot is available from every page in the Admin. You can open it in two ways: Your conversations persist across sessions so you can pick up where you left off. *** ## Page context When you open Copilot from certain pages, it automatically pulls in context about what you are viewing so you can reference "this ticket" or "this workflow" without specifying an ID. Copilot reads the full conversation and ticket details. You can ask it to summarize the conversation, draft a reply, search your knowledge base for relevant answers, or update the ticket. Learn more about [everyday tasks](/documentation/automate/copilot/everyday-tasks) Copilot sees the workflow's configuration and run history. You can ask it to edit steps, troubleshoot a failed run, or build a new workflow from scratch. Learn more about [building automations](/documentation/automate/copilot/build-automations) *** ## Session history Access and manage your past conversations with Copilot through the session history panel. Click any conversation to load and continue it. ### Managing conversations Conversations are automatically organized by recency: * **Today**: Conversations from the current day * **Yesterday**: Conversations from the previous day * **This week**: Conversations from the past week * **This month**: Conversations from the past month * **Older**: Conversations older than 30 days Update conversation titles to make them easier to identify. Hover over a conversation in the history sidebar and click the three-dot menu icon. Select **Rename**, enter a new title, and press Enter or click away to save. Press Escape to cancel renaming without saving changes. Remove conversations that are no longer needed. Hover over a conversation in the history sidebar and click the three-dot menu icon. Select **Delete**. The conversation is permanently removed. Deleted conversations cannot be recovered. Make sure you no longer need the conversation history before deleting. Learn more about [everyday tasks](/documentation/automate/copilot/everyday-tasks), [building automations](/documentation/automate/copilot/build-automations), and [configuring your workspace](/documentation/automate/copilot/configure-workspace) # Build Foundry functions Source: https://docs.ravenna.ai/documentation/automate/foundry/actions Create, test, publish, and roll back Foundry functions to add custom code actions to Ravenna workflows and AI agents, with built-in editor and runtime context. A function is something Foundry can do, like "send a DocuSign envelope" or "look up a Salesforce contact." You build it by describing what you want, and Foundry writes and tests the code for you. Functions live inside the Foundry app (in the workspace sidebar between **Agents** and **Workflows**). They use integrations created by your org admins in [Settings → Integrations](/documentation/automate/foundry/integrations). *** ## The workspace Open Foundry from the sidebar. The left panel has two tabs: * **Functions**. Every function in your workspace, with their last test status (Passing, Failing, or Never run). Click **New Function** to start a new one. * **Integrations**. Every integration available to Foundry. The **New Integration** button takes you to Settings. When you open a function, the right side becomes the **function workspace** with the generated code and a publish button. The panel on the left shifts into four tabs for that function: * **Chat**. The conversation Foundry uses to generate and refine code. * **Test**. Run the function with sample inputs. * **Integrations**. Connect or disconnect integrations for this function. * **Configure**. Edit the name, description, and AI tool prompt, or delete the function. *** ## Build a function In Foundry's **Functions** tab, click **New Function**. A blank function opens in the workspace. Open the function's **Integrations** tab and connect the integration the function should call. You can add more than one, which is useful when a function needs to read from one tool and write to another. The first integration is the **primary** one and supplies the function's default scope and OAuth connected account. If you don't have the integration you need, an admin can create one in [Settings → Integrations](/documentation/automate/foundry/integrations). In the **Chat** tab, write what you want the function to do in plain language. Be specific: List all active users and return their name, email, and role Create a project with the given name, description, and team Look up a contact by email and return their company and last activity date Foundry generates code, type-checks it, and runs a dry-run against the API. Open the **Test** tab, fill in the inputs, pick a runtime environment (development, staging, or production), and click **Run Test**. Foundry shows the result, every HTTP request the function made, and any log output. Secret-typed inputs accept credentials from your organization's [Vault](/documentation/platform/organizations/vault). Vault references are decrypted in memory when the test runs, and the decrypted values are scrubbed from the test output. Turn on **Dry Run** in the function workspace header to test without changing external state. See [Dry Run mode](#dry-run-mode) below. If something isn't right, ask in plain language from the **Chat** tab: Add pagination so it fetches every page. If the API returns a 429, wait and retry up to 3 times. Only return users where status is active. When Foundry suggests a follow-up, clickable suggestion chips appear in a strip above the input. Click a chip to prefill the composer so you can edit before sending. Click **Publish** in the function workspace. Foundry validates the code one more time, generates an AI tool prompt (so agents know when to call it), and publishes the function. It's now available as a workflow step and as a tool for your AI agents. Foundry shows generation status (`Idle`, `In progress`, `Success`, or `Error`) in the function workspace, so if a generation stalls or fails, you can see why. Want prompts you can copy? See [Foundry examples](/guides/how-to/foundry/examples) for worked recipes, or [Tips & troubleshooting](/guides/how-to/foundry/tips-and-troubleshooting) for ways to get better code out of Foundry. *** ## Version history Foundry snapshots a function every time its code changes, so you can go back to a version that worked. ### Version numbers Two numbers track a function, and they move for different reasons: * The **published version** (`published v3` in the workspace header) is the release number. It only moves when you publish. * The internal **revision** moves on every code write: an AI generation, a hand edit in the editor, or a checkpoint restore. It is what tells Foundry whether your draft has drifted from what is live, and it is why a test result recorded against an older revision is flagged as stale. So a function can sit at `published v3` while you make ten draft edits. Publishing again makes it `v4`. ### Restore a checkpoint Every code-changing step in the **Chat** tab gets a **Checkpoint** marker with its timestamp. Click **Restore** on a marker to roll the function back to that point. Restoring reverts the code, schemas, settings, and integration bindings, and rewinds the chat to that point so the conversation matches the code. Your current state is saved as a checkpoint first, so a restore is itself reversible. The checkpoint at your current state shows the marker without a **Restore** option, since there is nothing to change. Restoring changes your draft, not what is live. Publish afterward to push the restored code to workflows and agents. ### Roll back the published version Publishing also records a checkpoint, which gives you a deployable history. Click the **published v3** badge in the function workspace header to open **Publish history**, pick an earlier version, and confirm. A rollback reverts the code, schemas, settings, and integration bindings to that version and re-publishes, so anything running picks up the old code right away. Two differences from a checkpoint restore: * **Your chat is preserved.** A rollback is a deployment operation, not a rewind of your work, so the conversation stays where it is. * **It publishes a new version rather than reusing the old number.** Rolling back from `v5` to `v3` produces `v6`, annotated `↳ rolled back to v3` in the history so you can tell the two apart. The version currently live is marked **(current)** and cannot be selected. Rollback needs a published function, so an unpublished draft has no publish history. A rollback takes effect immediately for every workflow and agent using the function. There is no separate confirmation step after the dialog. *** ## Dry Run mode Dry Run lets you exercise a function end-to-end without changing external state. Use it to safely test functions that send email, create tickets, post messages, or update records. Turn on the **Dry Run** toggle in the function workspace header, then click **Run Test** from the **Test** tab as usual. When you publish a function, Foundry analyzes the code and picks one of two strategies. The active strategy shows up in the toggle's tooltip: | Strategy | When Foundry picks it | What runs | | -------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | As-is | The function only reads or searches (no external writes). | The original code runs live. | | Variant | The function makes at least one state-changing call (create, update, delete, send, etc.). | Foundry runs a generated copy of the code where only the writes are mocked. Reads stay live, so bad inputs and auth errors surface exactly like a real run. | A few things to know: * Dry Run is available once a function has been published or had its dry-run code generated. New, never-published functions show the toggle disabled. * The code editor switches to read-only while Dry Run is on, and a banner tells you which strategy is active. Turn Dry Run off before editing. * Each mocked write is logged in the test output so you can see exactly what the function *would* have done. * If you change the function and the dry-run variant looks stale, click the **Sparkles** button next to the toggle to regenerate it. Only workspace admins can regenerate dry-run code. * `dryRun` is also exposed on the `POST /foundry/actions/run-test` API via the `useDryRunVariant` flag. Dry Run is the safest way to test a function against production credentials. Use it whenever a failed test would create unwanted side effects, like duplicate tickets or real customer notifications. *** ## Advanced: the ActionContext SDK This section is for users who want to read or hand-edit the generated TypeScript code. You don't need any of this to build, test, or publish a function. Every function exports a `run` function that receives an `ActionContext`. The context gives you authenticated HTTP clients (one per integration), the Ravenna operations namespace, and runtime info. ```typescript theme={"system"} import type { ActionContext } from '@ravenna/actions' export async function run(ctx: ActionContext, input: RunInput): Promise { // Each integration is available by its slug, with auth and default headers injected. const salesforce = ctx.integrations.salesforce const response = await salesforce.fetch(`${salesforce.baseUrl}/services/data/v59.0/query`) const { records } = await response.json() // Call Ravenna operations the same way you'd call any built-in action. await ctx.ravenna.createTicket({ title: `New account: ${records[0].Name}`, queueId: input.queueId, statusId: input.statusId, requesterId: input.requesterId, authorId: input.authorId, }) ctx.log(`Processed ${records.length} records in ${ctx.env}`) return { count: records.length } } ``` ### Context properties | Property | What it is | | ---------------------------------------- | --------------------------------------------------------------------------------------------- | | `ctx.integrations` | A map of integration clients keyed by slug. Each has `.fetch` (auth-injected) and `.baseUrl`. | | `ctx.ravenna` | The Ravenna operations namespace. See the list below. | | `ctx.log()` | Writes to the function's log output. | | `ctx.workspaceId` / `ctx.organizationId` | IDs for the current execution context. | | `ctx.env` | `'development'`, `'staging'`, or `'production'`. | | `ctx.workflowExecutionId` | Set when the function is running as a workflow step. | `ctx.fetch`, `ctx.baseUrl`, and `ctx.auth` still exist for backwards compatibility but are deprecated. They point at the primary integration. New code should use `ctx.integrations.` so it keeps working when more integrations are added to the function. ### Ravenna operations Available on `ctx.ravenna`: **Tickets:** `createTicket`, `updateTicket`, `addTicketComment`, `setTicketStatus`, `setTicketPriority`, `setTicketAssignee`, `addTicketFollowers`, `addTicketTags`, `moveTicket` **Users:** `getUser` Slack is not a `ctx.ravenna` operation. To post to Slack from an action, select the Slack integration and call the Slack Web API directly with `ctx.integrations.native_slack.fetch`. Your workspace's bot token is attached automatically, so you pass Slack arguments only (such as channel and text), never a workspace or team id. Foundry actions for Microsoft Teams are not yet available. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview) for the current beta scope. *** ## Advanced: how generation and testing work Foundry validates generated code in two phases, automatically: 1. **TypeScript compilation** catches syntax errors, type mismatches, and bad imports. Foundry auto-fixes failures up to 3 times. 2. **Dry-run execution** runs the code in a sandbox without making real API calls, to catch issues like malformed URLs. Foundry auto-fixes failures up to 2 times. When you run a real test from the **Test** tab, you pick the runtime environment (`development`, `staging`, or `production`) that the function sees via `ctx.env`. The function runs in an isolated sandbox with the credentials resolved for each of its integrations, limited to 30 seconds per execution. When you publish, Foundry runs a final validation, then generates an AI tool prompt that helps agents decide when to call the function. You can regenerate that prompt from the function's **Configure** tab. Learn how to [use published functions](/documentation/automate/foundry/using-actions) in workflows and with AI agents. # Foundry integrations Source: https://docs.ravenna.ai/documentation/automate/foundry/integrations Connect external tools to Foundry from your organization settings using API keys, bearer tokens, basic auth, or custom OAuth providers for Ravenna workflows. An integration is a connection to an outside tool. Each integration stores the sign-in details so your functions can talk to the tool, plus a link to the tool's documentation so Foundry knows what the tool can do. Integrations are managed by **organization admins** in Settings. Once an integration is set up, anyone using Foundry can build functions on top of it. *** ## Where integrations live Foundry uses two settings pages: * **Settings → Integrations**. Create and manage custom API integrations. They appear in the **Custom** category alongside Ravenna's built-in integrations. * **Settings → OAuth Providers**. Register OAuth providers that end users connect their own accounts to. You can also see the list of integrations available to Foundry inside the Foundry app itself, under the **Integrations** tab in the left sidebar. The **New Integration** button there links straight to Settings. *** ## Custom API integrations Use these for any tool with an API that uses a static credential (API key, bearer token, basic auth) or no auth at all. ### Create one Select the **Custom** category, then click **New Integration**. Fill in the API name, an optional description and logo, a category, and a link to the tool's documentation. The best documentation link is one that goes straight to the API reference, not the marketing homepage. If the tool has an OpenAPI or Swagger link, use that. Foundry reads the documentation to learn how the tool works, including pagination, auth methods, rate limits, error handling, and versioning. You'll see live progress for each of those steps. This usually takes under a minute. Select the sign-in type and fill in the credentials. The wizard supports **API key**, **Bearer token**, **Basic auth**, and **No auth**. You can also add **default headers** that should be sent with every request from this integration. These are useful for things like a tenant or account header. Review your settings, then save. The integration is now available to Foundry functions. ### Edit or delete later From **Settings → Integrations**, click any custom integration to open its details. You can edit the basics and authentication, re-run docs research, or delete the integration. You'll need to remove or unpublish any functions using it before you can delete it. Credentials are stored in Ravenna's secure vault. They're only used when a function runs and they're never shown to the AI that writes your function code. For a step-by-step walkthrough of the custom integration wizard, see [Set up a custom API integration](/guides/how-to/foundry/setup-custom-api) in the Foundry guide. ### Set up a custom integration from Copilot chat You can also create a custom API integration by asking Copilot to add one. When Copilot creates a draft integration on your behalf, it renders an inline **setup card** in the conversation so you can finish the wizard without leaving chat. The card handles API key, bearer token, and basic auth integrations end-to-end; OAuth 2.0 integrations still finish through the OAuth **Connect** chip. The card advances through four stages: Confirm the API base URL, docs URL, and authentication type. Clicking **Continue** saves the draft integration and moves to the next stage. If you pick **No auth**, the card skips credentials and goes straight to validation. Enter the credential in a masked field on the card. The value is submitted directly to Ravenna's encrypted vault out-of-band. It never appears in the chat transcript, is never sent to the LLM, and is not stored in message history. For services that use basic auth with an API key in the username slot and no password (Stripe, Mailgun, Cursor), the card shows a single masked **API key** field instead of separate username and password fields. Paste the key there. Under the hood the integration still uses basic auth and Foundry sends a valid `Authorization: Basic` header with the key as the username. Ravenna runs a live authenticated request against the auth-test endpoint discovered during docs research. "Connection succeeded" only appears once the target API accepts the credential. If validation fails, the card shows the status code and lets you re-enter credentials or retry. The card collapses to a ** connected** tile you can click through to the integration's settings page. The integration is now ready for functions. The card is reload-safe. If you refresh or reopen the chat after credentials are already stored, the card resumes at validation instead of asking for the credential again. For OAuth 2.0 integrations, the card shows the same **Connect** popup used in Settings rather than an inline credential field — the provider's sign-in page can't be embedded in chat. Everything else about the flow (draft creation, docs research, validation, publish) is the same. ### Update an integration from Copilot chat Copilot can also fix an existing custom API integration in place. If an integration has the wrong name, base URL, docs URL, or authentication type, ask Copilot to correct it. This works for any integration in the workspace, including a draft Copilot created earlier in the same conversation. Copilot updates the existing integration rather than creating a duplicate draft. ```text theme={"system"} The Mailgun integration is pointing at the wrong base URL. Change it to https://api.eu.mailgun.net ``` What happens next depends on which field changed: * **Name, base URL, description, or default headers.** The change applies immediately with no side effects. Docs validation status and stored credentials are untouched. * **Docs URL.** Foundry restarts docs research against the new URL, since the previous research was based on the old documentation. Wait for validation to finish before publishing the integration or generating functions on it. * **Authentication type.** Ravenna clears the stored credentials, because the old and new auth types don't share a credential shape. Copilot then re-renders the **Credentials** setup card so you can enter the credential for the new type. No card appears if you switch to **No auth**. Two authentication changes aren't available in chat: * Copilot can't switch an integration **to** OAuth 2.0. An OAuth 2.0 integration needs an OAuth provider attached, and that only happens through **Settings → OAuth Providers**. * Copilot can't switch an integration that already has an OAuth provider linked **away from** OAuth 2.0. If you need a different auth mechanism for that API, create a separate integration. *** ## OAuth providers Use these for tools where end users sign in with their own account, for example Google, Microsoft, or Salesforce. Each user who runs a function connects their account once, and the function executes as that account. ### Register a provider Click **Add Provider**. Give the provider a name, a slug (used internally), an optional description and logo, and the base URL and docs URL for the API. Enter the provider's authorization URL, token URL, scopes, client ID, and client secret. Expand **Advanced** if the provider has non-standard requirements (extra parameters, alternate credential delivery, or a non-`Bearer` API auth header). See [Advanced OAuth settings](#advanced-oauth-settings) below. Foundry researches the docs URL the same way it does for custom API integrations, then saves the provider. It's now enabled for the org and shows up in the **Custom** category of **Settings → Integrations**, where users can connect their accounts. ### Connect fields on Ravenna-provided providers Some Ravenna-provided OAuth providers need a per-user value (a workspace subdomain, an account region, a per-tenant API host) to complete the OAuth flow. When you connect an account to one of those providers, Ravenna opens a **Connect ** dialog and asks for the required values before starting sign-in. Each field shows a label, an optional placeholder, and one-line help text explaining where to find the value. The **Connect** button stays disabled until every required field has a value. Ravenna then URL-encodes each value, substitutes it into the provider's URLs, and starts the OAuth flow. It stores the values alongside the connection and reuses them on every API call from that user's functions. Connect fields only appear when a provider template defines them — most providers don't. Custom OAuth providers you register from **Settings → OAuth Providers** don't use connect fields. You can disable or delete providers at any time from **Settings → OAuth Providers**. ### Advanced OAuth settings Most providers work with just the basic fields above. Expand **Advanced** on the OAuth tab when a provider deviates from the OAuth 2.0 defaults. Foundry auto-expands the section when you edit a provider that already has non-default values. | Field | When to use it | Default | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | | **Grant type** | Which OAuth 2.0 flow Foundry uses to obtain tokens. Keep **Authorization Code** when each user signs in with their own account. Switch to **Client Credentials** for a server-to-server provider that uses a single shared machine credential for the whole org. See [Grant types](#grant-types) below. | Authorization Code | | **Auth URL params (JSON)** | Extra query parameters appended to the authorization URL. Google needs `{"access_type": "offline", "prompt": "consent"}` to issue refresh tokens. | None | | **Token exchange params (JSON)** | Extra parameters merged into the token request body. Use for provider-specific fields the OAuth 2.0 spec doesn't define. | None | | **Credential delivery** | How the client ID and secret are sent to the token endpoint. **Authorization Header** uses HTTP Basic auth (most providers). Switch to **Request Body** if the provider expects `client_id` and `client_secret` in the form body instead. | Authorization Header | | **Token exchange format** | Content-Type of the token request body. **Form URL-encoded** is the OAuth 2.0 default. Switch to **JSON** for providers that require it. | Form URL-encoded | | **API auth header scheme** | The scheme prefix Foundry uses in the `Authorization` header when calling the provider API with the access token. Set this when a provider rejects the standard `Bearer` prefix — Discord bot tokens, for example, use `Bot`. | `Bearer` | The API auth header scheme only changes the prefix Foundry sends with API calls (for example `Authorization: Bot ` instead of `Authorization: Bearer `). It doesn't change how the token itself is obtained. ### Grant types Foundry supports two OAuth 2.0 grant types. Pick the one that matches how the third-party API expects to be called. **Authorization Code** is the default and the right choice for any provider where each user should act as themselves — Google, Microsoft, Salesforce, GitHub, and most consumer APIs. Each user connects their own account from **Settings → Integrations**, and Foundry runs functions as the connected user. Tokens refresh automatically using the stored refresh token. **Client Credentials** is a server-to-server flow with no user redirect. Foundry exchanges the client ID and client secret directly for an access token, and every function call uses that same machine credential. Pick it when the provider issues an org-level token rather than per-user tokens — for example, an internal API that authenticates the whole organization with a single service account. When you choose Client Credentials, the **Authorization URL** field is no longer required. The connect step doesn't open a sign-in page either: clicking **Connect** in **Settings → Integrations** fetches a token immediately and reuses it for every user. Tokens are re-fetched in place when they expire, since there's no refresh token. Client Credentials is only offered for organization-owned OAuth providers, since the credential is shared across everyone in the org. Built-in Ravenna providers stay on Authorization Code. ### Connect an account Once a provider is registered, each user connects their own account by going to **Settings → Integrations**, finding the provider in the **Custom** category, and clicking through the standard OAuth sign-in flow. Tokens refresh automatically. For Client Credentials providers, the connect step is a single click rather than a sign-in flow, and any user in the org who runs a function on the integration uses the same shared token. ### Reconnect a Foundry OAuth account A refresh token can eventually expire — Okta's default refresh token lifetime is a common example, and some providers also invalidate refresh tokens after long inactivity or a password change. When that happens, functions built on the integration start failing with auth errors even though the connection still exists. Use **Reconnect** to renew credentials in place. Reconnect re-runs the OAuth consent flow against the same connection, so the new tokens replace the old ones while everything else on the integration — its configured actions, its integration settings, and the automatic token-refresh schedule — is preserved. There's no need to disconnect first, and you don't have to re-link the integration to any functions that already use it. Reconnect is available in two places: * **In the Foundry builder.** Open the function, go to the **Authentication** tab, and click **Reconnect** next to the connected account. * **In the integration tile.** From **Settings → Integrations**, open the integration, and choose **Reconnect** from the actions menu on the connection row. Both entry points run the same in-place update: Ravenna reuses the connection's stored connect field values, sends you through the provider's consent screen, and writes the fresh tokens back to the existing connection. Reconnect is the recommended remedy when a refresh token expires (for example on an Okta connection). Disconnecting and reconnecting also works, but it drops the connection and requires re-linking any functions that reference it — Reconnect avoids that. Client Credentials providers don't show a **Reconnect** button in the integration tile's manage dialog. They don't require a user redirect, so tokens are re-fetched in place automatically when they expire — there's nothing to re-consent to. Need help registering a provider? The Foundry guide has end-to-end walkthroughs for [Google Cloud](/guides/how-to/foundry/setup-oauth/google-cloud), [GitHub](/guides/how-to/foundry/setup-oauth/github), and [DocuSign](/guides/how-to/foundry/setup-oauth/docusign), plus a [shared overview](/guides/how-to/foundry/setup-oauth/overview) you can adapt to any provider. *** ## Native credential bridges Some integrations you have already connected to Ravenna can share their credentials with Foundry actions directly. When a native bridge is available, you do not need to configure a separate Foundry integration. The action runs with the same OAuth token your Ravenna integration uses. **Available native bridges:** | Integration | What Foundry can access | | ----------------- | ------------------------------------------------------------------------------------------------------------ | | Notion | Read and write pages, databases, and blocks in connected Notion workspaces. | | Jamf Pro | Query and manage devices, users, and policies in your Jamf Pro instance. | | Slack | Post messages, read channels, and interact with the Slack API using your connected bot token. | | Google Workspace | Access Google Drive, Calendar, and Admin APIs through your connected service account. | | Okta | Read and manage users, groups, and applications in your Okta org. | | Microsoft Entra | Read and manage users, groups, and applications in your Entra tenant. | | Cloudflare Access | Read and manage Access applications, policies, and identity providers on your Cloudflare account. | | FleetDM | Query device inventory and run live queries against enrolled hosts. | | Jira | Read and write issues, projects, and comments in your connected Jira site. | | Linear | Read and write issues, projects, and comments in your Linear workspace. | | GitHub | Read and write issues, pull requests, and repository contents on your connected GitHub account. | | PagerDuty | Read and manage incidents, services, and schedules in your PagerDuty account. | | HubSpot | Read and write CRM records — contacts, companies, deals, tickets — via the HubSpot API. | | Incident.io | Read and manage incidents, follow-ups, and workflows via the Incident.io API. | | Vanta | Read compliance data — controls, tests, and evidence — in your Vanta account. | | Freshservice | Read and write tickets, requesters, assets, and changes in your Freshservice instance; per-tenant subdomain. | | JumpCloud | Read and manage users, systems, applications, and policies in your JumpCloud org. | | Microsoft Intune | Read and manage devices, users, and policies via the Microsoft Graph endpoints Intune exposes. | | Iru | Per-tenant device and identity data through your Iru workspace. | | Rippling | Read and manage employees, groups, and app assignments via the Rippling REST API. | **Using a native bridge:** When you create or generate a Foundry action, select the connected integration from the integration picker. Foundry injects the integration's credentials into the sandbox at runtime. Your action code can call the third-party API directly without managing authentication. Native bridges use the same permissions your Ravenna integration has. If your Notion integration has read-only access, Foundry actions using that bridge also have read-only access. *** ## Managing integrations * **Edit** to update sign-in details, the base URL, or the docs URL. * **Re-research** to make Foundry re-read the documentation if the API has changed. * **Delete** to remove the integration. Remove or unpublish any functions using it first. Ready to build? Learn how to [create a function](/documentation/automate/foundry/actions). # Foundry overview Source: https://docs.ravenna.ai/documentation/automate/foundry/overview Build custom integrations and functions for Ravenna in plain language. Foundry generates the code, runs it, and exposes it to workflows and AI agents. Foundry is currently in Beta and under active development. Share your feedback with the team to help us build and improve. Foundry lets you connect Ravenna to any third-party tool and build custom **functions** by describing what you want in plain language. Foundry handles the code behind the scenes, enabling anyone on your team to extend Ravenna with custom integrations. Once a function is published, it shows up as a step in the workflow builder and as a tool your AI agents can use. The same function powers both. *** ## What you can do Connect to tools that don't have a native Ravenna integration, like internal APIs or niche SaaS products. Write what the function should do in plain language. Foundry builds and tests it for you. Drop the function into any workflow as a step, just like a built-in action. Your AI agents can call the function during conversations whenever it's the right tool for the job. *** ## Where to find Foundry * **Foundry** in the workspace sidebar (between Agents and Workflows) is where you build, test, and publish functions. * **Settings → Integrations** is where org admins create the custom integrations Foundry connects to. Custom integrations show up in their own **Custom** category alongside Ravenna's built-in integrations. * **Settings → OAuth Providers** is where org admins register OAuth providers that Foundry can use for end-user account connections. *** ## How it works An org admin connects to the tool from **Settings → Integrations**. Foundry reads the tool's documentation to learn what it can do. In Foundry, click **New Function** and write what you want it to do in plain language. In the function's **Integrations** tab, attach the integrations it should call. A function can use more than one. Run the function with sample inputs. Foundry shows you exactly what happened so you can confirm it works. Want to change something? Ask in plain language and Foundry updates the function. Also return their account owner. Publishing makes the function available everywhere in Ravenna, as a workflow step and as a tool for your AI agents. *** ## Key terms **Integration.** A connection to an outside tool. Stores the sign-in details and the tool's documentation so Foundry knows how to talk to it. Managed in **Settings → Integrations**. **Function.** Something Foundry can do, like "send a DocuSign envelope" or "look up a Salesforce account." Built and tested inside Foundry, then published so workflows and agents can use it. **Connected account.** For tools that use a sign-in flow (OAuth), the specific account a function runs as. You pick this when you build the function. *** ## Get started Connect your first tool from Settings. Create, test, and publish your first function. Want to go deeper? The [Foundry guide](/guides/how-to/foundry/overview) has end-to-end setup walkthroughs, OAuth examples for Google Cloud, GitHub, and DocuSign, and recipes you can adapt to your stack. # Use Foundry functions in workflows and agents Source: https://docs.ravenna.ai/documentation/automate/foundry/using-actions Call published Foundry functions from Ravenna workflows and AI agents to run custom code actions, integrations, and data lookups in your automations. Once you publish a Foundry function, it's available in two places: as a step in a workflow, and as a tool your AI agents can use. A single function you build once works in both. *** ## In workflows Published functions show up in the workflow builder alongside built-in actions. Go to **Workflows** and open or create a workflow. In the step picker, find your function under **Code Actions**. Each function has input fields. Connect them to data from the workflow trigger or earlier steps. For example, map a ticket's requester email to the function's "email" input. For secret-typed inputs (API keys, tokens, passwords), select a credential from your organization's Vault instead of pasting the value. The workflow stores only a reference to the credential. Ravenna decrypts the value in memory when the function runs and scrubs it from execution logs. This works for secret fields at any nesting depth, including inside objects and arrays. Pasting a plaintext value directly still works. The function's output is available to every step after it. Functions support two output formats: * **Text**: Returns a plain text string. The entire output is a single value downstream steps can reference. * **JSON**: Returns structured JSON data. Each top-level key in the returned object becomes a separately addressable output field. For example, if your function returns `{ "userId": "abc", "plan": "pro" }`, downstream steps can reference `userId` and `plan` individually. Select the output format in the function's **Configure** tab. When JSON output is selected, your code's return value is parsed as JSON automatically. ### Example A common pattern is enriching a ticket with information from another tool: 1. **Trigger:** A new ticket is created. 2. **Foundry function:** Look up the requester in your CRM by email and return their company and plan. 3. **Update ticket:** Set custom fields with the CRM data and route the ticket based on the plan. *** ## With AI agents Agents in your workspace can use published functions automatically. When a user asks something a function can help with, the agent calls it. You can also point agents at specific functions in your agent rules. Reference a function by name with `@Function Name`: When a user asks about a customer, use @Look up CRM contact to find their details by email. Share the company, role, and plan with the user. You don't need to write any agent-facing documentation. When you publish a function, Foundry generates an AI tool prompt that tells agents what it does and when to use it. You can regenerate that prompt at any time from the function's **Configure** tab. See how teams wire published functions into real workflows and agent rules in the [Foundry examples](/guides/how-to/foundry/examples) guide. *** ## Who sees a function A function is visible to the same workspaces its integrations are. | Integration type | Where the function is available | | ---------------------- | ------------------------------------ | | Custom API integration | The workspace it was created in | | OAuth provider | Every workspace in your organization | For functions that use more than one integration, the most restrictive scope wins. *** ## Managing published functions * **Unpublish** removes the function from workflows and agents. Workflows already running finish, but new runs won't start. * **Update and republish** pushes a new version. Workflows and agents pick it up automatically. * **Regenerate the AI tool prompt** if you've changed what the function does and want agents to learn the new behavior. Learn more about [building workflows](/documentation/automate/workflows/overview) and [configuring AI agents](/documentation/automate/agents/configure). # Generate KB articles Source: https://docs.ravenna.ai/documentation/automate/knowledge/generate-articles Turn resolved tickets into draft KB articles using AI, generated from Slack reactions or the Admin. You can turn ticket conversations into draft knowledge base articles using AI. This turns real questions into reusable documentation. There are two ways to generate a KB article: * React with the 🧠 emoji on a Slack message. * Use the **Generate KB Article** action on a ticket in the Admin. ## Generation methods ### From Slack with 🧠 Add the 🧠 (`:brain:`) emoji reaction to any Slack message to generate a KB article from that thread. 1. Find a Slack thread that contains a question and an answer worth capturing. 2. React to the **original channel message** (not a thread reply) with 🧠. 3. You see an ephemeral message confirming that knowledge generation has started. If the thread does not already have a ticket, Ravenna creates one automatically before generating the article. If a ticket already exists for the thread, Ravenna uses it. If you react with 🧠 on a thread that has already produced a KB article, Ravenna updates the existing article with the latest conversation instead of creating a duplicate. The confirmation message indicates whether a new article was created or an existing one was updated. Emoji actions only trigger on the original message in a channel. Reacting to a reply inside a thread does not trigger article generation. Learn more about [Emoji actions](/integrations/slack/emoji-actions) Microsoft Teams: the 🧠 (`:brain:`) reaction is **not** in the [Microsoft Teams emoji action set](/integrations/microsoft-teams/emoji-actions) (currently ✅ ❌ 📖 👀 👎). Generate KB articles from Teams threads using the Admin instead. ### From a ticket in the Admin You can generate or regenerate a KB article from any ticket in the Admin. 1. Open the ticket in Ravenna. 2. Click the **⋯** (more) menu on the ticket. 3. Select **Generate KB Article**. 4. The **Create KB Article** dialog opens and starts generation automatically. 5. When generation completes, click the article preview to open and edit it in your knowledge base. If a KB article already exists for the ticket, the dialog shows the existing article and offers a **Regenerate** option. ## How generation works The generation workflow: 1. **Enriches the conversation** with ticket metadata and message context. 2. **Segments the conversation** into question-and-answer exchanges and identifies bot failures. 3. **Classifies knowledge gaps** to determine which exchanges represent missing documentation. 4. **Generates article sections** from the identified gaps, using ticket context. 5. **Saves the article** to your knowledge base and ingests it for search. 6. **Notifies the requester** when the article is ready. Generated articles are drafts. Review and edit them in your knowledge base before relying on them for agent answers. ### Generation states The generation dialog reflects the current status: | State | Description | | ------------ | -------------------------------------------------------------------------------------------- | | Initializing | Article generation has been requested but not yet queued. | | Queued | The generation job is waiting to run. | | Generating | The workflow is running. A progress bar shows completion percentage. | | Completed | The article is ready. A preview and link to the KB are shown. | | Failed | The workflow could not complete. Try regenerating, or contact support if the issue persists. | Generation may finish without producing an article if the conversation does not contain a clear knowledge gap. For example, the bot may have already answered correctly, or the thread may not have added any new information. ## After generation * New articles land in your knowledge base and are immediately searchable by agents that have access to the parent folder. * Edit the article to refine wording, add screenshots, or link to related content. * Archive or delete the draft if it is not useful. The source ticket remains unchanged. * For tickets, the **Generate KB Article** action becomes **Regenerate KB Article** once an article exists. ## Programmatic generation You can also trigger KB article generation via the API: * [Generate a KB article from a ticket conversation](/api/ticket/generate-a-kb-article-from-a-ticket-conversation) * [Get unified KB article status](/api/ticket/get-unified-kb-article-status-including-existing-articles-and-job-progress) # Knowledge gaps Source: https://docs.ravenna.ai/documentation/automate/knowledge/knowledge-gaps Automatically detect recurring topics your knowledge base does not cover well, ranked by severity and 30-day trend so you know what to document next. Knowledge Gaps is currently in private Beta and enabled for selected customers. If you'd like access, reach out to the team on Slack or via the in-app chat. Knowledge Gaps looks at tickets your AI agent could not resolve, groups the similar ones together, and surfaces them as prioritized recurring topics your knowledge base doesn't cover well yet. Instead of skimming escalations by hand, you get a ranked list of what to document next that refreshes automatically each week. Each gap (a **cluster**) has: * A **severity** bucket (Low, Medium, High, or Critical) driven by ticket volume and 30-day trend. * A **trend** pill: red and rising when the topic is growing, green and falling when it's shrinking, grey when it's steady. * A **classification** of why it's a gap: no content exists, or content exists but wasn't sufficient. * The tickets behind it, an item and problem type, and a lifecycle state so you can see whether it's growing, quiet, or archived. Find it under **Knowledge > Gaps**. *** ## The Gaps screen Gaps are listed as cards, one per gap, newest activity and highest severity first. Each card shows the ticket count in a severity-colored circle, the gap's label and description, a trend pill, and when the topic was last mentioned. Gaps whose coverage has been published also carry a **Resolved** badge. Click a card to expand it. Ravenna loads the underlying tickets and lists them one per row with who asked, the ticket ID (click to open it), and which channel it came from. The first five rows show immediately; **See more** reveals the rest. ### Narrow the list The toolbar above the list controls what you see: * **State** filter: **Open** (active and dormant gaps), **Archived**, and **Watching** (the emerging pool). Open is the default. The filter accepts more than one state, so you can look at Open and Archived together. * **Severity** legend: click **Low**, **Medium**, **High**, or **Critical** to toggle that severity in or out of the list. * **Search**: search by label or example question, from the box in the page header. * **Date range**: set the window from **View options**. Filtering, searching, and paging all run server-side, so the list stays fast on a workspace with thousands of gaps. Change any filter and you return to page one. *** ## How gaps are detected Detection runs automatically on a weekly cycle, per workspace. Each run pulls escalated tickets since the last successful run, matches them against existing gaps, clusters what remains, splits mixed-topic clusters, classifies each cluster, and recomputes severity, trend, and lifecycle for every gap in the workspace. ```mermaid theme={"system"} graph TD A(Weekly run starts) --> B(Pull escalated tickets
since last successful run) B --> C{Matches an
existing gap?} C -->|Yes| D(Add to that gap) C -->|No| E(Cluster remaining tickets
into new gaps) E --> F(Split any cluster mixing
distinct products or systems) F --> G(Classify each cluster:
no content / weak content / not a gap) D --> H(Recompute severity, trend,
and lifecycle for every gap) G --> H H --> I(Run complete) classDef question fill:#E2EAEF,stroke:#165d6e,stroke-width:1px,color:#0f172a classDef step fill:#269cbd,stroke:#269cbd,color:#ffffff classDef terminal fill:#165d6e,stroke:#165d6e,color:#ffffff class C question class B,D,E,F,G,H step class A,I terminal ``` If a scheduled run is still finishing when the next one is due, the next run is skipped rather than queued behind it. Runs that fail don't advance the watermark, so the next run automatically re-covers the same window with no gaps or double-processing. ### What counts as an escalation An escalation is any ticket where the AI agent could not resolve the customer's question. For each one, detection records: * **Knowledge-base signal**: whether the agent tried a KB lookup and what came back. * **No content**: searched and found nothing. * **Had content**: searched and found something, but it didn't resolve the question. * **Not searched**: the agent never attempted a lookup. * **Item and problem type**: the product or system involved and the kind of problem, extracted from the ticket. Synonyms and casing are canonicalized so one gap doesn't silently swallow unrelated topics with similar wording. * **Queue and agent attribution**: for per-queue reporting. ### Running detection on demand Use **Sync** from the Gaps tab to force an immediate run using the same pipeline as the weekly schedule. *** ## Severity and trend Every gap gets a severity bucket, recomputed on every run from ticket volume and 30-day trend. ```mermaid theme={"system"} graph LR V(Volume score
caps at ~150 tickets) -->|60%| S(Severity score
0 to 100) T(Trend score
flat = neutral) -->|40%| S S --> L{Bucket} L -->|score ≥ 75| C1(Critical) L -->|50 to 74| C2(High) L -->|30 to 49| C3(Medium) L -->|below 30| C4(Low) classDef input fill:#E2EAEF,stroke:#165d6e,stroke-width:1px,color:#0f172a classDef question fill:#E2EAEF,stroke:#165d6e,stroke-width:1px,color:#0f172a classDef step fill:#269cbd,stroke:#269cbd,color:#ffffff classDef terminal fill:#165d6e,stroke:#165d6e,color:#ffffff class V,T input class L question class S step class C1,C2,C3,C4 terminal ``` **How volume and trend combine:** * **Volume** contributes 60% of the score. It saturates once a cluster hits about 150 tickets. Beyond that, more tickets don't raise volume further. * **Trend** contributes 40%. Trend is the percentage change in new tickets over the last 30 days compared with the prior 30 days. * A flat cluster scores neutral, so it isn't rewarded or penalized. * A growing cluster scores higher and can rank above a bigger but flat one. * A declining cluster scores lower and sinks in the list on its own. * New clusters without prior-window history are treated as flat, so they aren't penalized or inflated on their first appearance. Trend is computed from each ticket's real escalation date, not the date the ticket was processed. A ticket that escalated three weeks ago but only joined a cluster today (through the Watching pool) counts on the date the customer actually hit the issue. A gap's severity can change even with no new tickets. The scoring window slides forward in time with "today", so an unchanged cluster can drop a bucket purely because comparable activity fell out of the trailing 30-day window. This is expected. *** ## Emerging topics Some escalations are too rare or too early to hit the clustering threshold on their first pass. Rather than being dropped, they're held in a pending pool and automatically re-fed into every subsequent weekly run. Once enough similar tickets accumulate, they graduate into a real, visible gap. * Set the **State** filter to **Watching** to see them. They're listed as loose tickets rather than cards, with how many detection runs each one has been through, because they aren't gaps yet. * A stray that goes 21 days without gathering enough companions ages out. * Tickets where the agent never attempted a KB lookup are never pooled. Use Watching to spot new product areas or edge cases before they get large enough to hurt. *** ## Cluster lifecycle Every cluster has a lifecycle state that's maintained automatically as part of each weekly run. ```mermaid theme={"system"} graph LR A(Active) -->|30+ days idle| D(Dormant) D -->|90+ days idle| R(Archived) D -->|New tickets| A R -->|Manual restore| A A -->|Manual archive| R classDef live fill:#165d6e,stroke:#165d6e,color:#ffffff classDef idle fill:#E2EAEF,stroke:#165d6e,stroke-width:1px,color:#0f172a classDef archived fill:#F1F5F9,stroke:#94a3b8,color:#475569 class A live class D idle class R archived ``` | State | Meaning | How it's reached | | ------------ | -------------------------------------------------------------------------- | -------------------------------------------------- | | **Active** | Normal, in-rotation gap. Ranked and visible under the Open state. | Default on creation and while getting new tickets. | | **Dormant** | No new tickets in 30+ days, but not yet archived. Still listed under Open. | Automatic sweep. | | **Archived** | No new tickets in 90+ days and not marked as covered. | Automatic sweep. | Labels and descriptions are refreshed automatically once a cluster has grown meaningfully since it was last labeled, so the name stays accurate as more tickets land in it. A cluster that has stopped growing keeps its existing label even if it feels dated. Label refresh only fires after meaningful new growth. This is intentional to avoid churn on stable clusters. *** ## What you can do with a gap Expand a gap to see the tickets behind it: who asked, what they asked, and which channel it arrived on. Use it to confirm the cluster matches what you'd expect before you write anything, then open the tickets you want to read in full. The workflow from there is to write the article yourself. Create it in your knowledge base and cover the topic the gap names. Once the content is published and the agent starts resolving those questions, the gap picks up a **Resolved** badge and its trend starts to fall on the next detection run. Gaps that stop getting tickets age into Dormant and then Archived on their own, so there is nothing to close by hand. Archive and Restore exist on the backend but are not yet wired into the redesigned screen. Let the lifecycle sweep handle quiet gaps for now. *** ## Common issues Detection is a weekly cycle. On a brand-new workspace, results appear after the first scheduled run. Use **Sync** to force an immediate first run if you don't want to wait. Most likely it's still in **Watching** because it hasn't accumulated enough tickets yet, or the agent never attempted a KB lookup on those tickets (which routes them out of the gaps list entirely), or the tickets fall outside your current date range. Check your severity toggles too: a gap filtered out by severity looks identical to one that doesn't exist. Labels only refresh after a cluster has grown meaningfully since its last relabel. A cluster that has stopped growing keeps its old wording. This is expected. Expected. Severity uses a trailing 30-day comparison window that slides forward with today, so a bucket change without new activity is the math working, not a bug. *** ## Glossary * **Gap / cluster**: a group of similar customer questions that the knowledge base doesn't currently answer well. * **Severity**: Low, Medium, High, or Critical, driven by ticket volume and 30-day trend. * **Trend**: the 30-day change in how often a topic is coming up, compared with the prior 30-day window. * **Watching (emerging)**: questions that resemble each other but haven't yet reached enough volume to be called a confirmed gap. * **Archived**: a gap that has gone quiet for 90+ days and was either resolved or naturally faded. # Overview Source: https://docs.ravenna.ai/documentation/automate/knowledge/overview Connect knowledge sources, organize them into folders scoped to channels or agents, and power AI answers in Slack with searchable docs and wikis. Knowledge folders provide searchable documentation, wikis, and resources that power agent responses in Slack. Scope folders to specific channels or agents, sync automatically from multiple sources, and test responses before deployment. ## What you can do * Connect documentation from Slack, Notion, Google Drive, Confluence, Coda, Guru, Zendesk, and websites * Organize content into folders scoped to specific channels or agents * Test agent responses using the chat panel * Sync content automatically or on-demand * Archive outdated content while preserving it for reference ## Creating a knowledge folder Knowledge folders organize your imported content and control how agents access it through channel and agent scoping. Click the **Knowledge** tab in the left navigation. Click the **Create** button to add a new knowledge folder. Set your folder name. ### Adding documents Navigate to a knowledge folder. Documents can only exist within a parent folder. Click **Add Documents** in the top right corner. Select your knowledge source and complete the authentication flow to grant Ravenna access. ### Searching across folders Use the search bar on the Knowledge page to find folders and documents together from a single query, without opening each folder first. * Searching from the **Folders** tab matches both folder names and document titles across every folder in the workspace. * Each result shows whether it is a folder or a document, and which knowledge folder owns it. * Selecting a document result opens the document directly; selecting a folder result opens the folder with your search term preserved, so you can keep narrowing inside it. * Filters and sort apply to folder-only browsing. While a search is active, results use the search ranking instead. Use root-level search to jump straight to a specific runbook or policy when you don't remember which folder owns it. ## Knowledge sources Ravenna supports multiple knowledge sources to help you centralize your organization's information: Import messages and threads from your Slack channels. Sync your Notion pages and databases. Import documents from Google Drive. Sync your Confluence spaces and pages. Import your Coda documents and pages. Index repository files and markdown from GitHub repos connected via the GitHub App. Sync your Guru cards and collections. Import Zendesk Help Center articles. Import content from public websites. ## Testing your knowledge Test agent responses using the chat panel before deploying your knowledge to production. Click **Chat** in the top right of the KB Documents screen. Ask questions related to your imported content to see how agents respond. Update source documents based on test results, then sync to validate improvements. Use the chat panel to validate agent responses before scoping knowledge to channels or agents. ### How search works Agents use hybrid search to find relevant content: * **Semantic search**: AI embeddings understand query meaning and context, finding conceptually similar content even without exact keyword matches. * **BM25 keyword search**: Traditional text search finds exact matches and specific terminology. * **Hybrid ranking**: Results from both methods combine and rank to surface the most relevant documents. This dual approach handles both conceptual questions and specific keyword queries. ## Scoping knowledge Control which channels and agents can access specific knowledge folders. Restrict knowledge to specific Slack channels for targeted support. Navigate to your knowledge folder's Details panel. Turn off the **Knowledge to all channels** toggle. Select the specific channels that should have access to this knowledge. By default, knowledge folders are accessible from any channel where agents are present. Assign knowledge folders to specific agents to control which content each agent can access. Navigate to your knowledge folder's Details panel. Select which agents should have access to this knowledge folder. Learn how to [reference knowledge in agent rules](/documentation/automate/agents/configure#rules) Route agent knowledge lookups to different folders based on the user's question using conditional logic in agent rules. When a rule contains natural language conditions with different knowledge folder or document references in each branch, the agent searches only the sources from the matching branch. Navigate to your agent's configuration and open the Rules section. Use the **@** mention picker within your rule text to insert specific knowledge folders or documents. If a folder contains subfolders, press **Tab** or **→** to drill into it and select a nested folder or document. Selecting a folder grants the agent access to everything inside, including subfolders. Different branches of your rule can reference different knowledge sources. Write natural language conditions in your rule that direct the agent to search specific knowledge sources based on the topic. **Example rule:** IF the user asks about engineering processes, search @Engineering Docs. IF the user asks about HR policies, search @HR Handbook. Otherwise, search @General Knowledge Base. Conditional KB routing prevents the agent from searching irrelevant sources, improving response accuracy and reducing noise in answers. Channel and agent scoping work together. An agent can only access knowledge if both the channel and agent have the appropriate permissions. ## Syncing and monitoring Knowledge folders sync automatically once every 24 hours by default to keep content up-to-date. Navigate to your knowledge folder and view the Details panel on the right. Toggle auto-sync on or off in the **Auto-sync** section. Sync timing is randomized within each 24-hour period to distribute load. Trigger a manual sync to immediately update your knowledge base with the latest content from your source. Click the **Sync** button in the top right of your knowledge folder. Manual syncs run a full resync: every document in the folder is re-fetched and re-extracted from the source, regardless of whether it changed. Use this when source updates are not yet reflected in Ravenna or when a previous auto-sync missed a change. Monitor the status of your knowledge folder syncs in real-time: * **Sync state badge**: View the current sync status in the folder's Details panel * `Done`: Sync completed successfully * `In Progress`: Sync is currently running * `Queued`: Sync is scheduled to run * `Errored`: Sync encountered an error * **Progress indicator**: Track sync completion percentage for large imports * **Last sync timestamp**: See when the folder was last successfully synced * **Documents synced count**: View how many documents have been imported Sync progress updates automatically - no need to refresh the page to see the latest status. When a sync fails, Ravenna provides detailed error information to help you resolve issues: * **Error messages**: View specific error details in the folder's Details panel under "Sync state" * **Common errors**: * Authentication expired: Reconnect your integration to restore access * Source unavailable: The source content or service is temporarily inaccessible * Permission denied: Ravenna no longer has access to the content * Content not found: The source document or page has been deleted or is inaccessible * **Automatic retry**: Failed syncs are automatically retried during the next scheduled sync * **Manual retry**: Click the **Sync** button to immediately retry a failed sync * **Document preservation**: If a document disappears from the source, Ravenna marks it with an error but doesn't delete it from your knowledge base to protect content your bot depends on If a sync error persists, check your integration connection and ensure Ravenna still has the necessary permissions to access your content. ## Managing documents Ravenna preserves the organizational structure from your source systems: * **Preserved organization**: Original folder and page structures from services like Notion or Confluence are maintained in Ravenna. * **Easy navigation**: Navigate the knowledge base using the familiar structure from your source system. * **Automatic updates**: When documents are moved or reorganized in the source service, the hierarchy updates during the next sync. This mirroring approach ensures your knowledge base feels familiar and maintains the organizational logic you've already established. You can edit documents directly in Ravenna only when they were created in Ravenna. Documents synced from an external integration (Notion, Google Drive, Confluence, Coda, Guru, Zendesk, Slack, or a website) are read-only in Ravenna, and the **Edit** button is hidden on their detail view. To change the content of an externally-synced document, update it in the source system and wait for the next sync — or trigger a manual sync to pull the change in immediately. This keeps Ravenna and the source of truth in sync. Edits made in Ravenna would be overwritten on the next sync from the external source. ## Knowledge gaps Knowledge Gaps is currently in private Beta and enabled for selected customers. Reach out on Slack or in-app chat to request access. The **Gaps** tab on the Knowledge page surfaces topics where your agents could not find an answer. Each gap is a cluster of similar tickets, ranked by severity and 30-day trend, so you can prioritize what to document next. Emerging topics and cluster lifecycle are maintained automatically each week. Learn more about [Knowledge gaps](/documentation/automate/knowledge/knowledge-gaps) ## Archiving documents Archive documents and folders to exclude them from agent responses while keeping them in your knowledge base for reference. * **Selective exclusion**: Archive specific documents or entire folders to prevent them from being used in agent responses. * **Preserved structure**: Archived content remains in your knowledge base for reference but won't influence agent answers. * **Cascade archiving**: When you archive a parent folder, all child documents and subfolders are automatically archived. * **Smart sync behavior**: During auto-sync, new documents added to archived folders in your source system are automatically archived in Ravenna. * **Easy recovery**: Unarchive content anytime to make it available to agents again. Archiving is useful for: * Outdated documentation that's no longer relevant. * Deprecated processes or procedures. * Sensitive information that should be retained but not actively used by agents. * Historical content that needs to be preserved for compliance. ## Mental model Knowledge is the agent's reference library. Knowledge folders contain documents synced from external sources (Slack, Notion, Google Drive, Confluence, Coda, Guru, Zendesk, websites). When a user asks a question, the agent searches connected knowledge folders using hybrid search (semantic + keyword) and returns sourced answers. Key relationships: * One workspace has many knowledge folders. * One knowledge folder has many documents from one or more sources. * Knowledge folders are scoped to specific agents and/or channels. * An agent can only search knowledge folders explicitly connected to it. * A knowledge folder can be connected to multiple agents. Knowledge is the primary way to make the agent accurate and context-aware. Without knowledge, the agent relies solely on its base training and rules. With knowledge, it can answer questions using your organization's actual documentation. *** ## How search works The agent uses hybrid search combining two approaches: 1. **Semantic search**: AI embeddings match query meaning to document meaning. Finds conceptually similar content even without exact keyword matches. 2. **BM25 keyword search**: Traditional text matching finds exact terms and specific terminology. 3. **Hybrid ranking**: Results from both methods are combined and ranked by relevance. This means the agent handles both "What is our PTO policy?" (conceptual) and "How do I configure SAML SSO?" (specific terminology) effectively. *** ## Scoping strategies Knowledge scoping controls which agents and channels can access which folders. Two dimensions: **Channel scoping**: By default, knowledge folders are accessible from any channel where agents are present. Disable "Knowledge to all channels" to restrict a folder to specific channels. **Agent scoping**: Assign knowledge folders directly to specific agents. An agent only searches folders connected to it. Both scoping dimensions work together. An agent must have access to the folder AND be deployed in a channel that has access to the folder. Common patterns: * **Department-specific knowledge**: IT knowledge folder scoped to IT agent and IT channels only. HR knowledge folder scoped to HR agent and HR channels. * **Shared knowledge**: Company-wide policies folder available to all agents and channels. * **Sensitive knowledge**: Compliance or security documentation scoped to a single private channel and specific agent. * **Conditional routing**: Write natural language conditions in agent rules to reference different knowledge folders per branch. The agent only searches the folders from the matching branch, preventing irrelevant results. *** ## Knowledge quality patterns **What makes good knowledge content:** * Clear, well-structured documentation with headings and sections. * Frequently asked questions with direct answers. * Step-by-step procedures for common tasks. * Policy documents with clear statements. **What produces poor agent responses:** * Raw meeting notes or chat logs without structure. * Documents with outdated or contradictory information. * Very long documents without clear section breaks. * Content that relies heavily on images or tables without text context. **Improving agent accuracy:** * Use the chat panel to test agent responses before deployment. * Archive outdated documents to prevent stale answers. * Organize content into focused folders rather than one large collection. * Update source documents based on test results, then sync. *** ## Sync behavior * Knowledge folders auto-sync every 24 hours by default. Sync timing is randomized within each 24-hour period. * Manual sync is available at any time. * Sync preserves the folder hierarchy from the source system (Notion page trees, Confluence space structures). * If a document disappears from the source, Ravenna marks it with an error but does not delete it. This protects content the agent depends on. * Failed syncs retry automatically during the next scheduled sync. *** ## Constraints and gotchas * Knowledge folders are workspace-scoped. There is no cross-workspace knowledge sharing. * An agent can only search knowledge folders explicitly connected to it. Connecting a folder to a channel is not enough if the agent is not also connected. * Archived documents are excluded from agent searches but remain in the knowledge base for reference. * Archiving a parent folder cascades to all child documents and subfolders. * New documents added to an archived folder in the source system are automatically archived in Ravenna during sync. * Sync requires active integration authentication. If credentials expire, sync fails until reconnected. * Knowledge referenced in agent rules with `@Knowledge Folder Name` grants the agent access to that folder for search during rule execution. * The agent does not distinguish between knowledge sources. It searches all connected folders equally and ranks results by relevance. # Web scraping Source: https://docs.ravenna.ai/documentation/automate/knowledge/sources/website Import content from public websites by scraping single pages or crawling up to 100 pages per domain to build agent knowledge from help centers. Import content from public websites to power agent responses. Scrape individual pages or crawl entire documentation sites to build knowledge from help centers, docs, and web resources. ## What you can do * Import single pages or crawl up to 100 pages from a domain * Scrape JavaScript-rendered and formatted content * Auto-sync to keep website content up-to-date * Organize crawled sites with automatic folder structures ## Setup When adding documents to a knowledge folder, select **Website** from the available sources. Provide the URL of the webpage you want to import. Toggle crawling on to import up to 100 pages from the same domain, or leave it off to import only the single page. Content is scraped and imported from the specified URL. Learn more about [managing knowledge folders](/documentation/automate/knowledge/overview) ## How it works Browser rendering scrapes website content for accurate extraction: * Main page content and text. * Formatted content (headings, lists, paragraphs). * JavaScript-rendered content. * Publicly accessible information only. By default, content is imported from only the single URL you provide. This is ideal for: * Specific documentation pages. * Help articles. * FAQ pages. * Individual blog posts. Enable crawling to import entire documentation sites automatically: * **Automatic discovery**: Links within the same domain are followed to discover and import connected pages. * **Breadth-first crawling**: Pages are crawled level by level for comprehensive coverage. * **Page limit**: Maximum of 100 pages crawled to prevent overloading your website. * **Folder structure**: Crawled sites are organized under a root folder named after the domain. * **Same-domain only**: Crawling stays within the original domain, external links are filtered out. Crawling respects the same domain as the starting URL. External links are automatically filtered out. ## Requirements * Website must be publicly accessible (no authentication required). * Content must be available without login or paywalls. ## Managing imported content After import: * Archive pages to exclude them from agent responses. * Delete pages that are no longer needed. Learn more about [managing documents](/documentation/automate/knowledge/overview#managing-documents) ## Auto-sync When auto-sync is enabled, website content stays up-to-date: * Page content is re-scraped during sync to capture updates. * Changes to the webpage are reflected in your knowledge base. * If the page becomes unavailable, the sync fails and you're notified. Auto-sync re-scrapes the same URLs only. It does not discover new pages or follow links, even if crawling was initially enabled. # MCP server Source: https://docs.ravenna.ai/documentation/automate/mcp/overview Connect AI assistants like Claude, Cursor, and Windsurf to your Ravenna workspace through the Model Context Protocol to manage tickets and users. This feature is currently in Beta. We appreciate all feedback to help us improve this feature, so please share via Slack or via [support@ravenna.ai](mailto:support@ravenna.ai). The Ravenna MCP server lets AI assistants interact directly with your workspace through the Model Context Protocol. Instead of switching between your AI tool and the Admin, you can manage tickets, look up users, configure access policies, and more from a single conversation. The server works with ChatGPT, Claude Code, Codex, Cursor, VS Code, and any other MCP client that supports OAuth. Sign in with your Ravenna account using OAuth to securely authenticate and access your workspaces. *** ## What you can do Create, update, search, and triage tickets. Add messages, change statuses, apply tags, and link related tickets. Build workflows, manage task templates, and automate processes across your workspace. Look up users, manage group memberships, configure access policies, and handle access requests. Set up channels, categories, custom fields, ticket statuses, and other workspace settings. *** ## How it works The MCP server exposes Ravenna's API as a set of tools that AI assistants can discover and call. Your AI client connects to a single endpoint (`/mcp`) over HTTPS using Streamable HTTP. You do not need to choose or configure a transport yourself. OAuth-capable clients like ChatGPT and Claude discover Ravenna's authorization server from the MCP endpoint and sign you in with your existing Ravenna account. Your AI assistant accesses only the data and workspaces that your user account is authorized to see. *** ## Permissions and workspace targeting The MCP server enforces your existing Ravenna roles on every tool call. Your assistant can only do what your account is allowed to do in the Admin. * **Workspace tools** (most tools, including tickets, channels, custom fields, and task templates) require you to be a member of the target workspace with an allowed role. Most workspace tools allow both Admin and Member roles; some configuration tools are limited to Admins. * **Organization tools** (such as creating users) require organization admin privileges. * **Guests** (organization members without workspace membership) cannot call workspace tools for that workspace. If your role does not permit a tool, the call returns a forbidden error and your assistant reports that you do not have access. ### Targeting a workspace Because your account can span multiple workspaces, your assistant must know which workspace each call applies to. For workspace tools, the AI client passes a `workspaceId` parameter on every call. * **OAuth connections** can reach any workspace you are a member of. Tell your assistant which workspace to use, for example: *"In the IT Support workspace, list open tickets assigned to me."* Your assistant resolves the workspace and supplies the ID automatically. * **API key connections** are pinned to the workspace that issued the key. Calls targeting any other workspace are rejected, even if you are a member of it. Use OAuth if you need to work across multiple workspaces in a single session. *** ## Use cases Because MCP is an open standard, you can pair the Ravenna server with other MCP servers your AI client is connected to. This means your assistant can pull context from multiple systems in a single conversation. **Create tickets enriched with context from other tools** > "Look up Jamie Lee in HiBob, then create an onboarding ticket in the IT Support channel with their department, start date, and manager." Your AI assistant can pull data from other MCP-connected services like HiBob, Slack, or your calendar and use that context to create detailed tickets in any Ravenna workspace without you copying and pasting between apps. **Review channels and find tickets that need attention** > "Show me open tickets in the IT Support channel that have been waiting more than 48 hours. Which ones are unassigned?" Quickly scan your channels for stale or unassigned tickets. Your assistant summarizes what is waiting, highlights anything overdue, and helps you decide what to pick up or reassign. **Plan your day with your AI assistant** > "What tickets are assigned to me across all my workspaces? Prioritize them by due date and flag anything that is overdue." Use your AI assistant as a personal task tracker. Ask it to pull your assigned tickets, summarize where things stand, and help you decide what to work on next. As you work through your list, update statuses and add messages without leaving the conversation. **Bulk update tickets and close out incidents** > "Pull the resolution notes from the DNS outage post-mortem in Incident.io, then post a summary message on all open tickets tagged 'dns-outage' and move them to Resolved." Handle incident follow-up in a single conversation. Your assistant can pull context from another MCP-connected service like Incident.io, draft a stakeholder update, apply it across affected tickets, and bulk-update statuses, categories, or tags to keep your workspace organized. Ready to connect? Follow the [setup guide](/documentation/automate/mcp/setup) to configure your AI client. # Setup Source: https://docs.ravenna.ai/documentation/automate/mcp/setup Add the Ravenna MCP server to ChatGPT, Claude, Cursor, VS Code, Windsurf, and other AI clients using OAuth sign-in or a workspace API key. Connect your AI assistant to Ravenna by adding the MCP server to your client's configuration. All requests go through a single endpoint: `https://core.ravenna.ai/mcp`. Authenticate using OAuth sign-in. Your client redirects you to sign in to Ravenna with your existing account — no API keys needed. *** ## Sign in with OAuth OAuth-capable MCP clients discover Ravenna's authorization server automatically from the MCP endpoint. When you add the server, your client opens a browser window for you to sign in to Ravenna. After sign-in, the client receives an access token scoped to your user and organization, and uses it for every MCP request. **When to use OAuth:** * Your MCP client supports OAuth (for example, ChatGPT or the latest versions of Claude and Cursor). * You want to authenticate as yourself rather than share a workspace-level API key. * You do not have permission to create API keys in your workspace. **How to connect:** In your client's MCP settings, add a server pointing to `https://core.ravenna.ai/mcp`. Do not set an `Authorization` header — your client handles the token automatically once OAuth completes. Your client opens a browser window to Ravenna's sign-in page. Authenticate with your Ravenna account, then approve the connection. The browser window closes automatically when sign-in completes. Return to your client and ask your assistant to list its Ravenna tools. The tools become available immediately once the token is issued. OAuth tokens are scoped to your user account and grant access to all workspaces and data that your account has permissions to access. Your assistant can work across any of your workspaces in a single session. *** ## Configure your AI client ### ChatGPT ChatGPT connects to Ravenna using OAuth sign-in. You add the MCP server URL in ChatGPT's connector settings, then sign in to Ravenna in a browser pop-up. No API key required. In ChatGPT, open **Settings** → **Connectors** → **Add custom connector**. Fill in the details: 1. **Name:** `Ravenna` 2. **MCP Server URL:** `https://core.ravenna.ai/mcp` 3. Leave the authentication field set to OAuth. Click **Connect**. A browser window opens to Ravenna's sign-in page. Authenticate with your Ravenna account and approve the connection. Start a new ChatGPT conversation and ask it to list your Ravenna tools to confirm the connection. Your ChatGPT connection is scoped to your user account and grants access to all workspaces you have permissions for. Specify which workspace you want to work with when prompting your assistant. *** ### Claude Code Claude Code supports OAuth authentication for MCP servers. A single terminal command registers the Ravenna server and initiates the OAuth flow. Run the command below in your terminal. The `--callback-port 56567` option is critical for the OAuth callback. ```bash Terminal theme={"system"} claude mcp add ravenna \ --transport http \ https://core.ravenna.ai/mcp \ --callback-port 56567 ``` Your browser will open automatically for you to sign in to Ravenna. Authenticate with your Ravenna account and approve the connection. The browser window closes automatically when sign-in completes. Open a new Claude Code session. The Ravenna tools will be available automatically. Ask Claude Code to list your Ravenna channels to confirm the connection works. You can also run `/mcp` to check the server status. Your OAuth token is scoped to your user account and grants access to all workspaces you have permissions for. You can work across any of your workspaces in a single session. Learn more about [MCP servers in Claude Code](https://code.claude.com/docs/en/mcp) *** ### Codex Codex supports OAuth authentication for MCP servers. Configuration is stored in a `config.toml` file. Codex stores MCP configuration in `config.toml`. The exact location depends on your platform: * **macOS:** `~/Library/Application Support/Codex/config.toml` * **Linux:** `~/.config/codex/config.toml` * **Windows:** `%APPDATA%\Codex\config.toml` Add the following to your `config.toml`: ```toml config.toml theme={"system"} # Set a fixed OAuth callback port (required by Ravenna) mcp_oauth_callback_port = 56567 [mcp_servers.ravenna] url = "https://core.ravenna.ai/mcp" ``` Run the login command to initiate the OAuth flow: ```bash Terminal theme={"system"} codex mcp login ravenna ``` Your browser will open automatically. Sign in to Ravenna and approve the connection. Start Codex and ask it to list your Ravenna channels to confirm the connection works. The OAuth callback port setting is shared across all MCP servers in Codex. If you connect to multiple OAuth-based MCP servers, they'll all use port 56567. Learn more about [MCP servers in Codex](https://developers.openai.com/codex/mcp) *** ### Claude Desktop Claude Desktop can connect to Ravenna using the `mcp-remote` package, which bridges the remote HTTP MCP server to Claude Desktop's stdio-based MCP protocol. Claude Desktop stores MCP configuration in `claude_desktop_config.json`. The location depends on your platform: * **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json` * **Windows:** `%APPDATA%\Claude\claude_desktop_config.json` Add the following configuration to your `claude_desktop_config.json`: ```json claude_desktop_config.json theme={"system"} { "mcpServers": { "ravenna": { "command": "npx", "args": [ "mcp-remote@latest", "https://core.ravenna.ai/mcp", "56567", "--host", "127.0.0.1" ] } } } ``` Restart Claude Desktop to load the new MCP server configuration. When you first use the Ravenna MCP server, Claude Desktop will prompt an OAuth flow. Your browser will open automatically for you to sign in to Ravenna. Authenticate with your Ravenna account and approve the connection. Ask Claude to list your Ravenna tools to confirm the connection works. The `mcp-remote` package acts as a bridge, allowing Claude Desktop (which uses stdio-based MCP) to connect to HTTP-based MCP servers like Ravenna. Port 56567 is used for the OAuth callback flow. *** ### Cursor Cursor supports OAuth authentication for MCP servers. Add the Ravenna server to `.cursor/mcp.json` and Cursor handles the OAuth sign-in flow automatically the first time you connect. Create or edit `.cursor/mcp.json` in your project root. For global access across all projects, use `~/.cursor/mcp.json` in your home directory instead. Add the following configuration: ```json .cursor/mcp.json theme={"system"} { "mcpServers": { "ravenna": { "url": "https://core.ravenna.ai/mcp" } } } ``` Do not add an `Authorization` header — Cursor handles OAuth automatically once you sign in. Open **Cursor Settings** → **Tools & MCP**. Ravenna appears in the MCP servers list. Toggle it on if it is not already enabled. The first time you use the server, Cursor opens a browser window to Ravenna's sign-in page. Authenticate with your Ravenna account and approve the connection. Ask Cursor to list your Ravenna channels to confirm the connection works. Your OAuth token is scoped to your user account and grants access to all workspaces you have permissions for. Learn more about [MCP servers in Cursor](https://cursor.com/docs/mcp) *** ### VS Code VS Code supports OAuth authentication for MCP servers through GitHub Copilot. The OAuth callback URL is `http://127.0.0.1:33418/` and is automatically handled by VS Code. Create a file called `.vscode/mcp.json` in your project root. For global access across all projects, add the configuration to your VS Code User Settings JSON instead. Add the following configuration to `.vscode/mcp.json`: ```json .vscode/mcp.json theme={"system"} { "servers": { "ravenna": { "type": "http", "url": "https://core.ravenna.ai/mcp" } } } ``` Note: Do not add an `Authorization` header — VS Code handles OAuth authentication automatically. Reload the window or restart VS Code to load the new MCP server configuration. When you first use the Ravenna MCP server, VS Code will prompt you to authenticate. Your browser will open automatically for you to sign in to Ravenna. Authenticate with your Ravenna account and approve the connection. Ravenna tools will be available through GitHub Copilot Chat in agent mode. Ask your assistant to list your Ravenna channels to confirm the connection works. Your OAuth token is scoped to your user account and grants access to all workspaces you have permissions for. You can work across any of your workspaces in a single session. Learn more about [MCP servers in VS Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) *** ### Other MCP clients If your MCP client is not listed above, you can still connect it to Ravenna as long as it supports OAuth and remote HTTP servers. If you're using a client that does not yet support OAuth for remote MCP servers, reach out to us at [support@ravenna.ai](mailto:support@ravenna.ai) to discuss alternative authentication methods. #### Custom MCP clients Any MCP-compatible client that supports OAuth and remote HTTP servers can connect to Ravenna. Use these connection details: * **URL:** `https://core.ravenna.ai/mcp` * **Transport:** Streamable HTTP (may be labeled `http` or `streamable-http`) * **Authentication:** OAuth 2.0 with automatic discovery * **Callback URL:** Most clients handle this automatically. Common defaults: * VS Code: `http://127.0.0.1:33418/` * Claude Code: Configurable via `--callback-port` * Cursor: `cursor://anysphere.cursor-mcp/oauth/callback` Your client should automatically discover Ravenna's authorization server from the MCP endpoint and prompt you to sign in. Refer to your client's documentation for OAuth-based MCP server setup. The `/mcp` endpoint uses Streamable HTTP and automatically discovers OAuth authorization server metadata. Ravenna's OAuth implementation supports the standard callback URLs used by popular MCP clients. *** ## Test your connection Ask your AI assistant: "What Ravenna tools do you have available?" It should list the available MCP tools. Try a basic read operation like "List my Ravenna channels" or "Get the current user." Confirm that the response contains actual data from your workspace, like real channel names or your user profile. *** ## Troubleshooting * Verify your configuration file is in the correct location for your client. * Check that the JSON is valid (no trailing commas, correct nesting). * Restart your AI client completely after making configuration changes. * Confirm the server URL is exactly `https://core.ravenna.ai/mcp`. * Check that your API key is correct and has not been revoked. * Verify the `Authorization` header uses the `Bearer` prefix with a space before the token. * Ensure there are no extra spaces or newline characters in your key value. * If your key has **Allowed IP ranges** configured, confirm your client's public egress IP is inside one of those ranges. Requests from outside the allowlist return `403 Forbidden` and do not include a `WWW-Authenticate` header, and the error deliberately does not reveal that the key is IP-scoped. See [Restrict a key to specific IP ranges](/api/overview#restrict-a-key-to-specific-ip-ranges). * Confirm your API key is scoped to the workspace you expect. * Verify that your user account has the necessary permissions to access the requested data. * Try a simple operation like "get current user" to isolate whether the issue is with authentication or with a specific tool. The MCP server enforces your workspace and organization roles on every tool call. * Some tools require an Admin role in the target workspace. Member or Guest accounts cannot call them. * A few tools (such as creating users) require organization admin privileges. * Confirm your role in the target workspace from **Settings** → **Members** in the Admin, and ask a workspace admin to upgrade your role if needed. For tools that operate on a specific workspace, your assistant supplies a `workspaceId` on each call. * If your assistant targets the wrong workspace, name the workspace explicitly in your prompt (for example, *"In the IT Support workspace, ..."*). * If you connected with an API key, your session is pinned to the workspace that issued the key. Calls to any other workspace are rejected even if you are a member. Switch to OAuth to work across multiple workspaces. * A "workspace membership not found" error means your user account is not a member of the workspace you targeted. Add yourself to the workspace, or pick one you belong to. * Some clients maintain a persistent connection to the server. If your network is interrupted, restart the client to reconnect. * If the connection drops after a period of inactivity, this is expected. Start a new conversation or restart the client. * Check that your network allows long-lived HTTPS connections and does not have aggressive idle timeouts. Learn more about [available MCP tools](/documentation/automate/mcp/tools) # Available tools Source: https://docs.ravenna.ai/documentation/automate/mcp/tools Browse Ravenna MCP tools by domain including ticket management, user administration, access control, workflows, analytics, and workspace configuration. The Ravenna MCP server provides tools covering ticket management, user administration, access control, workflows, analytics, and workspace configuration. Your AI client automatically discovers tool schemas and parameters when it connects to the server. You do not need to memorize tool names or parameters. Your AI client discovers them automatically. This page helps you understand what is possible so you can ask your assistant the right questions. **Tool calls with unknown parameters are rejected.** If your client sends a parameter that is not in a tool's advertised input schema (for example, inventing `assigneeIds` on `search_tickets`), the call is rejected with an error naming the unrecognized keys and listing the accepted set. Nothing runs, so an invented filter cannot silently drop and return an unfiltered result set. Check the tool's `inputSchema` and retry with the parameter names it advertises. *** ## Tickets Manage the full lifecycle of tickets in your workspace. Fetch full details for a specific ticket including messages, status, and metadata. * Review complete ticket history * Check current status and assignee * Retrieve custom field values Create a new ticket with a title, description, and optional fields like priority, category, and assignee. * Log new requests from conversations * Create follow-up tickets from existing work **Attach the matching form.** Call `list_forms` first to find the form that covers the request, and pass its id as `requestTypeId`. Put form field values in `customFields` (keyed by `custom_field_id` from `list_forms` or `get_form`), and workspace ticket attributes in `attributeFields`. The two are separate maps. Call `get_form` only when you need the option ids for a `SELECT` or `MULTI_SELECT` field. **Only Published forms can be attached.** Passing a `requestTypeId` whose form status is `Draft` or `Archived` is rejected with `FORM_NOT_PUBLISHED` and nothing is created. An id that does not exist in the current workspace is rejected with `FORM_NOT_FOUND`. **`unsetFields` on the response.** When the created ticket has no value for one or more of its form fields or workspace attributes, the response includes an `unsetFields` array. Each entry carries `custom_field_id`, `label`, `type`, `required`, and `source` (`"form"` or `"attribute"`). The field is advisory. The ticket is created regardless, and conditionally hidden fields and fields you lack permission to set are excluded. Fill any of the listed fields you have support for with `update_ticket`; leave the rest alone rather than guessing. | Parameter | Type | Required | Description | | --------- | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `files` | array of objects | No | File attachments. Each object requires `name` (filename), `content` (base64-encoded file content), and `mimeType` (MIME type like "application/pdf" or "image/png"). | Modify ticket fields such as status, priority, assignee, category, or custom fields. * Reassign tickets during triage * Update priority based on new information * Change status as work progresses * Move a ticket to a channel in another workspace the caller belongs to Setting `queueId` to a channel in another workspace triggers a cross-workspace move. The caller must be a member of the destination workspace (admin or member); otherwise the tool rejects the call. A cross-workspace move must be its own call: pass only `id` and `queueId`, with no other fields, files, or task template changes set. The move carries the ticket's tags, category, and attributes into the destination by name (reusing destination rows where they exist and creating them where they don't), re-points the status to the destination status of the same label (falling back to Open), and clears the form and parent link. See [Move tickets](/documentation/tickets/move-tickets) for the full behavior. **Switching the ticket's form.** Passing a new `requestTypeId` swaps the form on the ticket. The new form must be Published; a `Draft` or `Archived` form is rejected with `FORM_NOT_PUBLISHED`, and an id not in the workspace is rejected with `FORM_NOT_FOUND`. The guard only fires when the form is actually changing. A ticket already sitting on a form that has since been unpublished can still be updated without re-attaching it. | Parameter | Type | Required | Description | | --------- | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `queueId` | string | No | Destination channel ID. Use `List channels` (with `targetWorkspaceId` for another workspace) to find one. | | `files` | array of objects | No | File attachments. Each object requires `name` (filename), `content` (base64-encoded file content), and `mimeType` (MIME type like "application/pdf" or "image/png"). | Perform semantic search across tickets to find relevant results by meaning, not just exact keywords. * Find related tickets when investigating an issue * Search across all ticket content including messages **Filter columns.** Alongside `priority`, `type`, `assigneeId`, `queueId`, `requestTypeId`, `requesterId`, `source`, `tags`, `createdAt`, `updatedAt`, `resolvedAt`, and `dueAt`, the tool also filters on `categoryId`, `parentId`, `approvalStatus`, `slaStatus`, `slaBreachingIn`, `csatScore`, `closedAt`, `respondedAt`, `snoozed`, and `archived`. Filter by ticket status through the top-level `status` argument rather than a filter row. `slaStatus` and `slaBreachingIn` answer different questions. `slaStatus` is a finished outcome — use it for tickets that already met or breached a target. `slaBreachingIn` is the at-risk filter: pass `equals` with a single positive number of minutes (for example, `"60"`) to match tickets whose pending SLA target breaches within that window. Already-breached targets never match `slaBreachingIn`. Each filter is validated against its column's vocabulary before the query runs. An unknown `approvalStatus` or `slaStatus` value, a non-numeric `csatScore`, an `slaBreachingIn` filter that is not `equals` with a single positive number, or a `snoozed`/`archived` filter that is not `equals` with `"true"` or `"false"` is rejected with a message listing the accepted values instead of returning an unfiltered result set. Archived and snoozed tickets are excluded unless you pass the corresponding filter. **Filter by custom field value.** Set `column` to `attributeFields.` to filter on a workspace ticket attribute, or `customFields.` to filter on a value captured by a form field. `SELECT` and `MULTI_SELECT` fields accept either the option id or the option's display text as `value`. Use the wrong prefix and the tool returns an error naming the correct prefix for that field. Custom field filters require a specific workspace and are reported back on `field_filters` in the response, separately from the scalar `filters` array. ```json Example: filter by attribute and form field values theme={"system"} { "filters": [ { "column": "priority", "operation": "equals", "value": "HIGH" }, { "column": "attributeFields.cf_impacted_app", "operation": "in", "value": ["Okta"] }, { "column": "customFields.cf_department", "operation": "equals", "value": "Engineering" }, { "column": "archived", "operation": "equals", "value": "false" } ] } ``` Given one source ticket, return that requester's other tickets that are semantically similar to it. Use this to answer "has this person already filed this?" before creating a new ticket or during triage. * Detect duplicates for a specific ticket by id, short id, or display id (e.g. `IT-42`) * Tune how strict the match is with a similarity threshold (0-100) * Cap how many matches come back, most similar first Results are scoped to the same requester as the source ticket. A source ticket with no requester returns no matches, and tickets without embeddings are skipped. Retrieve child tickets linked to a parent ticket. * View sub-tasks of a larger project * Track progress across related work items ### Ticket messages Add and manage messages on tickets to track communication and progress. To read a ticket's messages, use `Get ticket by ID`, which returns the conversation history alongside the ticket's other details. Add a new message to a ticket. * Post updates or status changes * Add internal notes for your team * Reply to requester questions | Parameter | Type | Required | Description | | --------- | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `files` | array of objects | No | File attachments. Each object requires `name` (filename), `content` (base64-encoded file content), and `mimeType` (MIME type like "application/pdf" or "image/png"). | Edit an existing message on a ticket. * Correct information in a previous update * Add additional context to a message | Parameter | Type | Required | Description | | --------- | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `files` | array of objects | No | File attachments. Each object requires `name` (filename), `content` (base64-encoded file content), and `mimeType` (MIME type like "application/pdf" or "image/png"). | ### Ticket statuses Define and manage the status options available for tickets in your workspace. Retrieve all ticket statuses configured in the workspace. * View available status options for ticket updates * Audit your status workflow Fetch details for a specific status. * Check status configuration and properties Add a new status option to the workspace. * Extend your workflow with additional stages * Add custom statuses for specific processes Modify an existing status, such as its name or order. * Rename statuses to match updated workflows * Reorder statuses in the pipeline Remove a status from the workspace. * Clean up unused status options * Simplify your ticket workflow Retrieve the number of tickets in each status. * Generate quick status reports * Monitor queue health and workload distribution * Identify bottlenecks in your workflow ### Ticket tags Organize and classify tickets with tags. Search tags in the workspace by name, or retrieve the full list. * Find available tags before applying them * Audit tag usage across the workspace Create a new tag for classifying tickets. * Add tags for new projects or initiatives * Create tags for specific issue types Modify a tag's name or properties. * Rename tags to match updated conventions ### Ticket links Create relationships between tickets and external resources. Retrieve all links associated with a ticket. * View connected tickets and external references * Audit relationships between work items Create a new link between tickets or to an external resource. * Connect related tickets for tracking * Link tickets to external tools like Jira or Linear Remove a link from a ticket. * Detach a link that was added to the wrong ticket * Clean up outdated references ### Task items Manage individual task items within tickets for granular work tracking. To view a ticket's checklist, use `Get ticket by ID`, which returns its task items. Retrieve task items assigned to the current user across the current workspace. * View your personal task list with linked ticket context (queue and ticket number) * Filter by completion status to focus on open work * Paginate through results for large task lists Add a new task item to a ticket. * Break down tickets into actionable steps * Add checklist items during triage Modify a task item, such as marking it complete or changing its description. * Track progress on individual steps * Update task details as requirements change Deleting task items is not available over MCP. Remove them from the ticket in the Ravenna app. ### Task templates Create and manage reusable task templates that can be applied to tickets. Retrieve all task templates in the workspace. * View available templates for common processes * Audit template usage Fetch details for a specific task template including its items. * Review template content before applying * Check template configuration Create a new task template with a set of predefined items. * Standardize processes like onboarding or incident response * Create checklists for recurring procedures Modify an existing task template. * Add or remove items from a template * Update template names or descriptions ### Categories Manage the ticket categories the AI classifier assigns to incoming tickets. Each category has a name, an optional description, and example phrases the classifier reads to pick a category. Categories are flat, with no nesting. Exactly one category is the workspace default, used as the fallback when the classifier finds no better match. Retrieve categories in the workspace, with each entry's name, description, classifier examples, and whether it is the default. * Review how tickets are being classified * Look up a category ID before updating it * Filter by name with an optional case-insensitive substring search Add a new category with a name, optional description, and example phrases. Names must be unique in the workspace (case-insensitive). The first category created in a workspace automatically becomes the default; after that, pass `is_default: true` to promote the new category and demote the current one. * Add a category for a new service area * Seed the classifier with example phrases users would send * Set a new fallback category for unmatched tickets Change a category's name, description, examples, or default status. Only the fields you pass are changed, and `examples` replaces the existing list wholesale, so include the phrases you want to keep. Setting `is_default: true` promotes this category and demotes the current default; `is_default: false` is rejected because a workspace always needs exactly one default. * Rename a category * Refine the description or example phrases to improve classification * Promote a different category to be the default Delete a category by ID. The default category cannot be deleted; promote another category to be the default first. * Remove categories that are no longer relevant * Consolidate overlapping categories ### Channels Manage the channels (queues) where tickets are received and organized. Retrieve all channels in the workspace. * View your channel structure * Find channels for ticket routing * Look up a destination channel in another workspace before a cross-workspace ticket move By default the results come from the current workspace. To list channels in another workspace, pass `targetWorkspaceId`. The caller must be a member (admin or member) of that workspace; otherwise the tool rejects the call. This is intended for finding the destination of a cross-workspace ticket move. Omit it for everything else. Get workspace IDs from `Get current user context` rather than guessing. | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | ------------------------------------------------------------------------------------ | | `targetWorkspaceId` | string | No | List channels in another workspace the caller belongs to instead of the current one. | Create a new channel for receiving tickets. * Set up channels for new teams or service areas * Create dedicated channels for specific ticket types Modify channel settings such as name, description, or configuration. * Update channel details as team structures change List the Slack channels available to connect to Ravenna: every channel the Ravenna Slack bot has been invited to, each marked with the Ravenna channel it already feeds. * Find candidate Slack channels before connecting one to a Ravenna channel * Check which Slack channels are already connected ### Forms Discover the [forms](/documentation/tickets/forms/overview) available in the workspace, inspect the fields they capture, and build new ones. Use the read tools to pick the right form for a new ticket before calling `create_ticket`. Every form starts in Draft and is invisible to end users until you publish it with `update_form`. `create_form` accepts full form configuration and an ordered `fields[]` array in one call, so a typical authoring flow is: check `list_forms` for a name collision, call `create_form` with settings and fields, iterate with the field and reorder tools, then publish. **Deleting a whole form is not exposed over MCP.** These tools can create, configure, publish, unpublish, and remove individual fields, but the destructive delete-form action is only available inside Ravenna Copilot. To retire a form, unpublish it with `update_form` (`status: "Draft"`) and delete it from the Admin UI. Retrieve every form and collection in the workspace with enough detail to pick the right one for a request and know what it will capture. Each form entry includes: * `id`: pass this as `requestTypeId` to `create_ticket`, `update_ticket`, and `search_tickets`. * `name`, `description`, and `status` (`Draft`, `Published`, or `Archived`). Only Published forms can be attached to a ticket. * `isDefault`: true when this is the workspace's default form. * `channels[]`: the channels this form is attached to, as `{ id, name }`. Use `channels[].id` as `queueId` on `create_ticket`. Empty means the form is not scoped to a channel. * `defaultChannelId`: the channel this form's tickets land in by default, or `null`. * `parentId`: parent collection id, if any. * `formEnabled`: true when the form has custom fields. * `fields[]`: a per-field summary carrying the field's `id` (used by another field's `parentId`), `custom_field_id` (the key to use in `customFields`), `name`, `description`, `type` (`TEXT`, `TEXT_AREA`, `SELECT`, `MULTI_SELECT`, `DATE`, `NUMBER`, `BOOLEAN`, `USER_SELECT`, ...), `required`, `hidden`, `private`, and conditional-visibility `parentId` and `dependsOnValue`. Optionally filter by a search term. Call `get_form` only when you need the option ids for a `SELECT` or `MULTI_SELECT` field, or the form's full usage counts. * Pick the form that matches a request before creating a ticket * Discover which fields a form will require so you can gather values in one turn * Find the `queueId` for a form-attached channel * Check for a name collision before calling `create_form` * Find the id of an existing form to update or add fields to Fetch full detail for one form by id, including its ordered fields, every field's option list and validation rules, each field's `id` (RTCF join id) and `private` flag, and usage counts. * Look up the option ids for a `SELECT` or `MULTI_SELECT` field before filling it * Inspect a form's full configuration when `list_forms` is not detailed enough * Read the current field order before calling `reorder_form_fields` * Look up a field's RTCF id and `private` flag before calling `remove_form_field` Create a new form with full configuration and an optional ordered `fields[]` array in one call. Covers name, description, icon/color/emoji, defaults (priority, channel, ticket type, task template), title template, audience targeting, tags, and assigned agents. * Author a complete intake form in a single call rather than create-then-update * Add top-level fields at creation; each field needs a `label` and `type`, and `SELECT` / `MULTI_SELECT` also need `options` * Nest inside a collection by passing `parentId` Forms are created as Draft. Publish afterward with `update_form` (`status: "Published"`). Conditional child fields (with `parentId` and `dependsOnValue`) are not created here. Add them afterward with `create_form_field`, referencing the parent field id returned by `get_form`. **Title templates.** Write placeholders as the field's LABEL in double braces (`{{Location}}`), not a field key. The tool wires each placeholder to the field it creates. `{{requester}}` and `{{requestType}}` are always available. A placeholder that matches no field label renders empty and is reported back on `partialApply` so you can fix it with `update_form`. **Audience.** Set `audienceType` to `Specific` together with `allowedGroupIds` to restrict the form to certain user groups. `Everyone` and `WorkspaceMembers` ignore `allowedGroupIds`. **Partial success.** If the form is created but a follow-up step (nesting, a field, or the settings update) fails, the response includes a `partialApply` string describing what to retry with `update_form` or `create_form_field`. Do not re-call `create_form`, because the form already exists. Update an existing form's settings. Provide the form id and only the fields you are changing; omit the rest. * Publish a form by passing `status: "Published"`, or unpublish back to editable with `status: "Draft"` * Change defaults (priority, channel, ticket type, status, task template) or the title template * Adjust visibility (`audienceType`, `allowedGroupIds`, `isPrivate`, `featuredInPortal`) and visual style (`icon`, `color`) * Reassign tags or agents `tags` and `agents` **replace** the existing set, so send the full list you want, not just additions. Resolve ids first with `search_tags`, `list_agents`, `list_user_groups`, and `search_task_templates`. Use `update_form` only for existing forms; for field-level configuration like allow lists or source filters, use `edit_form_field`. Create a collection (folder) that groups related forms. Pass a name, optional description, and optional `parentId` to nest it inside another collection. * Group related intake forms under one folder * Returns the collection id, which you pass as `parentId` to `create_form` or `update_form` to place a form inside This creates a folder, not an intake form. Use `create_form` for an actual form. Add a field to an existing form. Pass `request_type_id`, `label`, and `type`; `SELECT` and `MULTI_SELECT` require `options`. * Add fields that were not part of the initial `create_form` call * Add conditional child fields by passing a parent field id and `dependsOnValue` * Fields created here are private to the form by default Modify an existing field on a form: label, type-specific configuration, allow list, source filters, and other field-level settings. * Rename a field or change its help text * Adjust allow lists or source filters * Update options on a `SELECT` or `MULTI_SELECT` Attach a **shared** field (one whose definition already exists on another form) to this form. * Reuse a workspace-level field across multiple forms * Re-attach a shared field that was previously detached with `remove_form_field` Fields created with `create_form_field` are private and cannot be re-attached after removal. Remove a field from a form by its RTCF id (the `id` returned per field by `get_form`). There are two outcomes, so check the field's `private` flag on `get_form` first: * **Shared field** (`private: false`): only the attachment to this form is removed. The field definition survives and stays on other forms. Reversible with `attach_form_field`. * **Private field** (`private: true`): the field definition is **permanently deleted**, along with any conditional child fields. Not reversible. Every field created with `create_form_field` is private, so this is the common case. To remove a private field you must pass `confirm_delete_private_field: true`, or the call is rejected. Reorder all top-level fields on a form in one call. Pass `request_type_id` and `ordered_field_ids`: the **complete** set of the form's field RTCF ids (from `get_form`), in the desired top-to-bottom order. * Move a single field by reading the current order from `get_form`, repositioning that id, and sending the whole list back * Rearrange the entire form at once A partial list, one with missing or duplicated ids or ids from other forms, is rejected, because leaving fields out would produce duplicate or ambiguous ordering. ### Custom fields Define custom data fields that can be added to ticket forms. Retrieve all custom fields in the workspace. * View available fields for form configuration * Audit field usage across forms Fetch details for a specific custom field. * Check field type, validation, and configuration Create a standalone field in the workspace field library, attached to no form. The result is a shared field you can put on any form later with `attach_form_field`, and optionally register as a [ticket attribute](/documentation/tickets/forms/attributes) shown on every ticket. * Add a re-usable field once, then attach it to multiple forms * Create a ticket attribute in the same call by passing `is_attribute: true` * Prefer this over `create_form_field` when the field is not scoped to a single form Provide `label` and `type`. `SELECT` and `MULTI_SELECT` require an `options` list. Entity-picker types (for example `USER_SELECT`, `APPLICATION_SELECT`, `USER_GROUP_SELECT`) are system-managed and do not take `options`; use `allowList` and, for user/group pickers, `source` to restrict the picker. **Ticket attributes.** Passing `is_attribute: true` also surfaces the field on every ticket in the workspace. Only `TEXT`, `TEXT_AREA`, `DATE`, `DATETIME`, `BOOLEAN`, `SELECT`, `MULTI_SELECT`, `USER_SELECT`, and `USER_MULTI_SELECT` are attribute-eligible; other types return an error. Set attribute values later via the `attributeFields` key on `create_ticket` / `update_ticket`. Requiredness is form-local and is not set here. Pass `required` when you attach the field to a form. Check `list_custom_fields` before calling to avoid a duplicate; re-use an existing field with `attach_form_field` if one already matches. To edit or remove a field that is attached to a form, use `edit_form_field` and `remove_form_field` (see [Forms](#forms)). Updating or deleting a standalone workspace field is not available over MCP; manage those from **Settings > Fields** in the Ravenna app. ### Custom field options Read the selectable options for dropdown-type custom fields. Retrieve all options for a custom field. * View available choices for a dropdown field ### Snippets Manage the reusable [snippets](/documentation/tickets/snippets) agents insert into ticket replies. Retrieve saved snippets in the workspace, with optional filters. * Find a saved response to insert into a ticket reply * Audit the snippet library Save a response as a reusable snippet for future tickets. * Turn a well-written reply into a standard response Revise an existing snippet. * Keep saved responses current as processes change ### Reminders Read and configure the workspace [reminder policies](/documentation/tickets/reminders) that nudge pending approvers and ticket assignees on a recurring schedule. Each workspace has at most one policy of each type: `APPROVAL` (nudges pending approvers on an open approval round) and `ASSIGNMENT` (nudges the current assignee of an open ticket). Both tools are admin-only. Callers without the workspace `Admin` role are rejected. The same policies power the **Settings → Workspace → Automation** UI, so changes here take effect immediately for all reminders in that workspace. Read the current reminder policies for the workspace. A policy type absent from the results has no policy yet, so those reminders are off. * Check whether approval or assignment reminders are enabled before configuring them * Audit the interval, cap, business schedule, and conditions on each policy | Parameter | Type | Required | Description | | --------- | ------ | -------- | ------------------------------------------------------------------------------ | | `type` | string | No | Return only this policy type: `APPROVAL` or `ASSIGNMENT`. Omit to return both. | Create or update a reminder policy for one type. Uses patch semantics: only the fields you pass change, the rest keep their current values. When creating a policy for the first time, `enabled` defaults to `false` and `interval_hours` to `24` unless you set them. * Turn approval or assignment reminders on or off * Adjust the interval, cap, or business schedule without touching other fields * Scope a policy to a subset of tickets with filter groups | Parameter | Type | Required | Description | | ---------------- | --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `type` | string | Yes | Which policy to configure: `APPROVAL` or `ASSIGNMENT`. | | `enabled` | boolean | No | Turn the policy on or off. Omit to leave unchanged. | | `interval_hours` | number | No | How often to send a reminder, in hours. Omit to leave unchanged. | | `max_reminders` | integer or null | No | Cap on total reminders sent per ticket. Pass `null` for unlimited. Omit to leave unchanged. | | `schedule_id` | string or null | No | [Business schedule](/documentation/platform/workspaces/settings#business-schedules) whose working hours reminders are confined to. Pass `null` to send around the clock. Omit to leave unchanged. | | `filter_groups` | array or null | No | Filter groups limiting which tickets the policy applies to. Outer array is OR, inner is AND. Pass `null` to apply to all tickets. Omit to leave unchanged. | Learn more about [reminder policies](/documentation/tickets/reminders), including how the interval, cap, business schedule, and conditions behave at fire time. *** ## Platform ### Users Look up and manage user accounts in your organization. Retrieve the profile of the authenticated user. * Verify your connection and identity * Check your own permissions and role Retrieve all users in the organization. * Find users for ticket assignment * Generate user reports * Audit organization membership Fetch details for a specific user by ID. * Look up a user's profile, role, and group memberships * Verify user details for access requests Modify a user's profile or settings. * Update user roles or properties * Manage user account details Create a new user in the organization and optionally add them to a workspace. Requires organization admin privileges. * Onboard new team members by creating their account and workspace membership in one step * Create user accounts without sending invitation emails for pre-provisioned setups * Add users to a specific workspace with a designated role (Guest, Member, or Admin) ### User groups Organize users into groups for permissions, assignment, and routing. Retrieve all user groups in the organization. * View team structure and group organization * Find groups for routing rules Fetch details for a specific group. * Check group configuration and membership count Retrieve a group along with its full member list. * See who belongs to a specific team * Audit group membership for compliance Create a new user group. * Set up groups for new teams or departments * Create groups for access control policies Modify a group's name, description, or membership. * Update group details as teams change * Add or remove members from a group ### Organization members View members of your organization with full user details. Retrieve all organization members with full user profile details. * Generate organization-wide user reports * Audit who has access to the organization * Look up members across all workspaces ### Workspaces Manage the workspaces within your organization. Fetch details for a specific workspace. * Check workspace configuration and settings Modify workspace settings. * Update workspace name, description, or configuration Slack emoji-action bindings are not part of this tool's input. Use `configure_slack_emoji_action` (below) to change which emoji triggers a Ravenna action. ### Business schedules Manage the [business schedules](/documentation/platform/workspaces/settings#business-schedules) that define working hours for SLAs and reminders. Retrieve business hour schedules for the workspace, including name, timezone, weekly hours, and holiday configuration. * Look up a schedule ID before attaching it to a reminder policy * Audit working hours and holidays Create a business hour schedule with a name, IANA timezone, and weekly hours with time ranges per day. * Set up working hours for a new team or region Update a schedule. Supports partial updates to name, timezone, weekly hours, holidays, or default status. * Adjust hours or holidays as they change * Promote a schedule to be the workspace default ### Slack emoji actions Read and remap the [Slack emoji actions](/integrations/slack/emoji-actions) for the workspace: the reactions that create tickets, assign work, resolve tickets, and more when added to a Slack message. Retrieve every configurable emoji action in the workspace. Each entry includes the `action` key, a human-readable label and description, the emoji shortcode and native character currently bound to it, the default shortcode, and whether the action is still on its default. * See which emoji currently triggers each action * Find custom bindings by checking `isDefault` * Get the exact `action` keys before calling `configure_slack_emoji_action` Bind a Slack emoji to a Ravenna action, or reset the action to its default emoji. Pass an `action` key from `list_slack_emoji_actions` together with either an `emoji` or `reset_to_default: true`. * Remap an action to an emoji your team already uses * Restore an action to its default binding The `emoji` value can be a native glyph (`✅`), a shortcode (`white_check_mark`, with or without colons), or a recognized alias. An unrecognized value is rejected with `INVALID_EMOJI` and nothing changes. Each emoji can map to only one action. Binding an emoji that already triggers another action is rejected with `EMOJI_SHORTCODE_IN_USE`, naming the conflicting action. Reset that action first or pick a different emoji. | Parameter | Type | Required | Description | | ------------------ | ------- | -------- | --------------------------------------------------------------------------------------------- | | `action` | string | Yes | The Ravenna action to configure, from `list_slack_emoji_actions`. | | `emoji` | string | No | Emoji to bind: native glyph, shortcode, or alias. Required unless `reset_to_default` is true. | | `reset_to_default` | boolean | No | Restore the action's default emoji, removing any custom binding. | Learn more about [Slack emoji actions](/integrations/slack/emoji-actions), including what each action does and who can trigger it. ### Workspace members View members of a specific workspace. Retrieve all members of a workspace. * View who has access to a specific workspace * Audit workspace membership Retrieve workspace members with full user profile data. * Generate workspace-specific user reports * Look up member details for assignment or routing ### Applications Manage the applications in your organization that users can request access to. Search the application catalog with `search_applications`. Pass `query` to filter case-insensitively on name, display name, and domain (space-separated words must all match), or omit it to browse the whole catalog. Results come back in pages of 25 lean rows with `total_count` and `has_more`; pass the `offset` named in the response summary to fetch the next page. * Browse the access catalog before requesting or granting access * Find the application a request should target * Narrow to a single workspace's catalog with `workspace_id` * Fetch full detail (ownership, notes, entitlement count) for up to 25 known applications per call with `application_ids`; IDs that don't resolve come back in `missing_ids` rather than as an error Archived applications are excluded unless you pass `include_archived: true`. Organization admins search the whole catalog. Everyone else's search results include only applications available in a workspace they can reach, so an application missing from results may exist but be out of view. Fetch a single application by ID, including its description and workspace associations. * Confirm which workspaces an application is available in Modify an existing application's name, description, workspace associations, or archived status. * Retire an application from the catalog by archiving it * Expand an application to another workspace **`search_applications` replaces the retired `application__list`.** `application__list` is no longer MCP-enabled and now returns a stale-tool stub pointing at `search_applications`. External MCP clients calling the old name must migrate. ### Access policies Configure and manage access control policies for applications and resources. Retrieve all access policies in the workspace. * View your access control configuration * Audit existing policies Fetch details for a specific access policy. * Review policy rules and conditions * Check approval requirements Define a new access policy for an application or resource. * Set up access controls for new applications * Create policies with approval workflows Modify an existing access policy. * Adjust approval requirements * Update policy scope or conditions Retrieve access levels a user is eligible for. * Show available options during access requests * Determine what a user can request Retrieve applications a user is eligible to request access to. * Guide users to available applications * Filter access request options by eligibility ### Access levels Define and manage the specific permissions, roles, or entitlements that users can request within an application (for example, "Admin Access", "Read-Only", or "Developer Role"). Retrieve access levels across all applications in the organization, optionally filtered by application. * Discover what access can be requested for a given application * Audit access levels across the organization Create a new access level for an application by specifying the application, provisioning method, and optional approvers or access policy. * Define a new requestable permission such as "Admin Access" or "Viewer Role" * Link the access level to an approval policy at creation time Modify an access level's name, description, approvers, provisioning method, or associated access policy. * Adjust approvers or provisioning behavior for future requests * Rename or relink an access level without affecting existing entitlements ### Access requests Submit access requests on behalf of users. Create an access request for an application on behalf of a user. * Submit requests programmatically as part of onboarding workflows * Request access on behalf of a new hire before their first day * Automate access provisioning based on role changes | Parameter | Type | Required | Description | | --------------- | ------ | -------- | --------------------------------------------------------------------------- | | `applicationId` | string | Yes | The ID of the application to request access to. | | `accessLevelId` | string | Yes | The ID of the access level being requested. | | `requesterId` | string | No | The user ID of the requester. Defaults to the current user. | | `reason` | string | No | Justification for the access request. | | `duration` | string | No | Requested access duration, if the policy allows requester-chosen durations. | ### Access entitlements View the access users currently hold across applications. Retrieve access entitlements in the organization, with standard filter support. * Audit who holds which access levels * Build access reviews from current entitlements Retrieve an overview of all access entitlements for the current user in the workspace. * Check what access you currently hold * Review your entitlements before requesting more access ### Vault credentials Read the credentials stored in the organization vault. Retrieve all vault credentials for the organization. Returns metadata only; decrypted values are never exposed. * Audit which credentials are stored * Look up a credential before wiring it into provisioning ### Approval templates Create and manage reusable, multi-round approval workflows that can be applied across access requests, ticket escalations, change management, and other workflows requiring sign-off. Retrieve approval templates in the organization, including each template's rounds and approver configuration. * Find existing templates when configuring workflows * Review a template's rounds and approvers before assigning it to a queue or policy * Audit approval processes across the organization Define a new approval template with one or more rounds of approvers. Approvers can be specific users or groups, or dynamic options such as the requester's manager. * Standardize multi-round approval workflows for reuse across the app * Provision templates programmatically as part of workspace setup Modify the rounds or approver configuration on an existing template. Changes affect new workflows; in-flight approvals continue with their original configuration. * Adjust approvers as team structures change * Add or reorder rounds without rebuilding downstream workflows Given a template ID, return the access policies that reference it, each with the access levels it governs. * Understand what a change affects before editing or retiring a template * An empty result means no access policy currently references the template *** ## Automation ### Code actions Browse the automated code actions configured in your workspace. Authoring and publishing happen through [Foundry](/documentation/automate/foundry/overview), including the Foundry tools below. Retrieve all code actions in the workspace. * View available automations * Audit existing code actions Fetch details for a specific code action including its configuration and status. * Review action logic and settings * Check activation status ### Foundry Author [Foundry](/documentation/automate/foundry/overview) integrations and actions from your AI client: connect an external API, generate action code against its documentation, test it, and publish it for agents and workflows to call. Create and maintain the custom-API integrations that actions are built against. * `list_foundry_integrations`: list the workspace's Foundry integrations with auth type, draft state, and docs-validation status * `create_foundry_integration`: create an integration shell from an API's base URL, docs URL, and auth type * `get_foundry_integration`: check an integration's draft state, docs-validation status, and whether credentials are stored * `update_foundry_integration`: change an existing integration's name, URLs, auth type, or default headers * `connect_foundry_integration`: re-surface the authentication step for an integration that requires credentials * `verify_foundry_integration_auth`: make one authenticated read against the API to confirm stored credentials work * `validate_foundry_docs`: re-run documentation validation after fixing a docs URL * `publish_foundry_integration`: publish a draft integration so its actions can be dry-run and published Credentials never travel through the conversation. They are entered through Ravenna's secure connect flow and stored encrypted. Let a Foundry action borrow credentials from a native Ravenna integration the organization has already connected. * `list_native_bridge_integrations`: list connected native integrations that can lend credentials to a Foundry action * `set_action_native_bridge`: re-link or unlink the native integration supplying an existing action's credentials Search the workspace's Foundry actions by what they do, ranked by relevance. * Find an existing action that already covers a request before building a new one * Narrow by integration, or to published actions only Create an action from a natural-language request, then generate its code. * `create_foundry_action`: create the action record against an integration, a native credential bridge, or as an internal Ravenna-data-only action * `generate_foundry_action`: generate the action's code from the integration's validated API documentation Generation is asynchronous. Poll `get_foundry_action` for the settled generation status. Fetch an action's generation status, any generation error, last test status, published state, and input schema. * Poll while generation or iteration is running * Read the input parameters before testing or running the action Test an action safely and revise it with natural-language feedback. * `dry_run_foundry_action`: run the non-mutating variant (live reads, mocked writes) and return the result, errors, and logs * `iterate_foundry_action`: hand feedback or a dry-run failure to Foundry's code agent to revise the action Publish a generated action so agents and workflows can call it. The backing integration must be published first. * Wire the published action to an agent rule as a tool, or into a workflow as a step * Publishing requires a completed generation, and a successful dry run is strongly recommended first Running a published action directly is not available over MCP. Run it from the Foundry studio, or wire it to an agent or workflow. ### Agents Configure the AI agents that handle conversations, route requests, and automate work in your workspace. Retrieve all AI agents in the workspace. * View available agents and their configuration * Audit agent deployment across channels Fetch details for a specific agent including its capabilities, rules, and connected channels. * Review agent configuration before changes * Check which knowledge sources and tools are enabled Create a new AI agent with a name, description, and initial configuration. * Stand up a new agent for a specific team or domain * Provision agents programmatically as part of onboarding Modify an existing agent's name, description, capabilities, or configuration. * Rename agents to reflect their scope * Update escalation instructions or capability settings * Adjust which channels an agent serves Retrieve the tools that can be wired into agent rules, including integration tools and published Foundry actions. * Find a tool key before adding it to a rule's tool list * Check what integrations your agents can act through Learn more about [configuring agents](/documentation/automate/agents/configure) ### Agent rules Manage the natural language rules that define how your agents handle specific scenarios. Rules can be workspace-level (shared across agents) or attached to individual agents. Retrieve all agent rules in the workspace, or rules attached to a specific agent. Pass a rule ID to get full detail for one rule (trigger, instruction, examples, tool wiring, execution policies, and attached agents) instead of the summary view. * Audit the rules powering your agents * Find rules that reference a specific form, workflow, or knowledge folder * Inspect a rule's full configuration before editing it Create a new agent rule with a title and natural language instruction. Optionally attach it to one or more agents. * Add a rule for a new kind of request your agents should handle * Bulk-author rules from external prompts or templates Modify a rule's title, instruction, or enabled state. * Iterate on rule wording to improve agent behavior * Disable a rule temporarily while debugging Add an existing workspace-level rule to a specific agent. * Reuse a shared rule across multiple agents for consistent behavior * Roll out a new rule to selected agents only Remove a rule from an agent without deleting the rule itself. * Stop an agent from using a shared rule while keeping it available for others Learn more about [writing agent rules](/documentation/automate/agents/configure#rules) ### Knowledge bases Discover the [knowledge bases](/documentation/automate/knowledge/overview) available to your agents. List knowledge bases in the workspace, look them up by ID, or filter by name. Each result includes its document count and connected agents. * Find knowledge base IDs before connecting them to an agent * Check which agents a knowledge base already serves ### Workflows Plan, build, edit, and manage multi-step workflows directly from your AI client. These tools are consolidated, workflow-shaped operations designed for MCP agents. Start with `plan_automation` when the user describes an outcome in natural language, then create and configure the workflow with the tools below. Turn a natural-language request ("close stale tickets after 14 days") into a concrete workflow plan before anything is built. Returns a proposed trigger, step sequence, and any requirements that cannot be met so the user can confirm or adjust before `create_workflow` is called. * Route ambiguous "build me a workflow" requests through a single planning step * Surface gaps (missing integration, unsupported action) before drafting Retrieve workflows in the workspace, with optional search by name and filter by state. * Find an existing workflow before editing * Audit which workflows are Draft, Active, Paused, or Archived Fetch a single workflow's full configuration including its steps, connections, trigger, and state. * Inspect a workflow's current shape before editing * Pull step IDs needed by `edit_workflow_step`, `remove_workflow_step`, or `configure_workflow_steps` Create a new workflow in Draft state with a name, description, trigger, and initial steps. Returns each new step with the input suggestions needed to configure it. * Draft a new workflow after `plan_automation` returns a confirmed plan * Scaffold workflows programmatically as part of onboarding Update a workflow's name or description. Metadata-only; does not touch the step graph, trigger, or state. * Rename a workflow to match a new process * Refresh a workflow's description after its scope changes Check whether a workflow is structurally valid and ready to go live. Returns validation issues (unresolved branches, disconnected steps, unconfigured inputs) instead of activating. * Verify a workflow after configuring every new step * Surface problems before asking a user to publish Publish a workflow so it goes live and runs on its trigger. Call `validate_workflow` first: publishing a workflow with unresolved issues returns those issues instead of publishing, and a workflow that cannot be published from its current state comes back as `published: false` with the reason rather than an error. When republishing an active workflow that already has in-progress runs, the tool short-circuits and returns `requires_decision` alongside `active_run_count`. Ask the user whether those in-flight runs should finish on the previously published version (`stop_active_runs: false`) or be stopped so only the new version runs (`stop_active_runs: true`), then call `publish_workflow` again with the chosen value. * Take a Draft workflow live after `validate_workflow` returns clean * Republish a workflow after edits, deciding what happens to in-flight runs Take a published workflow offline. Two modes: * `mode: 'pause'` stops accepting new runs but lets in-progress runs finish. The workflow shows as Paused and can be resumed later with `publish_workflow`. * `mode: 'deactivate'` unpublishes immediately and stops all in-progress runs. The workflow shows as Off. Omit `mode` when the user has not decided. The tool then returns `requires_decision` with the in-progress run count so the agent can ask which mode to use. Pause is the less destructive default. * Pause an active workflow without cancelling in-flight runs * Unpublish a workflow and stop everything currently running **Duplicating and reverting workflows is not available over MCP.** To reuse a workflow's shape, call `create_workflow` and respecify the trigger, steps, and connections. Version rollback (previously "Revert workflow") is not currently exposed over MCP. **Lifecycle tools replace the older tRPC-shaped MCP tools.** `workflow__update`, `workflow__run`, `workflow__retryWorkflowRun`, `workflow__pause`, and `workflow__deactivate` are no longer MCP-enabled and now return stale-tool stubs pointing at their replacements (`edit_workflow_info`, `run_workflow`, `retry_workflow_run`, `publish_workflow`, and `deactivate_workflow`). External MCP clients calling those names must migrate. `workflow__pause` and `workflow__deactivate` also no longer accept bulk `ids[]`. Call `deactivate_workflow` once per workflow. ### Workflow steps Add, edit, and configure the individual steps that make up a workflow. Connections are managed implicitly by these tools. Pass `source_id` on `add_workflow_step` to chain a new step after an existing one, and `remove_workflow_step` reconnects around the removed step automatically. Add one or more steps to an existing workflow. Pass `source_id` on each step to control where it attaches. Returns the created steps with input suggestions to feed into `configure_workflow_steps`. * Extend a workflow with additional logic * Insert a new action between existing steps Update a step's title, description, or swap its action for a different one. Requires `workflow_id` and `step_id`. * Swap a placeholder step for a real action * Change a step's action without recreating it Set input values and optional conditions on a single step. Use this to fix an individual step after a batch `configure_workflow_steps` call. * Correct one step's inputs without touching the rest of the workflow * Add a conditional guard to a specific step Configure inputs and conditions for multiple workflow steps in one call. Pass every step returned by `create_workflow` or `add_workflow_step` at once to avoid extra round-trips. * Fill in inputs for a freshly-created workflow in a single call * Apply a batch of edits during a workflow refactor Add or update filters on a workflow's trigger step. Narrows which events actually start a run (for example, only tickets in one channel or messages with a specific reaction). * Scope a trigger to a single channel or category * Match on a specific event property before starting a run Remove a step from a workflow. Incoming and outgoing connections are re-attached automatically, so removing a middle step reconnects around it rather than orphaning downstream children. * Delete an unused or obsolete step * Simplify a workflow during refactoring **Duplicating steps and repositioning steps on the canvas is not available over MCP.** Add fresh steps with `add_workflow_step` instead of duplicating. Layout changes (dragging steps to a new position on the canvas) are not exposed over MCP. ### Workflow discovery Discover the actions, triggers, and input options available when building or editing a workflow. Retrieve every action available for use in a workflow, grouped by category (triggers, ticket actions, conditionals, wait/monitor, control flow, integrations). * Discover what integrations and actions are available * Find the right action name to pass to `add_workflow_step` Fetch a single action's details including its input schema, required fields, and validation rules. * Inspect an action's inputs before adding it as a step * Check available options for a dropdown-typed input Get input suggestions for a specific step: field types, literal options, and references to values from upstream steps. Returns `referenceId`s to pass to `edit_workflow_step_input` or `configure_workflow_steps`. * Look up how to reference a value from a previous step * Discover the available fields when configuring a step in a later turn List the available filter fields, operators, and values for a trigger step. * Discover what a trigger can be filtered by before calling `edit_workflow_trigger_filter` ### Workflow runs Inspect workflow executions, trigger runs by hand, and retry finished runs. Filter workflow runs across the workspace and page through the results, newest first. Filter parameters: * `workflow_id`: restrict to a single workflow. * `statuses`: array of run statuses. Use `["failed"]` to find runs worth retrying. * `created_after` / `created_before`: ISO 8601 timestamps. Invalid timestamps return `INVALID_DATE_RANGE` rather than a generic database error. * `limit`: cap on runs returned. Defaults to 50, max 1000. The response includes `count` (total runs matching the filter) and `truncated` (true when `count` exceeds the returned runs). Narrow the date range or raise `limit` before treating `count` as a definitive total. * Monitor recent runs of a specific workflow * Find failed runs in a time window for triage or bulk retry Fetch a single run's details including each step's status, timing, inputs, outputs, and any errors. * Debug why a run failed * Trace the exact path a run took through a branching workflow Trigger one run of a published workflow by hand, instead of waiting for its trigger to fire. The workflow must already be published; if it is not, the tool returns `started: false` and names `publish_workflow` rather than running anything. Pass `inputs` as an object keyed by field name to override the trigger payload the first step receives. The whole object is forwarded to the start step as-is. For a webhook-triggered workflow, nest the payload under `body` (and `headers` / `query` if the workflow reads them) so it matches the request shape the trigger expects. Omit `inputs` for a bare run. **Semantic change from the retired `workflow__run`.** `run_workflow` forwards the whole `inputs` object as the start-step record. `workflow__run` accepted a fixed `{ headers, url, query, method, body }` envelope. Callers migrating from `workflow__run` for a webhook trigger should move those fields into `inputs` (`{ headers, query, body, ... }`) rather than sending them at the top level. The returned `run_id` goes to `get_workflow_run_info` to check how the run went. * Trigger a run manually for a workflow that normally fires on a webhook or schedule * Kick off a workflow with a specific payload for a one-off backfill or test Start a new run from a finished one, usually a failure. The original run is left as it is; the new `run_id` is returned so you can inspect the retry with `get_workflow_run_info`. Options: * `retry_from_failure: true`: resume from the step that failed, reusing the successful steps' outputs. Right for transient issues (rate limit, outage) where only the last step broke. Omit or set false to replay the whole workflow from the start. * `use_latest_version: true`: retry against the workflow as it is published now. This mirrors the "Retry with latest version" option in the web UI and is what you want after fixing a broken workflow. Omit or set false to replay the exact version the original run used; later edits are not picked up. The response includes `used_latest_version` so callers can confirm which version the retry ran against. If the workflow has been edited since the original run and `use_latest_version` was not set, the message says so. If the workflow is not currently published and `use_latest_version: true` is set, the tool returns `retried: false` and points at `publish_workflow`. * Retry a failed run after fixing the workflow (`use_latest_version: true`) * Replay a failed run against its original version to reproduce a bug ### Workflow collections Organize workflows into collections for browsing in the Admin. Retrieve every workflow collection in the workspace. * Find an existing collection before creating a new one * Audit how workflows are organized Fetch a single collection's details by ID. * Check a collection's name and description Create a new collection to organize workflows. * Group related workflows for a team or process area * Reuse an existing collection first by checking `list_workflow_collections` before creating one Move a workflow into a collection, or pass `null` to remove it from its current collection. This is organizational only and does not affect the workflow's behavior. * Reorganize workflows after a team change * Move a workflow into the collection its owning team browses *** ## Analytics Query analytics data and manage the dashboards and widgets that power your reporting. Use these tools to count, chart, or trend data over tickets, ticket messages, knowledge base documents, and workflow runs without paging through list results. Run an analytics query and return aggregated, chart-ready data in a single call. * Count, group, or trend across tickets, ticket messages, knowledge base documents, or workflow runs * Pick a metric breakdown ("tickets by status") or a time series ("ticket volume per day") * Skip pagination through list tools when all you need is the aggregate Retrieve the analytics dashboards and folders in the workspace with a compact summary of each dashboard's widgets. * Find an existing dashboard before creating a new one * Decide where a new widget belongs based on existing topics * Search by name to narrow the list * Identify folders (entries with an `item_type` of `collection`) so you can file dashboards inside them View a single dashboard's widgets with freshly-computed data, layout, and re-runnable query specs. * Read the current numbers on a named dashboard * Inspect a widget's spec to re-run or edit its query Create a new, empty analytics dashboard, or a folder to group dashboards in. Optionally set a default date range and time interval. * Stand up a new reporting view for a team or initiative * Set the default view options every widget on the dashboard inherits * Create a folder by passing `item_type: "collection"` * File the new dashboard inside a folder by passing that folder's id as `parent_id` Modify a dashboard or folder's name, description, or default view options (date range and time interval), or move it into or out of a folder. * Shift the reporting window for every widget on a dashboard at once * Rename or re-describe a dashboard as its purpose evolves * Move a dashboard into a folder by passing that folder's id as `parent_id` * Move a dashboard back to the top level by passing `parent_id: null` Save a chart or a ticket list as a persistent widget on an existing dashboard. For a chart, re-pass the same query parameters used with `query_analytics_chart` so the saved widget matches the previewed chart. For a ticket list, pass `query_type: "table"` with filters and the columns each row should show. * Pin a one-off chart for ongoing tracking * Build out a dashboard from a series of ad-hoc queries * Keep a live ticket list on a dashboard (for example, "add my open P1s to the dashboard") without collapsing it into a count **Table widgets** Use `query_type: "table"` to save a Data card that lists individual tickets, one row per ticket, instead of an aggregate. Table widgets take `filters`, `sort_by`, `sort_order`, `limit`, and `columns`; they do not accept `group_by`, `aggregation`, `chart_type`, or `time_interval`. Pass `columns` as an ordered list of column references, left to right: * Built-ins: `key`, `title`, `status`, `priority`, `assignee`, `requester`, `createdAt` * A form field captured on the ticket: `customField::` (look ids up with `list_workspace_custom_fields`) * A workspace ticket attribute: `attributeField::` (look ids up with `search_workspace_attributes`) Omit `columns` to save the widget with the default five: `priority`, `key`, `status`, `title`, `requester`. `requester` works as a column but is not sortable. Sort on `createdAt`, `key`, `status`, `assignee`, or a `customField:` / `attributeField:` reference (no `:` suffix on sort). The tool returns a preview of the tickets the saved widget currently lists. Dashboard-level filters and date range apply at render time, so the live widget can show a different set. Modify an existing widget: change its query, chart type, name, description, or (for table widgets) its columns and sort. Only the fields you pass change. Omit a field to leave it as-is. * Adjust a saved widget's grouping or aggregation * Restyle a chart by passing just `chart_type` (no `query_type` needed) * Rename or re-describe widgets without recreating them * Change which columns a Data card shows, or re-sort its rows **Table widgets** To change what a ticket-list widget shows, pass `query_type: "table"` together with the field you want to change (`columns`, `filters`, `sort_by`, `sort_order`, `limit`). Each field you pass replaces its saved value wholesale rather than merging, so read the widget's current spec from `get_dashboard` and re-pass the full set you want the widget to end up with. Pass `columns: []` to reset back to the default five columns. Table widgets have no `chart_type`. Learn more about [analytics dashboards](/documentation/measure/analytics) Learn more about [setting up the MCP server](/documentation/automate/mcp/setup) # SLAs Source: https://docs.ravenna.ai/documentation/automate/slas Set service level agreements that automatically monitor ticket response, resolution, and closure deadlines with early warning alerts and reporting. Service Level Agreements (SLAs) help your team maintain consistent service quality by automatically monitoring ticket response times, resolution times, and closure deadlines. Set time-based commitments, receive early warning alerts before breaches occur, and track performance through comprehensive reporting to ensure you never miss a commitment to your customers. **Key capabilities:** * Automated monitoring that continuously checks SLA compliance in the background * Multiple target types for response, resolution, and closure times * Business schedules that limit SLA measurement to your team's working hours * Pause statuses that stop the timer while a ticket is waiting on someone else * Early warning alerts before SLA breaches occur * Flexible filtering to apply SLAs to specific ticket types * Visual indicators showing SLA health at a glance * Priority ordering when multiple SLAs could apply to the same ticket Learn more about [SLA analytics](/documentation/measure/analytics#prepackaged-dashboards) and [ticket priorities](/documentation/tickets/organize/priorities) *** ## SLA components SLAs consist of targets that define time-based commitments and alerts that provide early warnings before breaches occur. Each SLA can contain multiple targets that define different time-based commitments for ticket handling. **Time to first response** * Measures time from ticket creation to first team response * Ensures customers get timely acknowledgment * Maintains customer satisfaction with prompt initial contact **Time to resolution** * Measures time from ticket creation to resolution * Tracks overall issue resolution performance * Serves as a key metric for service quality **Time to close** * Measures time from ticket creation to final closure * Includes any follow-up or verification steps * Provides complete lifecycle tracking Configure targets using flexible time units including minutes, hours, and days. Alerts provide early warning before SLA breaches occur, giving your team time to take action. **Time to first response alerts** * Warn before response deadline is missed * Give your team time to provide initial customer contact **Time to resolution alerts** * Alert before resolution deadline * Allow for escalation or resource reallocation **Time to close alerts** * Notify before final closure deadline * Ensure proper ticket completion Configure alerts using the same flexible time units as targets (minutes, hours, days). **How alert time is interpreted** The alert time is the amount of time **before the breach deadline** that the alert fires — not the elapsed time from ticket creation. For example, take a Time to first response target of 4 hours with an alert configured for 1 hour. The alert fires 3 hours after the ticket is created, which is 1 hour before the 4-hour deadline. If the alert time is greater than or equal to the target time, no alert is scheduled — there is no window in which an early warning makes sense. Attach a business schedule to an SLA to measure time against your team's working hours instead of wall-clock time. Nights and weekends outside the schedule are excluded from response, resolution, and close calculations. **What a schedule defines** * **Timezone**: The IANA timezone the schedule is anchored in (for example, `America/New_York`). * **Weekly hours**: One or more working time ranges per day of the week, in 24-hour `HH:MM` format. A day with no ranges is treated as fully off. **How it works** * When an SLA has a schedule attached, its timers only advance during the schedule's working windows. * When a ticket is created or transitions outside working hours, the timer waits to start (or resume) until the next working window opens. * A ticket's SLA badge shows **Resumes at ** outside business hours, indicating when the timer will next pick up rather than ticking down. * An SLA without a schedule continues to use wall-clock time (24/7). Create and manage schedules under **Settings → Business Schedules**, then select one in the **Settings** tab of an SLA. The same schedule can be shared across multiple SLAs. Pause statuses stop the SLA timer while a ticket sits in a state your team is not actively working on, so waiting time does not count against your targets. **Common use cases** * Pause while waiting on the requester (for example, a "Waiting on customer" status) * Pause while a ticket is blocked by an external dependency * Pause during scheduled change windows or planned downtime **How it works** * Select one or more statuses that should pause the SLA timer * When a ticket enters a pause status, that SLA's timers stop * When the ticket leaves the pause status, timers resume from where they left off * Time spent in a pause status is excluded from response, resolution, and close calculations Terminal statuses in the **Done** and **Closed** status groups cannot be selected as pause statuses. Reaching a terminal status already stops the SLA timer for good — the target is either met or breached. The pause status picker hides them, and the API rejects them on save. *** ## How SLAs work By default, SLAs apply to all tickets in your workspace. To target only certain tickets, turn off the "Apply to all tickets" toggle and add filter criteria based on status, priority, channel, form, assignee, assignee group, or other attributes. ### SLA outcome indicators Ravenna uses a color-coded system to show the SLA outcome at a glance on ticket cards and dashboards. Action completed within the SLA timeframe and target successfully achieved. SLA is active but no action taken yet. Still within the allowed timeframe with no alerts triggered. Alert threshold has been crossed and breach is imminent without action. Provides early warning to take preventive action. SLA deadline has passed and the service level target has been missed. Requires immediate attention. *** ## Creating SLAs Set up service level agreements to automatically monitor ticket response and resolution times. Go to **Settings** → **SLAs** to access SLA management. Click the **+ SLA** button to open the SLA creation form. Provide a descriptive name, description, and icon for your SLA, then click **Save**. Click your newly created SLA from the list to open the detailed configuration page. Set up your service level commitments by adding targets for Time to First Response, Time to Resolution, or Time to Close with specific time limits. Add alerts that warn before SLA breaches occur by setting alert timing for each target type. On the SLA's **Settings** tab, select a business schedule if you want SLA timers to honor your team's working hours instead of running 24/7. Leave this blank to keep wall-clock measurement. Business schedules are created under **Settings → Business Schedules**. Select any statuses that should pause the SLA timer, such as "Waiting on customer" or "Blocked". Time spent in a pause status is excluded from your SLA calculations. Terminal statuses in the **Done** and **Closed** groups are not selectable, since reaching them already stops the timer. By default, your SLA applies to all tickets. To target specific tickets, turn off the "Apply to all tickets" toggle and configure filter criteria based on status, priority, channel, form, assignee, assignee group, or other attributes. To target tickets by user group, use the **Assignee**, **Requestor**, or **Author** filter with the **is member of** or **is not member of** operator. Select one or more user groups to scope the SLA. Use this to define SLAs that follow a team rather than a specific user, for example, "Tier 1 Support" or "Security On-Call". Save your SLA configuration to activate monitoring for matching tickets. *** ## Managing multiple SLAs When multiple SLAs could apply to the same ticket, Ravenna uses priority ordering to determine which SLA is applied. ### Priority evaluation * SLAs are evaluated in the order they appear in your list * The first matching SLA is applied to each ticket * SLAs higher in the list take precedence over those lower in the list ### Best practices for ordering * Order SLAs from most specific to most general * Place urgent or critical SLAs at the top of the list * Use "Apply to all tickets" SLAs as fallbacks at the bottom * Review SLA order regularly to ensure proper precedence *** ## Notifications and alerts SLA notifications are automatically sent to relevant stakeholders when alerts trigger or breaches occur. ### Notification recipients Notifications are sent to the following recipients based on ticket assignments: * Ticket assignee (if assigned) * Ticket followers * Channel auto-assignees (if no specific assignee) * Workspace administrators ### Notification timing * **Alerts**: Sent when alert threshold is crossed, providing early warning before breach * **Breaches**: Sent when SLA deadline passes, requiring immediate attention Learn more about [configuring notifications](/documentation/platform/notifications) *** ## Monitoring SLA performance Track SLA compliance through visual indicators and comprehensive Analytics dashboards. ### Visual indicators SLA performance is displayed through: * Color-coded SLA badges on ticket cards * Progress indicators showing time remaining * Clear visual status at a glance in ticket lists ### Filter and export by SLA In any view, filter tickets by: * **SLA**: The SLA policy attached to the ticket * **SLA Outcome**: Whether the target was **Met** or **Breached** * **Target**: The SLA target type — **SLA Time to First Response**, **SLA Time to Resolution**, or **SLA Time to Close** * **SLA Target Outcome**: One target and its outcome together, such as **Time to First Response met** or **Time to Resolution breached**. Add two of these conditions to find tickets that met one target but breached another, which the separate **Target** and **SLA Outcome** filters cannot express. Supports the **is**, **is not**, **is one of**, and **is not one of** operators. * **Breaching Within**: Tickets with an active SLA target that will breach within a duration you set in minutes, hours, or days. Only pending targets breaching between now and the threshold match. Tickets that have already breached are excluded, so this filter surfaces at-risk work while there is still time to act. SLA filters are grouped under a single **SLA** entry in the filter menu. Exported CSVs include the assigned SLA name and its current status alongside other ticket data, so you can run compliance reporting offline. ### Dashboard metrics Analytics dashboards provide comprehensive SLA performance tracking. Charts and filters read from the SLA target record directly, so they account for business hours, pause statuses, and superseded targets. * **Compliance rate**: Percentage of tickets meeting SLA targets * **Average response time**: How quickly your team responds to new tickets * **Breach trends**: Patterns in SLA violations over time * **Performance by category**: SLA success broken down by priority, channel, or form #### Choosing a duration field on custom cards Custom analytics cards on the **Tickets** data source expose two families of duration aggregation fields: * **SLA Time to First Response**, **SLA Time to Resolution**, and **SLA Time to Close** read the SLA target record. They honor the SLA's business schedule, pause statuses, and superseded targets, and they only include tickets an SLA policy covers. Use these when you are reporting on compliance with your SLA commitments. * **Time to First Response**, **Time to Resolution**, and **Time to Close** measure wall-clock time from the ticket's own timestamps (`respondedAt`, `resolvedAt`, `closedAt`). They ignore business schedules and pause statuses, and they include every ticket with the timestamp set, whether or not an SLA policy applies. Use these to benchmark team performance across your full ticket volume, or to report on channels that don't have SLAs configured. Existing saved widgets keep pointing at the SLA-clock fields — they now render under the **SLA** labels but the underlying values and thresholds are unchanged. Learn more about [SLA analytics dashboard](/documentation/measure/analytics#prepackaged-dashboards) ## Mental model An SLA is a set of time-based targets applied to tickets. Each SLA defines deadlines for response, resolution, and/or closure. SLAs are workspace-scoped and evaluated against tickets based on filter criteria. SLAs are passive monitoring, not active automation. They measure whether time targets are met and generate visual indicators and notifications. They do not change ticket status, reassign tickets, or trigger workflows on their own. To take automated action on SLA events (breach, alert), use workflows with SLA-related triggers or conditions. *** ## SLA target types | Target | Measures | Timer starts | Timer stops | | -------------------------- | ------------------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------ | | **Time to first response** | How quickly the team acknowledges a ticket | Ticket creation | First team response (non-requester message) | | **Time to resolution** | How quickly the ticket is resolved | Ticket creation | Ticket status moves to a status in the **Done** group, or directly to a status in the **Closed** group | | **Time to close** | How quickly the ticket is fully closed | Ticket creation | Ticket status moves to "Closed" | Each SLA can have multiple targets. For example, a single SLA might require first response within 1 hour, resolution within 8 hours, and closure within 24 hours. **Done and Closed are independent milestones for SLA targets.** When a ticket moves to a status in the **Done** group, **Time to resolution** is marked Met (or Breached) and **Time to first response** stops. **Time to close** keeps running. The close timer only stops when the ticket moves to a status in the **Closed** group, at which point it is marked Met (or Breached). A ticket that sits in Done for an extended period before being Closed can meet its resolution target and still breach its close target. **Closing a ticket directly also completes resolution.** When a ticket transitions straight to a status in the **Closed** group without first passing through **Done**, both **Time to close** and **Time to resolution** are marked Met (or Breached) at the same moment, since closure implies the ticket is resolved. *** ## Business schedules A business schedule is a workspace-scoped resource that defines when SLA timers should run. A schedule has two configurable components in the UI: * `timezone`: an IANA timezone string (for example, `America/New_York`). * `weeklyHours`: per-day arrays of `{ start, end }` ranges in `HH:MM` 24-hour format. Days with no ranges are fully off. Overnight ranges (end ≤ start) wrap to the next day. Schedules are managed under **Settings → Business Schedules**. Each SLA can optionally reference one schedule by `scheduleId`. Schedules can be shared across multiple SLAs. To archive or delete a schedule, first reassign every SLA that uses it — Ravenna blocks archive and delete actions while connected SLAs exist. Behavior when a schedule is attached: * SLA target timers (response, resolution, close) only advance during the schedule's working windows. Time outside those windows is excluded. * Newly created tickets outside working hours wait to start the timer at the next window. The SLA badge displays **Resumes at ** during that wait, showing when the timer will next advance. * Alert and breach scheduling are computed against business time as well — a 1-hour alert on a 4-hour business-hours target fires 1 working hour before the working-hours breach deadline. If no schedule is attached, the SLA falls back to wall-clock measurement (24/7), which is the legacy behavior. Example schedule payload: ```json theme={"system"} { "name": "US Business Hours", "timezone": "America/New_York", "weeklyHours": { "mon": [{ "start": "09:00", "end": "17:00" }], "tue": [{ "start": "09:00", "end": "17:00" }], "wed": [{ "start": "09:00", "end": "17:00" }], "thu": [{ "start": "09:00", "end": "17:00" }], "fri": [{ "start": "09:00", "end": "17:00" }] } } ``` *** ## Pause statuses Each SLA can declare a list of pause statuses. While a ticket is in any of those statuses, all of the SLA's timers stop. When the ticket transitions out, the timers resume from the elapsed time at pause. Example configuration: ```json theme={"system"} { "name": "Tier 1 Support", "pauseOnStatusIds": ["status_waiting_on_customer", "status_blocked"] } ``` Rules: * Statuses in the **Done** and **Closed** status groups are terminal and cannot be used as pause statuses. The settings page filters them out of the picker, and the SLA create/update API responds with an `INVALID_PAUSE_STATUS` bad-action error if they are submitted. * Pause behavior applies to every target on the SLA (response, resolution, close) — it is not per-target. * Pausing does not change the SLA outcome badge color from On Track. The timer simply does not advance. *** ## SLA evaluation and priority When multiple SLAs exist, the system evaluates them in list order (top to bottom). The first SLA whose filter criteria match the ticket is applied. Only one SLA applies per ticket. Recommended ordering: 1. Most specific SLAs first (e.g., "Critical Priority Incidents" filtered to priority = Critical and channel = Incidents). 2. Medium-specificity SLAs next (e.g., "IT Support" filtered to a specific channel). 3. Catch-all SLA last with "Apply to all tickets" enabled as a default baseline. If no SLA matches a ticket, the ticket has no SLA monitoring. *** ## SLA outcome lifecycle | Status | Color | Meaning | | ------------ | ------ | ------------------------------------------------------------------- | | **On Track** | Blue | Target is active, deadline has not been reached, no alert triggered | | **Alert** | Orange | Alert threshold crossed, breach is approaching | | **Met** | Green | Action completed within the target timeframe | | **Breached** | Red | Deadline passed without the required action | *** ## SLA notifications SLA alerts and breaches generate notifications sent to: 1. The ticket assignee (if assigned). 2. Ticket followers. 3. Channel auto-assignees (if no specific assignee). 4. Workspace administrators. Approval notifications in Slack are always delivered and cannot be disabled. SLA notifications follow standard notification preferences. *** ## SLAs in automation SLAs themselves do not trigger workflow actions. To automate responses to SLA events: * Use workflow triggers that fire on ticket property changes combined with conditions that check SLA outcome. * Build escalation workflows that reassign or notify when tickets approach SLA deadlines. * Use the "Due Date" workflow action to set deadlines that align with SLA targets. SLA data is available in analytics dashboards for compliance reporting and performance tracking. *** ## Constraints and gotchas * Only one SLA applies per ticket. The first matching SLA in list order wins. * SLA timers run continuously from ticket creation unless you configure pause statuses. When a ticket enters a configured pause status, the SLA's timers stop and resume when it leaves. Snooze does not pause SLA timers — use pause statuses for that. * Pause statuses cannot include any status in the **Done** or **Closed** status groups. The settings UI hides terminal statuses from the picker and the SLA create/update endpoints reject them with an `INVALID_PAUSE_STATUS` error. * By default SLA targets use wall-clock time. A 4-hour response target includes nights and weekends unless a business schedule is attached. Attach a business schedule to the SLA to measure time only during the schedule's working windows. * Moving a ticket to **Done** finalizes **Time to resolution** but does not stop **Time to close**. The close timer continues to run (or breach) until the ticket moves to a status in the **Closed** group. Treat Done and Closed as separate SLA milestones when configuring close targets. * Closing a ticket directly (skipping **Done**) finalizes both **Time to close** and **Time to resolution** in the same transition, because reaching **Closed** implies the ticket is resolved. The resolution target is marked Met if the close happens before the resolution deadline, or Breached otherwise. * Changing a ticket's properties (priority, channel, form) after creation does not re-evaluate which SLA applies. The SLA is locked at ticket creation. * SLAs are workspace-scoped. There is no organization-level SLA that spans workspaces. * SLA filter criteria support status, priority, channel, form, assignee, requestor, author, and other ticket attributes. Filters use AND logic. * The **Assignee**, **Requestor**, and **Author** filters support the `is member of` and `is not member of` operators. These match tickets where that user belongs (or does not belong) to one of the selected user groups. Use them to scope an SLA to a team rather than a single user. Tickets where the user is unset never match `is member of` and always match `is not member of`. * The legacy **Assignee Group** filter column is deprecated. Use **Assignee** with `is member of` / `is not member of` instead. * The **Breaching Within** ticket filter matches tickets with a pending SLA target whose breach time falls between now and the configured duration (minutes, hours, or days). Targets that have already breached never match — filter by **SLA Outcome** to find those. * The **SLA Target Outcome** ticket filter binds one target type to one outcome in a single value (`Time to First Response met`, `Time to First Response breached`, `Time to Resolution met`, `Time to Resolution breached`, `Time to Close met`, `Time to Close breached`). Each condition is evaluated against the ticket's active (non-superseded, non-cancelled) SLA targets independently, so two conditions AND together to express combinations like first response met AND resolution breached. Available operators: `is`, `is not`, `is one of`, `is not one of`. Works in analytics widget conditions, dashboard filters, ticket lists, and saved views. * Alerts are early warnings only. They do not take automated action. To automate escalation, build a workflow. * Alert time is measured backward from the breach deadline, not forward from ticket creation. A 1-hour alert on a 4-hour target fires at the 3-hour mark. If the configured alert time is greater than or equal to the target time, no alert fires. * SLA performance data is available in the prepackaged analytics dashboards. # Collections Source: https://docs.ravenna.ai/documentation/automate/workflows/collections Group related Ravenna workflows into collections by team, department, or business process to keep automation organized as your library grows. Organize related workflows using collections. Group automation by team, department, or business process to keep workflows manageable as the number of workflows grows. ## Creating collections Open **Workflows** from your workspace sidebar Click **New Collection** and provide a clear name Explain what types of workflows belong in this collection Add an icon, emoji, or color to make the collection easily identifiable Optionally nest this collection under a parent for hierarchical organization *** ## Organization strategies Select an approach that matches your team structure and workflow needs. Organize collections by team or department. Each team manages its own automations. **Example structure:** * IT Operations (Server Monitoring, User Onboarding, Security Alerts) * HR Processes (Employee Onboarding, Time Off Requests, Performance Reviews) * Customer Support (Ticket Routing, Escalations, CSAT Surveys) Organize collections by business function. Works well when teams share automation across processes. **Example structure:** * Incident Management (Alert Routing, On-Call Escalation, Post-Incident Workflows) * Access Management (User Provisioning, Access Requests, Offboarding) * Ticket Management (Auto-Assignment, Status Updates, Notifications) Organize collections by external system. Works well when workflows are focused on specific integrations. **Example structure:** * Jira Workflows (Issue Creation, Status Sync, Escalations) * Okta Workflows (User Provisioning, Group Management, Access Reviews) * Slack Workflows (Notifications, Approvals, Alerts) *** ## Collection hierarchy Collections support nested structures that mirror your organization or business processes. Create hierarchical structures by nesting collections: parent collections contain related child collections, and you can reorganize by changing parent-child relationships at any time. **Example:** An "Engineering" parent collection contains "Backend", "Frontend", and "DevOps" child collections. *** ## Managing collections ### Editing collections Update collection name, description, appearance, or parent relationship at any time. Changes do not affect workflows within the collection. ### Moving workflows and collections Move workflows and collections between locations as processes change. **Drag and drop:** 1. Click and hold on a workflow or collection 2. Drag to the target collection or breadcrumb 3. Release to move To move multiple items, select them using checkboxes, then drag any selected item. All selected items move together. You can also drag items to the "Move to new folder" button to create and move in one action. **Bulk move:** 1. Select workflows or collections using checkboxes 2. Click the **Move** action in the toolbar 3. Select the target collection and confirm **Move restrictions:** * Workflows retain their history and configuration when moved * Collections cannot be moved into their own subcollections (prevents circular references) * Moving a collection also moves all workflows and subcollections within it ### Duplicating workflows Copy an existing workflow to use as a starting point for a new one. The original workflow is unchanged. The copy is independent — editing one does not affect the other. **Duplicate within the same workspace:** In the workflows table, hover over a workflow and click the three-dot menu. Provide a name, optional description, and target collection for the copy. The duplicate is created in **Draft** state with all steps, configuration, and dynamic value references intact. [Publish it](/documentation/automate/workflows/publish) when ready. **Duplicate to another workspace:** Use **Duplicate to Workspace** to share a workflow design across workspaces in the same organization — for example, when rolling out a proven automation from one team to another. In the workflows table, hover over a workflow and click the three-dot menu, then select **Duplicate to Workspace**. Select any workspace where you are a member (Guest memberships are not eligible). Provide a name and optional description. The copy is created in the target workspace in **Draft** state. Open it and reconnect any workspace-scoped references before publishing. Cross-workspace duplication clears references to workspace-scoped resources: channels, statuses, tags, forms, categories, SLAs, task templates, and connected Slack channels. Organization-scoped references are preserved, including users, user groups, applications, access levels, access policies, code actions, and approval templates. ### Deleting collections Deleting a collection also deletes all workflows within it. Collection deletion is permanent and affects all contained workflows. Export or move workflows before deleting if you want to preserve them. ### Permissions Control who can create, edit, or delete workflows within collections based on workspace roles and permissions. *** ## Tips * **Use descriptive names.** Choose names that clearly indicate the collection's purpose. Avoid vague names like "Misc" or "Other" that become catch-alls. * **Keep hierarchy shallow.** Limit nesting to 2-3 levels deep. Deeper hierarchies become difficult to navigate. * **Indicate ownership.** Use the description field to note which team or person owns each collection. * **Review regularly.** Periodically remove unused collections, consolidate similar ones, and update descriptions as processes evolve. * **Start simple.** Begin with a basic structure and add complexity only as needed. Splitting collections is easier than merging them. Learn more about [building workflows](/documentation/automate/workflows/workflow-builder) and [publishing workflows](/documentation/automate/workflows/publish) ## Collections overview Collections are folders that organize workflows. They support unlimited nesting, custom icons and colors, and descriptions. Each workflow belongs to zero or one collection. *** ## Organization recommendations **By department** works best when teams own their automations independently. Each team manages workflows in their collection without affecting others. Example: IT Operations, HR Processes, Customer Support as top-level collections. **By process** works best when workflows span teams. Group all workflows related to a business function together regardless of which team owns them. Example: Incident Management, Access Management, Ticket Management as top-level collections. **By integration** works best when workflows are tightly coupled to specific external systems. Group all Jira-related workflows together, all Okta workflows together, etc. **In practice,** most organizations use a hybrid: top-level collections by department or process, with subcollections for specific integrations or sub-processes within each. *** ## Hierarchy best practices * Keep nesting to 2-3 levels. Deeper hierarchies become hard to navigate. * Use descriptive names that indicate purpose, not vague labels like "Misc" or "Other." * Note ownership in the collection description (which team or person is responsible). * Review and consolidate periodically. Remove empty collections and merge overlapping ones. *** ## Duplicating workflows Two duplication options are available from the workflow row menu: * **Duplicate.** Creates a copy in the same workspace. All steps, configuration, and dynamic value references are preserved. The copy is created in `Draft` state. * **Duplicate to Workspace.** Creates a copy in another workspace within the same organization. The user must be a non-Guest member of the target workspace. Workspace-scoped resource references are cleared on the copy: channels, statuses, tags, forms, categories, SLAs, task templates, and connected Slack channels. Organization-scoped references are preserved: users, user groups, applications, access levels, access policies, code actions, and approval templates. Cross-organization duplication is not allowed. In both cases the copy is independent. Editing the original does not affect the copy. *** ## Constraints * Deleting a collection deletes all workflows within it. Move workflows out before deleting if you want to preserve them. * Collections cannot be moved into their own subcollections (prevents circular references). * Moving a collection moves all contained workflows and subcollections with it. * Workflows retain their configuration and execution history when moved between collections. # Monitor workflows Source: https://docs.ravenna.ai/documentation/automate/workflows/monitor Monitor workflow runs with detailed step logs, run states, performance metrics, and debugging tools to keep your Ravenna automations reliable. Monitor workflow execution with detailed logs, performance metrics, and debugging tools to keep your automation running reliably. ## Understanding workflow runs A workflow run represents a single execution triggered by an event and tracked from start to completion. ### Run states | State | Description | | ------------------------- | -------------------------------------------------------------------------------- | | **Pending** | Waiting for execution resources | | **Running** | Actively processing workflow steps | | **Completed** | All steps finished successfully | | **Completed with errors** | Run reached the end of the workflow, but at least one step errored along the way | | **Failed** | The run halted because a step encountered an unrecoverable error | | **Cancelled** | Execution stopped manually or by system | ### Run details Each run captures start time, duration, trigger context and inputs, step-by-step execution results, success and failure counts, and error messages. Access workflow run history from the workflow detail page. Filter by status, search by trigger data or time range, and sort by execution time or duration. *** ## Step-by-step logging Each workflow step is individually tracked with detailed execution information: * **Input values**: Raw and resolved inputs for the step * **Output data**: Data produced by the step * **AI reasoning**: For AI steps (Decision Maker, Custom Prompt), the explanation the model provided for its decision or response * **Execution duration**: How long the step took * **Error messages**: Details if the step failed * **Dynamic value resolution**: How references resolved at runtime Use step logs to trace how data flows through your workflow. See how trigger data passes to actions, how action outputs feed subsequent steps, and where values transform along the way. *** ## Performance monitoring Monitor executions per day, average duration, and peak usage periods Track completion rates and identify reliability trends Monitor error patterns and failure rates over time View processing times and identify performance bottlenecks *** ## Debugging workflows Check execution logs for specific error details and context Identify which step failed and review its inputs and outputs Verify data flowing between steps matches expectations Confirm external services are available and authenticated Make corrections in draft mode and test before republishing *** ## Common issues * Verify the workflow is published and active (not draft or paused) * Review trigger filters to confirm they match the expected event * Check that required integrations are connected * Check execution logs for the specific error message * Verify all required fields are populated * Test dynamic references with a manual run * Confirm integration permissions are correct and the external service is operational * Review dynamic value configuration for wrong references * Check trigger data structure in logs to confirm expected fields exist * Verify field names match exactly * Check for external API delays in step durations * Consider parallelizing sequential actions where possible * Review external service performance *** ## Error types | Error type | Cause | Fix | | --------------- | ------------------------------------------------------------- | ----------------------------------------------------------- | | **Validation** | Missing required fields, invalid formats, type mismatches | Review field requirements and provide valid data | | **Integration** | Connection timeouts, authentication failures, API rate limits | Check integration status and external service health | | **Permission** | Missing API scopes, insufficient access rights | Grant necessary permissions in integration settings | | **Timeout** | External API delays, large data processing, network issues | Optimize the workflow or check external service performance | *** ## Retrying workflow runs Retry a workflow run directly from the run history table when a run finishes in a state you want to redo. Use retries to recover from transient failures, rerun a workflow against the latest configuration, or re-execute a successful run on demand. ### When retry is available The **Retry** action appears in the row actions menu for any run with one of these statuses: * **Failed** * **Completed with errors** * **Completed** Pending, running, cancelled, and skipped runs cannot be retried. ### Retry options Selecting **Retry** opens a dialog with up to three options. Which options appear depends on the run's status and whether a newer workflow version has been published since the run started. | Option | When it appears | What it does | | ------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | | **Retry with latest version** / **Rerun with latest version** | The run used an older workflow version and a newer version has been published | Starts a new run from the first step using the workflow's current active version | | **Retry from failure** | The run failed or completed with errors and contains at least one failed step | Creates a new run that reuses successful upstream step outputs and reruns the failed step(s) on the same version | | **Retry from beginning** / **Rerun** | Always available for retryable runs | Starts a new run from the first step using the same workflow version as the original run | **Retry from failure** requires that the workflow shape upstream of the failed step has not changed between versions. If upstream steps were added, removed, or reconfigured, select **Retry with latest version** or **Retry from beginning** instead. ### Retry a run Navigate to the workflow and select the **Runs** tab Locate the run in the table. Filter by status if needed Hover the row and select **Retry** from the actions menu Select the option that matches your goal, then select **Retry** A new run appears in the table linked to the original as its parent. Open it to monitor execution ### Retry via API You can also retry a run programmatically. Send a `POST` request to `/workflows/runs/{runId}/retry` with an optional `versionId` and `retryFromFailure` flag. ```bash theme={"system"} curl -X POST https://api.ravenna.ai/workflows/runs/{runId}/retry \ -H "Authorization: Bearer $RAVENNA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "versionId": "wfv_abc123", "retryFromFailure": true }' ``` | Field | Type | Description | | ------------------ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `versionId` | string (optional) | Workflow version to run. Defaults to the version used by the original run. Pass the workflow's active version ID to retry against the latest published version | | `retryFromFailure` | boolean (optional) | When `true`, reuses outputs from successful upstream steps and reruns failed step(s). When omitted or `false`, the run starts from the first step | The response contains the new `runId`. Use it to fetch the new run or display it in your tooling. *** ## Skip wait steps Workspace admins can fast-forward past Wait and Wait Until steps on a running workflow. When a workflow is paused at a timer step, open the workflow run details and click **Skip** to advance the workflow immediately without waiting for the timer to expire. This is useful when: * A manual intervention resolves the condition the timer was waiting for * You need to expedite a time-sensitive request * Testing workflow behavior without waiting for delays *** ## Workflow attribution in tickets Each ticket event log shows which workflow triggered the change, including the workflow name, run ID, timestamp, and changed field values. Click the workflow badge on any ticket event to open the workflow run in a new tab and inspect the full run details. Use this to trace any automated update back to its source workflow. Workflow attribution helps you debug unexpected ticket changes, understand automation impact, and meet compliance requirements. *** ## Log management Workflow logs are retained for analysis and compliance. Run logs use a standard retention period, while error logs have extended retention. Export logs before the retention period expires if you need long-term storage. Log access is controlled by user permissions. View logs for workflows you own or manage. Workspace administrators can see all workflow logs. *** ## Failure notifications Configure notifications to receive alerts when workflow runs fail. Set up notifications from the workflow **Settings** tab. Failure notifications fire when a run finishes in either **Failed** or **Completed with errors**. The notification copy adapts to the run's final status so recipients can tell at a glance whether the workflow halted entirely or completed end-to-end with at least one step error. Subscribe to email notifications for workflows you manage to receive personal failure alerts Configure Slack channels to notify entire teams when critical workflows fail ### Configuring failure notifications Navigate to your workflow and select the **Settings** tab Toggle **Email me on failures** to receive personal email alerts when the workflow fails Connect a Slack channel to post team notifications when workflow runs fail Trigger a test failure to verify notifications are delivered correctly ### Email notifications Personal email alerts notify you when workflows encounter failures. Each email includes the workflow name, run ID, and a direct link to the failure details. The subject line and body reflect whether the run **failed** or **completed with errors**. Emails include a one-click unsubscribe link that requires no authentication. **Use email notifications when:** * You need personal alerts for critical workflows * You want offline notification access * You manage workflows requiring immediate attention ### Slack notifications Team Slack notifications post failure alerts to channels where your team collaborates. Messages include Block Kit formatting with clickable buttons and a direct link to run details. The message header reads **Workflow Run Failed** or **Workflow Run Completed With Errors** depending on the run's final status. **Use Slack notifications when:** * Teams need collective awareness of failures * Failures require coordinated response * Multiple people share responsibility for workflow reliability Email and Slack notifications work independently. You can enable both to ensure critical workflow failures reach your team through multiple channels. ### Unsubscribing from emails Workflow failure emails include a one-click unsubscribe link at the bottom. To resubscribe, visit the workflow **Settings** tab and toggle email notifications back on. Unsubscribe links are unique to each user and workflow. Clicking an unsubscribe link only affects your notifications for that specific workflow. *** ## Tips * **Set up failure notifications early.** Configure email and Slack alerts before relying on a workflow in production. * **Review error patterns regularly.** Look for increasing failure rates or performance degradation that might indicate systemic issues. * **Test after changes.** Monitor the first few executions closely after updating a workflow. * **Keep integrations healthy.** Refresh credentials before they expire and verify API permissions when integrations add new features. * **Document resolved issues.** Keep notes on what went wrong and how you fixed it. This helps troubleshoot similar problems faster next time. Learn more about [building workflows](/documentation/automate/workflows/workflow-builder) and [publishing workflows](/documentation/automate/workflows/publish) ## Run and step statuses **Run statuses:** | Status | Meaning | | --------------------- | ----------------------------------------------------------------- | | Pending | Queued, waiting for execution resources | | Running | Actively executing steps | | Completed | All steps finished successfully | | Completed with errors | Run reached the end of the workflow but at least one step errored | | Failed | Run halted because a step encountered an unrecoverable error | | Cancelled | Stopped manually or by system (e.g., Stop & Publish) | **Step statuses:** | Status | Meaning | | --------- | -------------------------------------------------------------------------------------- | | Pending | Not yet started | | Running | Currently executing | | Completed | Finished successfully | | Failed | Encountered an error | | Skipped | All immediate parents failed or were skipped, or the incoming edge condition was false | | Waiting | Paused on a wait step (Wait for Approval, Wait for Message, etc.) | *** ## What step logs capture Each step records: * **Resolved inputs:** The actual values used after dynamic references are resolved. * **Raw outputs:** The data produced by the step. * **AI reasoning:** For AI Decision Maker and Custom Prompt steps, the model's explanation for its output or decision. * **Duration:** Execution time for the step. * **Error details:** Error type, message, and context if the step failed. * **Retry attempts:** Number of retries and outcomes. *** ## Error types and retry behavior | Error type | Cause | Retries | Notes | | -------------- | -------------------------------------------------- | ------------------------------------- | ---------------------------------------------------- | | Validation | Missing fields, invalid formats, type mismatches | No | Fix the workflow configuration | | Integration | Connection timeout, API error, service unavailable | Yes (3 attempts, exponential backoff) | Check integration health and external service status | | Authentication | Expired credentials, insufficient permissions | No | Refresh credentials in integration settings | | Timeout | Step took too long to complete | Yes | Check external service performance | | Rate limit | Too many API requests | Yes (with backoff) | Reduce workflow frequency or stagger execution | Retries use exponential backoff: 1 second, then 2 seconds, then 4 seconds. After 3 failed attempts, the step fails permanently and the run is marked as failed. *** ## Retrying a run A run can be retried when its status is **Failed**, **Completed with errors**, or **Completed**. The **Retry** action appears in the row actions menu of the workflow runs table. Selecting it opens a dialog with up to three options: * **Retry with latest version** — Start a new run from the first step using the workflow's current active version. Only offered when the original run used an older version. * **Retry from failure** — Reuse outputs from successful upstream steps and rerun only the failed step(s). Requires that the upstream workflow shape and step configurations are unchanged between versions. Only offered when the run has at least one failed step. * **Retry from beginning** / **Rerun** — Start a new run from the first step using the same version as the original run. The new run is linked to the original through a parent run reference, which lets you trace retry chains. ### API `POST /workflows/runs/{runId}/retry` Body fields: | Field | Type | Notes | | ------------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `versionId` | string, optional | Workflow version for the new run. Defaults to the original run's version. Pass the workflow's active version ID to upgrade to the latest | | `retryFromFailure` | boolean, optional | If `true`, reuses successful upstream outputs and reruns the failed step(s). Otherwise the new run starts from the first step | Returns `{ runId }` for the new run. If the workflow shape upstream of the failed step changed between versions (a step was added, removed, or reconfigured), `retryFromFailure` returns an error. Fall back to starting from the beginning in that case. *** ## Skipping wait steps Workspace admins can skip Wait and Wait Until steps on a running workflow run. When a run is paused at a timer step, open the run details and click **Skip** on the waiting step to advance the workflow immediately. This is available only to workspace admins and only while the step is in a **Waiting** state. *** ## Debugging patterns **Workflow not triggering:** 1. Verify the workflow is published (not draft or paused). 2. Check trigger filters. Filters use AND logic, so overly specific filters may exclude the event. Test with relaxed filters first. 3. Confirm required integrations are connected (for integration-based triggers). 4. Check if another workflow is handling the same event first. **Action failing:** 1. Open the run log and find the failed step. 2. Check the resolved inputs. A common cause is a dynamic value reference resolving to null or an unexpected type. 3. Verify the integration is connected and credentials are valid. 4. Check external service status (Jira, Okta, etc. may be experiencing issues). 5. Test the same action with hardcoded values to isolate whether the issue is data or configuration. **Incorrect data in actions:** 1. Check the resolved inputs on the problematic step. Compare expected vs. actual values. 2. Verify the dynamic reference points to the correct upstream step and field. 3. Check for name collisions if multiple steps have similar names. 4. Review the trigger output to confirm the expected data was present in the originating event. **Slow execution:** 1. Check individual step durations to identify the bottleneck. 2. External API calls are the most common cause of slow steps. 3. Consider parallelizing sequential steps that are independent. 4. If a wait step is involved, verify the timeout configuration. *** ## Workflow attribution Ticket events include workflow attribution: the workflow name, run ID, and timestamp. Click the workflow badge to open the workflow run directly in a new tab. This lets you trace any automated ticket change back to the specific workflow run that caused it. Useful for debugging unexpected ticket changes, auditing automation impact, and understanding which workflows affect which tickets. *** ## Failure notifications Configure email and Slack notifications from the workflow Settings tab. * **Email:** Personal alerts with workflow name, run ID, and a direct link to the failure. Includes one-click unsubscribe. * **Slack:** Team notifications posted to a configured channel with formatted details and a link to run details. Notifications fire for runs that end in **Failed** *or* **Completed with errors**. Subject line, email body, and the Slack header reflect which terminal status the run reached. Set up failure notifications before relying on a workflow in production. Both channels work independently and can be enabled simultaneously. # Workflows Source: https://docs.ravenna.ai/documentation/automate/workflows/overview Build no-code automated workflows that respond to ticket and Slack events and execute actions across your integrated tools using a visual builder.
![Workflows overview](https://d1kzozfjh72w00.cloudfront.net/documentation/screenshots/automate/workflows/Overview-light.png)
![Workflows overview](https://d1kzozfjh72w00.cloudfront.net/documentation/screenshots/automate/workflows/Overview-dark.png)
Build automated workflows that respond to events and execute actions across your integrated systems. The visual builder connects triggers and actions without any coding required. ## What you can do Assign tickets to team members based on category, priority, or custom fields Notify teams in Slack when high-priority tickets are created or status changes occur Create or update issues in Jira, Linear, or other ticketing systems when tickets are created Automate Okta user provisioning, group assignments, and password resets Trigger PagerDuty or Incident.io workflows when critical issues are detected Check on-call schedules and route tickets to the appropriate responder *** ## Workflows vs agent rules Workflows and agent rules both automate work, but they fit different situations. | | Workflows | Agent rules | | ---------------------- | -------------------------------------- | ------------------------------- | | **How they run** | Background automation | Conversational, real-time | | **What starts them** | Events, schedules, or manual triggers | User messages to the agent | | **How you build them** | Visual builder with steps and branches | Natural language instructions | | **User interaction** | No interaction during execution | Interactive dialogue with users | ### Using both together Workflows and agents both automate work, but they run independently. Agents handle conversations with users — answering questions, collecting information, categorizing requests, and creating or updating tickets. Workflows handle event-driven backend processing — provisioning access, creating issues in external systems, or running multi-step approval flows. Agents cannot trigger workflows directly. Instead, connect the two through ticket state: have the agent create or update a ticket (set a category, apply tags, submit a form, or change status), and configure a workflow that fires on that ticket event. You can build workflows manually with the visual builder or use Copilot to generate them from a natural language description. Start with simple workflows manually and use Copilot for more complex automation. *** ## How workflows work Every workflow has a **trigger** that starts the automation and one or more **actions** that perform tasks. When the trigger condition is met, the workflow executes its connected actions in sequence, in parallel, or through converging branches that rejoin into a single path. ### Triggers Triggers listen for events like ticket creation, status changes, or Slack reactions. Add filters to ensure workflows only activate for relevant events. Available triggers include ticket created, ticket assigned, form submitted, category assigned, status changed, tags changed, task completed, message sent, cron schedule, and third-party integration events. ### Actions Actions perform tasks like creating tickets, sending Slack messages, or calling external APIs. Data flows between steps automatically, so information from the trigger is available in subsequent actions. Available actions include ticket management (create, update, assign, set status), messaging (Slack, email), integration actions (Jira, Linear, Okta, Google Workspace), AI steps (summarize, decision maker, custom prompt), and control flow (conditional, if/else, wait, goto). Microsoft Teams: a dedicated **Send Microsoft Teams Message** workflow action is not yet available. Ticket triggers (created, status changed, and so on) fire for tickets opened in Microsoft Teams just like Slack. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview). ### Data flow Information flows automatically between workflow steps. Reference data from triggers or previous actions using dynamic values in the workflow builder. Click a field input and select from available data sources. Values resolve when the workflow runs, and the builder highlights invalid references before publishing. See all available [triggers and actions](/documentation/automate/workflows/triggers-actions) with configuration details *** ## Common use cases **Auto-triage support tickets:** Categorize and assign incoming tickets based on keywords, priority, or requester information. Route high-priority issues to senior engineers and standard requests to the general support queue. **Sync tickets with Jira:** Create Jira issues when tickets are created in specific channels or categories. Keep status synchronized between systems and notify requesters when issues are resolved. **Automate user onboarding:** Automate Okta account creation, group assignments, and access provisioning based on department or role information from HR tickets. **Escalate critical issues:** Escalate high-priority or SLA-breaching tickets by notifying management, creating PagerDuty incidents, or triggering on-call workflows. *** ## Getting started Organize workflows by team or process using [collections](/documentation/automate/workflows/collections) Add a trigger and connect actions using the [visual builder](/documentation/automate/workflows/workflow-builder) Test your workflow with manual triggers, then [publish](/documentation/automate/workflows/publish) to make it active View detailed [logs](/documentation/automate/workflows/monitor) for every workflow run *** ## Tips * **Start with one specific scenario.** Build a linear workflow that handles a single case. Add branching and complexity after you confirm the basics work. * **Use Copilot for complex workflows.** Describe what you want in plain language and Copilot builds the trigger, steps, and connections for you. * **Name steps clearly.** Descriptive step names make workflows easier to understand when multiple team members work with them. * **Keep workflows focused.** Create separate workflows for distinct processes rather than one workflow that handles everything. * **Test before publishing.** Use manual triggers with realistic data. Check edge cases like missing fields or error conditions. Learn more about [building workflows](/documentation/automate/workflows/workflow-builder), [triggers and actions](/documentation/automate/workflows/triggers-actions), and [Copilot workflow building](/documentation/automate/copilot/build-automations) ## System overview A workflow is a background automation: one trigger connected to one or more actions. When the trigger event fires and passes its filters, the workflow engine creates a run and executes the action graph. Actions can run sequentially, in parallel branches, or through converging paths that wait for all parents to complete. | | Workflows | Agent rules | | -------------------- | ---------------------------------------------- | -------------------------------- | | **Execution** | Background, asynchronous | Conversational, real-time | | **State** | Multi-step with wait states, approvals, delays | Stateless, single-turn responses | | **Triggers** | Events, schedules, agent handoff | User messages | | **Branching** | Conditional paths, parallel execution | Linear rule matching | | **External systems** | Native integration actions, HTTP requests | Tool calls | **Use workflows when you need:** approval gates, parallel execution across systems, scheduled automation, wait states (for messages, approvals, inactivity), multi-step orchestration with error handling. **Use agent rules when you need:** conversational information gathering, simple ticket updates, interactive dialogue, single-action responses. *** ## Available building blocks **Triggers:** Ticket lifecycle (created, assigned, status changed, tags changed, archived, approval decision), form submitted, task events (completed, template applied), message sent, Slack reactions (added/removed), cron schedule, and third-party integration events. **Actions by category:** * **Ticket management:** Create Ticket, Update Ticket, Set Status, Set Priority, Add Assignee, Add Followers, Add Approvers, Add Tags, Move Ticket, Share Ticket, Search Tickets, Publish Ticket, Link Ticket, Apply Task Template, Send CSAT * **Wait and monitoring:** Wait (duration), Wait Until (absolute date), Wait for Approval, Wait for Message, Wait for Inactivity, Monitor Ticket, Check for New Messages * **Control flow:** Conditional, If/Else, Goto, Loop * **AI:** Summarize Ticket, AI Decision Maker, Custom Prompt * **Messaging:** Send Message, Send Email * **HTTP:** HTTP Request (external API calls) * **Integrations:** Okta, Google Workspace, Slack, Jira, Linear, Fleet, Jamf, and others (see integration docs) For detailed descriptions and use cases for each trigger and action, see the triggers and actions reference. *** ## Agent-workflow integration Agents cannot trigger workflows directly. Connect the two through ticket state: have the agent create or update a ticket, and configure a workflow that fires on that change. Common handoff patterns: * **Form submission.** The agent asks the user for details and submits a form on the ticket. Configure a Form Submitted workflow to run backend processing (provisioning, approvals, external system sync). * **Category assignment.** The agent classifies the request with `@Set Category`. Configure a Category Assigned workflow to route the ticket or kick off category-specific automation. * **Tag or status change.** The agent applies a tag or moves the ticket to a status. Configure a Tags Changed or Status Changed workflow to react. * **Ticket creation.** The agent publishes a ticket into the appropriate queue. Configure a Ticket Created workflow (filtered by queue, category, or form) to take it from there. **Recommended pattern:** Use the agent to handle the conversation (collecting information, answering questions, categorizing) and use workflows for the backend execution that follows. Ticket events are the handoff. *** ## Common patterns and recommended approaches **Approval flows:** Trigger on ticket creation or form submission. Add approvers (use Round Robin for load balancing or All for any-available approval). Add a Wait for Approval step, then branch into approved, declined, and timeout paths. The approved path provisions access or executes the request. The declined path notifies the requester with the reason. The timeout path escalates the request, reassigns to a backup approver, or auto-closes the ticket as expired. **Employee onboarding and provisioning:** Trigger on form submission in the IT queue. Use parallel branches to provision across systems simultaneously: Okta group assignment, Google Workspace account, Slack channel invites. Converge the branches, then send a summary notification. Each branch is independent, so one failure does not block the others. **Ticket escalation:** Trigger on status change or inactivity. Use a conditional to check priority or SLA outcome. Escalation path reassigns the ticket, notifies management, and optionally creates an incident in PagerDuty or Incident.io. Non-escalation path sends a reminder. **External system sync:** Trigger on ticket creation. Create an issue in Jira, Linear, or another system. Use the Link Ticket action to attach the external issue URL back to the Ravenna ticket. This maintains bidirectional traceability. **Scheduled maintenance:** Use a Cron trigger for recurring tasks like checking for stale tickets, sending digest reports, or running periodic cleanup. Cron-triggered workflows do not have ticket context, so you cannot reference ticket fields in downstream steps. **Wait-then-follow-up:** After an action (like sending a message or requesting info), add a Wait for Message or Wait for Inactivity step. Branch based on whether a response was received (timeout vs. success). Use this for follow-up reminders or auto-resolution after inactivity. *** ## Constraints and gotchas * **One trigger per workflow.** If you need the same actions for multiple events, create separate workflows or use a broad trigger with conditional branching. * **Cron triggers have no ticket context.** You cannot use ticket dynamic values in workflows triggered by a schedule. Use cron workflows for batch operations that query or iterate over tickets via other means. * **Agents cannot trigger workflows directly.** Hand off through ticket state (form submitted, category assigned, tags changed, status changed) and let a workflow fire on that event. * **Converging branches wait for all parents.** A converging step does not execute until every parent branch completes or is skipped. Design parallel branches to be independent so one slow branch does not delay the entire workflow. * **Wait steps have timeouts.** Wait for Message and Wait for Approval both default to 3 days. Wait for Approval branches into On Approved, On Declined, and On Timeout, so always plan a path for stalled approvals (escalate, reassign, or auto-close). * **Published workflows are live immediately.** There is no staging environment. Test thoroughly in draft mode before publishing. *** ## Building guidance * **One workflow per process.** Do not combine unrelated automations into a single workflow. Separate workflows are easier to debug, monitor, and maintain. * **Start linear, add complexity later.** Build a straight-line workflow first (trigger, then action, then action). Add conditional branches and parallel paths only after the linear version works. * **Name workflows descriptively.** The agent references workflows by name in rules. Clear names like "IT Access Provisioning" or "Jira Sync for Engineering" make rules more readable. * **Generate complex workflows from descriptions.** For multi-branch workflows with many actions, generating the structure from a natural language description and then reviewing the result is more efficient than building step by step. * **Prefer native integration actions over HTTP Request.** If an integration has a dedicated action (Okta, Jira, Linear, etc.), use it instead of calling the API via HTTP Request. Native actions handle authentication, error handling, and output parsing automatically. # Publish Source: https://docs.ravenna.ai/documentation/automate/workflows/publish Publish Ravenna workflows to activate triggers, then manage draft, published, and paused states as your automation requirements change over time. Publish workflows to activate automatic execution based on configured triggers. Manage workflow lifecycles by updating, pausing, and unpublishing workflows as your processes change. ## Workflow states Workflows progress through different states during their lifecycle. Draft workflows can be edited and tested but will not execute automatically. Use draft state to build, refine, and test automation before activation. **What you can do:** * Edit triggers and actions * Add or remove workflow steps * Test with manual triggers * Validate workflow configuration **Cannot:** Execute automatically based on triggers Published workflows are active and respond to triggers automatically. All executions are logged and tracked. You can edit published workflows, and changes take effect only after you publish again. Paused workflows stop accepting new runs while allowing in-flight executions to complete. This provides a controlled way to temporarily halt workflow execution. **When to use:** * Temporarily stop workflow activity during maintenance * Allow running workflows to complete before making changes * Gracefully wind down workflow execution Deleted workflows are soft deleted, preserving historical records while removing them from active use. Execution history is preserved and can be restored by support if needed. *** ## Publishing workflows Ensure your workflow has a trigger and at least one action The system automatically checks for required fields, proper connections, and valid configurations Address any highlighted issues before publishing Confirm publication to activate your workflow Check that the workflow appears in your active workflows list You need appropriate permissions to publish workflows within a collection. Contact your workspace administrator if you cannot publish workflows. *** ## Validation requirements Before publishing, workflows are validated to ensure they will work correctly. **Requirements:** * Exactly one trigger configured * All required trigger fields completed * Valid filters and conditions * Proper channel or event selection **Common issues:** * Missing trigger configuration * Invalid channel selection * Incomplete filter conditions **Requirements:** * At least one action connected to trigger * All required fields populated * Valid dynamic references * Proper integration permissions **Common issues:** * Missing required fields * Invalid dynamic value references * Disconnected integrations **Requirements:** * All actions connected to trigger or previous actions * No orphaned steps * No circular dependencies * Valid execution flow **Common issues:** * Disconnected actions * Circular references between steps * Invalid execution order **Requirements:** * All referenced integrations connected * Valid authentication credentials * Proper API permissions * Active integration status **Common issues:** * Disconnected integrations * Expired credentials * Insufficient API permissions *** ## Updating published workflows Edit published workflows without stopping them. A banner appears at the top of the editor showing "This workflow has unpublished changes" with publish and discard options. The banner persists until you publish or discard. When you are ready to apply your changes, choose a publish method: | Method | Behavior | When to use | | ------------------ | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | | **Publish** | In-flight workflows continue uninterrupted. New runs use the updated configuration. | Most updates. Safer and less disruptive. | | **Stop & Publish** | Stops all currently running workflows immediately. All new runs use the updated configuration. | Fixing critical bugs where existing runs must not continue with the old version. | To abandon your edits, click **Discard changes** to revert to the last published version. All unpublished edits are removed. This cannot be undone. The system shows how many active runs will be stopped when using "Stop & Publish" to help you make an informed decision. Use "Stop & Publish" carefully. Stopping running workflows may interrupt in-progress automation. Coordinate with your team when stopping workflows that affect shared processes. *** ## Unpublishing workflows Unpublish workflows to stop them from responding to triggers. Click the **Unpublish** button on a published workflow Select how to handle existing runs: **Pause:** Running workflows continue until completion, but new runs are blocked. The workflow can be republished to resume. Recommended for most situations. **Deactivate:** All running workflows are stopped immediately, new runs are blocked, and the workflow returns to draft state. Use only when an immediate stop is required. The dialog shows how many active runs will be affected. Review and confirm your choice. Deactivating a workflow stops running workflows immediately, which may leave processes in incomplete states. Coordinate with your team when deactivating workflows that affect shared processes. *** ## Tips * **Test before publishing.** Test workflows in draft state with manual triggers and realistic data. Monitor the first few executions closely after publishing. * **Use "Publish" by default.** Letting running workflows complete with the old version while new runs use the updated version is safer than stopping everything. Only use "Stop & Publish" for critical bug fixes. * **Start with limited scope.** Begin with workflows that affect a small subset of tickets or users. Expand scope after verifying reliable operation. * **Coordinate with your team.** Communicate with stakeholders before publishing workflows that affect shared processes. * **Add descriptions.** Explain the workflow's purpose and any recent changes in the description. This helps team members understand updates and troubleshoot issues. Learn more about [building workflows](/documentation/automate/workflows/workflow-builder) and [monitoring workflows](/documentation/automate/workflows/monitor) ## Workflow lifecycle states | State | Accepts new runs | In-flight runs | Editable | Can transition to | | ------------- | ---------------- | ---------------------- | --------------------------------- | ---------------------------------------- | | **Draft** | No (manual only) | N/A | Yes | Published | | **Published** | Yes | Running | Yes (creates unpublished changes) | Paused, Draft (via Deactivate) | | **Paused** | No | Continue to completion | Yes | Published, Draft (via Deactivate) | | **Deleted** | No | Stopped | No | N/A (soft delete, restorable by support) | *** ## State transitions * **Draft to Published:** Requires passing validation (trigger configured, actions connected, no orphans, no cycles, integrations active, required fields populated). * **Published to Published (update):** Two methods: * **Publish:** In-flight runs continue with old version. New runs use updated version. Default choice for most updates. * **Stop & Publish:** Stops all in-flight runs immediately. All new runs use updated version. Use only for critical bug fixes where old-version runs must not continue. * **Published to Paused:** Stops accepting new runs. In-flight runs complete. Use for temporary maintenance or gradual wind-down. * **Published to Draft (Deactivate):** Stops all in-flight runs immediately and blocks new runs. Use only when immediate stop is required. * **Paused to Published:** Resumes accepting new runs. *** ## Publishing validation The workflow engine checks before publishing: * Exactly one trigger with all required fields. * At least one action connected to the trigger. * All nodes reachable from trigger (no orphans). * No circular dependencies. * All required fields populated on every node. * All dynamic value references point to valid upstream steps and fields. * All required integrations are connected and authenticated. *** ## Editing active workflows When a published workflow is edited, changes are held as an unpublished draft overlay. The published version continues running unchanged until changes are explicitly published or discarded. * **Publish** applies changes to new runs only. In-flight runs are unaffected. * **Stop & Publish** stops in-flight runs, then applies changes to all new runs. * **Discard** reverts to the last published version, removing all pending edits. *** ## Recommendations * **Default to Publish over Stop & Publish.** Letting in-flight runs complete with the old version avoids interrupting active processes. Stop & Publish should be reserved for critical bug fixes. * **Test in draft mode before publishing.** There is no staging environment. Manual triggers with realistic data are the primary testing mechanism. * **Start with limited scope.** Filter triggers narrowly at first (specific channel, specific category). Widen scope after confirming the workflow works reliably. * **Coordinate team communication.** Workflows that affect shared processes should be published with team awareness. Unexpected automation changes can disrupt operations. # Triggers & actions Source: https://docs.ravenna.ai/documentation/automate/workflows/triggers-actions Reference for all Ravenna workflow triggers and actions, including ticket events, Slack reactions, integration actions, and configuration details. Every workflow needs exactly one trigger that starts the automation and one or more actions that perform tasks. This page documents all available triggers and actions. *** ## Triggers Triggers listen for specific events and provide context to the rest of the workflow. ### Ticket triggers Fires when new tickets are created. Filter by channel, form, or priority. **Common use cases:** * Auto-assign tickets based on form or channel * Send welcome messages to requesters * Notify team members of new tickets * Route tickets to specialized teams Fires when forms are submitted or when form data is updated on existing tickets. Filter by specific forms. **Trigger behavior:** * Fires when a ticket is created with form data * Fires when form field values are updated on existing tickets **Common use cases:** * Route tickets based on submitted form type * Trigger approval workflows for access request forms * Send notifications when specific forms are submitted Fires when categories are assigned or changed on tickets. Filter by specific categories. **Trigger behavior:** * Fires when a ticket is created with a category * Fires when a category is changed on an existing ticket **Common use cases:** * Route tickets based on assigned category * Auto-assign tickets from specific categories to specialized teams * Escalate tickets when high-priority categories are assigned Fires when tickets are archived. Use this to clean up related resources or send final notifications. **Common use cases:** * Clean up related Slack channels * Send final status notifications * Update external tracking systems Fires when tickets are assigned to users. **Common use cases:** * Notify assignees of new assignments * Update workload tracking systems * Send assignment confirmation messages Fires when tickets move between statuses. Filter by channel or assignee. **Common use cases:** * Send notifications on status changes * Update external systems when tickets are resolved * Trigger follow-up workflows based on status Fires when tags are added to or removed from tickets. **Output data:** * `ticketId` - The ID of the ticket that was updated * `action.added` - Array of tag IDs that were added * `action.removed` - Array of tag IDs that were removed **Common use cases:** * Escalate tickets when priority tags are added * Notify teams when specific tags are applied * Auto-assign tickets based on tag changes Fires when tickets are approved or declined through approval workflows. **Common use cases:** * Continue workflows after approval * Notify stakeholders of decisions * Provision access after approval * Handle declined requests Fires when an [SLA](/documentation/automate/slas) changes state on a ticket. Use this to react to SLA lifecycle events such as breaches, alerts, attachments, and successful completions. **Status options:** * **SLA Attached** - Fires when an SLA is first applied to a ticket. Use this to acknowledge the commitment or notify stakeholders. * **SLA Alert** - Fires when an SLA alert threshold is crossed, before a breach occurs. Use this for early warnings and escalations. * **SLA Breached** - Fires when an SLA target is missed. Use this for escalation, reassignment, or stakeholder notifications. * **SLA Met** - Fires when all SLA targets on a ticket are satisfied. Use this for confirmation messaging or reporting. **Output data:** * `ticketId` - The ID of the ticket whose SLA outcome changed **Common use cases:** * Escalate tickets and notify managers when an SLA is breached * Send early-warning pings to assignees on SLA alerts * Confirm to requesters when SLA commitments are met * Apply tags or update priority when an SLA is attached Fires when a scheduled reminder on a ticket reaches its fire time. Use this to drive follow-up automations when a ticket has been sitting without the expected action. **Configuration:** * **Reminder Type** (optional): Limit the trigger to a specific reminder type. Leave empty to fire on any reminder. Supports approval reminders and assignment reminders, which are scheduled automatically when an approver or assignee has not acted within the configured window. **Output data:** * `ticketId` - The ID of the ticket the reminder was attached to * `reminderType` - The type of reminder that expired (`Approval` or `Assignment`) **Common use cases:** * Nudge approvers in Slack or email when an [approval reminder](/documentation/tickets/reminders) fires * Reassign or escalate a ticket when an [assignment reminder](/documentation/tickets/reminders) fires * Post a private note on the ticket summarizing pending approvers Fires when an entitlement changes status. An entitlement is an individual access grant to a user for a specific user group, created when an [access request](/documentation/automate/access-provisioning/overview) is approved. **Configuration:** * **Statuses** (required): Select one or more entitlement statuses to trigger on. A single rule can fan out across multiple outcomes, so you do not need to duplicate the trigger for each status. * **Processing** - Provisioning or deprovisioning has started. For manual access levels this is the point at which someone needs to grant access. * **Access Provisioned** - The user was successfully granted access. * **Access Deprovisioned** - The user's access was successfully removed. * **Provision Failed** - Granting access failed. * **Deprovision Failed** - Removing access failed. * **Skipped Provisioning** - Provisioning was skipped (for example, the user already had access). * **Skipped Revocation** - Revocation was skipped (for example, another active grant still requires the access). **Output data:** * `ticketId` - The ID of the access request ticket that owns the entitlement * `entitlementId` - The ID of the entitlement whose status changed. Expand it to read `applicationId`, `accessLevelId`, `userGroupId`, `userId`, and `entitlementStatus`. **Common use cases:** * Notify the requester when their access is provisioned * Alert the IT team when provisioning or deprovisioning fails * Fan out one workflow across **Access Provisioned**, **Deprovision Failed**, and **Skipped Provisioning** together Learn more about [access requests and entitlements](/documentation/automate/access-provisioning/entitlements) ### Task triggers Fires when individual tasks within a task template are marked as completed. Provides access to both the completed task and the next task in the sequence for creating handoffs. **Output data:** * `ticketId` - The ID of the ticket containing the task * `taskItemId` - The ID of the completed task item * `currentTask` - Information about the task that was just completed * `nextTask` - Information about the next task in the sequence (if any) * `currentTaskAssigneeIds` - User IDs of assignees on the completed task * `nextTaskAssigneeIds` - User IDs of assignees on the next task * `hasMoreTasks` - Boolean indicating if there are more tasks remaining **Common use cases:** * Notify next task assignees when their task becomes active * Send completion notifications to stakeholders * Create task handoffs between team members * Escalate if tasks are completed outside SLA windows Fires when a task template is applied to a ticket. Use this to kick off workflows that depend on structured task lists being attached to tickets. **Common use cases:** * Notify assignees when a task template is applied * Trigger onboarding or checklist workflows * Set ticket status or priority based on the applied template ### Message triggers Fires when messages are added to tickets. **Configuration:** * **Message Authors** (optional): Limit the trigger to messages from specific users or groups. * **Visibility** (optional): Restrict the trigger to either `Public` or `Private` messages. Leave unset to fire on both. * **Public**: Messages visible to requesters and external channels. * **Private**: Internal-only [private notes](/documentation/tickets/private-notes) that stay hidden from requesters. * **Filters** (optional): Add filter groups to match on additional message or ticket attributes. **Common use cases:** * Analyze message content or sentiment * Notify team members of updates * Trigger automated responses * Route only public replies to customer-facing workflows, or only private notes to internal review flows ### Scheduled triggers Runs workflows on a recurring schedule defined by a standard cron expression. **Configuration:** * **Schedule** - A standard 5-field cron expression (`minute hour day-of-month month day-of-week`). Use the inline picker to build common schedules, or type an expression directly. Examples: * `0 * * * *` - Every hour, on the hour. * `0 9 * * 1-5` - 9:00 AM, Monday through Friday. * `0 0 1 * *` - Midnight on the first day of each month. * `*/15 * * * *` - Every 15 minutes. * **Timezone** - The timezone the schedule runs in. Defaults to UTC. Choose from regions including US, Europe, Asia Pacific, and other Americas. **Common use cases:** * Schedule recurring reports or cleanup tasks * Automate periodic ticket reviews * Run time-based processes Cron-triggered workflows have no ticket context, so they cannot reference ticket fields. Use them for batch operations, reports, or system maintenance. ### Webhook triggers Starts a workflow when an external system posts to a unique webhook URL. The trigger uses an AI prompt to parse the incoming request body into structured fields that downstream steps can reference. **How it works:** 1. Add the Webhook trigger to a workflow. 2. Copy the generated **Direct URL** and configure it as the destination in the emitting system. 3. Write a **Prompt** that describes how to transform the incoming payload into the fields you need downstream. 4. When the external system posts to the URL, Ravenna runs the prompt against the request body and starts the workflow with the parsed output. **Configuration:** * **Direct URL** - Read-only URL to register with the upstream webhook emitter. Click to copy. * **Prompt** - Instructions for transforming the incoming webhook body into structured data for downstream actions. **Authentication:** The Direct URL contains a unique, unguessable identifier and does not require API keys, signatures, or additional headers to accept a request. Treat the URL itself as a secret: anyone who has it can trigger the workflow. * Store the URL in your emitter's secret manager rather than pasting it into shared documents or public code. * If the URL is ever exposed, remove the Webhook trigger and add a new one to rotate to a fresh URL. * If the upstream system supports it, restrict egress by IP allowlist on the emitter side. Outbound calls made later in the workflow (for example, from an **HTTP Request** action) support API Key, Bearer Token, and Basic Auth using vault-stored credentials. * **Webhook response HTTP status code** - Status code Ravenna returns to the emitter once the run is accepted. Choose the value the emitter expects: * `200 OK` (default) - Generic success. * `201 Created` - Emitter expects a "created" acknowledgment. * `202 Accepted` - Emitter expects an asynchronous acceptance signal. * `204 No Content` - Emitter expects an empty body response. Set this to match what the upstream system requires for a successful delivery. Some webhook providers retry or disable the endpoint if they receive an unexpected status, so pick the code their documentation specifies. **Common use cases:** * Receive events from systems without a native Ravenna integration * Bridge custom internal tools into workflow automation * Trigger workflows from monitoring or alerting platforms ### Third-party integration triggers Many integrations provide workflow triggers for events in their systems. See the [Integrations overview](/integrations/overview) to explore available triggers and actions for each integration *** ## Actions Actions perform work in your workflows using information from triggers and previous actions. ### Ticket actions Creates a new ticket with configurable properties like title, description, channel, priority, and tags. Use trigger data to populate ticket details. **Cross-workspace creation:** Select any queue you have access to, including queues in other workspaces. If the destination queue is in a different workspace, Ravenna treats this as a cross-workspace create and publishes the ticket immediately. Triggers, notifications, and downstream workflows in the destination workspace fire as if the ticket were created normally. Same-workspace creates continue to skip downstream dispatch to prevent the workflow from retriggering itself. **Common use cases:** * Create follow-up tickets for multi-step processes * Generate tickets from Slack messages or external events * Split complex requests into multiple tickets * Hand off work to another team's workspace and let their automations pick it up Modifies existing tickets by changing properties like priority, tags, status, assignee, requester, parent ticket, or custom fields. **Common use cases:** * Escalate tickets by changing priority * Add processing or status tags * Update custom fields based on workflow logic * Set a parent ticket to organize tickets into a hierarchy * Reassign the requester when a ticket is submitted on behalf of someone else Changes ticket status with optional resolution notes. **Common use cases:** * Auto-resolve tickets meeting specific criteria * Move tickets through workflow stages * Add resolution notes automatically Updates ticket priority based on workflow conditions. **Common use cases:** * Escalate urgent issues automatically * Adjust priorities based on SLA requirements * Reprioritize based on ticket content analysis Assigns tickets to specific users or groups. When you select a group, it is automatically expanded to its individual members when the workflow runs. **Assignment strategy:** * **All**: Assigns every selected user (or every member of the selected group) to the ticket. * **Round Robin**: Assigns one user from the selected list or group using rotation to balance workload. **Round Robin rotation scope:** Each Add Assignee step keeps its own independent rotation. If a workflow has multiple Add Assignee steps configured with Round Robin, each step rotates through its assignees on its own counter. Two steps that share the same user list assign in parallel rotations rather than continuing a single shared rotation. This lets you stage hand-offs (for example, a triage assignee and a follow-up reviewer) without one step skipping members of the other step's group. **Common use cases:** * Distribute tickets across a group with Round Robin for load balancing * Assign based on expertise or tags * Route tickets to specific groups or teams * Stage multiple Round Robin assignments (triage, then review) within a single workflow without interfering rotations Adds followers to tickets to keep stakeholders informed. Select from Ravenna members or groups, including groups synced from third-party integrations. **Common use cases:** * Add managers to high-priority tickets * Include cross-functional stakeholders * Notify relevant parties automatically Adds approvers to a ticket and creates an approval round. Select from Ravenna members or groups. **Assignment strategy:** * **All**: Assigns everyone in the selected list as approvers. Any one of them can approve. * **Round Robin**: Assigns one approver from the list using rotation to balance workload. * **Auto**: System bot auto-approves immediately (use for conditional approval branches). **Common use cases:** * Route approvals to managers with load balancing via Round Robin * Add all qualified approvers and let the first available person approve * Assign approvers by department using Round Robin for fair distribution Pauses workflow execution until the ticket's approval rounds complete or the configured timeout expires. The step branches into three outcome paths: **On Approved**, **On Declined**, and **On Timeout**. **Configuration:** * **Duration**: Maximum time to wait for a response before falling through to the **On Timeout** branch. Default is 3 days. Accepts values like `1h`, `2d`, `1w`, or `Forever` to wait indefinitely. **Behavior with assignment strategies:** * **Auto**: Workflow continues immediately down **On Approved** (auto-approved by system bot) * **All**: Waits for any one of the assigned approvers to respond * **Round Robin**: Waits for the single assigned approver to respond * Honors the assignment strategy set by preceding "Add Approvers" actions **Output data:** * `isApproved` - Boolean indicating whether the ticket was approved * `isTimedOut` - Boolean indicating whether the wait expired before a response was received **Branch logic:** * **On Approved** runs when `isApproved` is `true`. * **On Declined** runs when `isApproved` is `false` and `isTimedOut` is `false`. * **On Timeout** runs when `isTimedOut` is `true`. Use this branch to send escalation reminders, reassign approvers, or close the ticket as expired. **Common use cases:** * Gate access provisioning until approved * Escalate to a backup approver when the primary does not respond in time * Auto-close stale approval requests after a deadline passes Pauses workflow execution until specific users send messages on a ticket. Automatically excludes workflow-generated and AI-generated messages. **Configuration:** * **Message Authors**: Select users or groups whose messages resume the workflow * **Timeout Duration**: Maximum wait time (default: 3 days, supports "1h", "2d", "1w") * **Message Sources** (optional): Filter by Web, Email, or Slack. If not specified, all sources are accepted. **Output data:** * `isSuccess` - Boolean indicating if a matching message was received before timeout * `ticketMessageId` - The ID of the message that resumed the workflow (if successful) **Common use cases:** * Wait for customer responses before proceeding * Pause until specific team members provide input * Hold workflow until user confirms information Adds tags to tickets for categorization and filtering. **Common use cases:** * Auto-tag based on content analysis * Categorize by form type * Add processing status tags Relocates tickets between workspaces, channels, or statuses. Supports cross-workspace moves while maintaining ticket history and context. **Common use cases:** * Transfer tickets between teams * Escalate to different departments * Move tickets across workspaces Shares a ticket to a destination queue in another workspace. Unlike Move Ticket, the original ticket stays in its current queue and a shared reference is created in the destination. Select a workspace first, then select a queue within that workspace. **Common use cases:** * Give another team visibility into a ticket without transferring ownership * Share requests across departments for collaborative resolution * Broadcast tickets to multiple queues for cross-team awareness Sends customer satisfaction surveys to users after ticket resolution. **Common use cases:** * Survey after ticket resolution * Measure service quality * Gather user feedback Monitors tickets until specific conditions are met, then continues workflow execution. **Common use cases:** * Wait for status changes before proceeding * Monitor for specific ticket updates * Trigger actions when conditions are met Pauses workflow execution until a ticket has been inactive for a specified duration. Helps keep channels clean and SLAs on track. **Common use cases:** * Auto-resolve tickets after inactivity period * Send reminder messages before auto-closing * Escalate tickets with no response Sends new messages on tickets. **Common use cases:** * Send automated updates to requesters * Request additional information * Provide automated status notifications Checks if there are any new messages on a ticket since the last check. **Common use cases:** * Detect user responses in monitoring workflows * Track conversation activity * Trigger actions when new messages appear Attaches links to external resources on the original Ravenna ticket. Maintains references to related external resources for visibility and audit trails. **Input fields:** * `ticketId` - The Ravenna ticket to attach the link to * `name` - Descriptive name for the link (e.g., "Related Jira Issue") * `url` - The external URL to link to **Output data:** * `isSuccess` - Boolean indicating if the link was created successfully * `ticketLinkId` - The ID of the created ticket link * `ticketId` - The ID of the linked ticket * `url` - The URL that was linked **Common use cases:** * Link to external tickets in other systems (Jira, Linear, GitHub Issues) * Reference related Slack channels created for incidents * Create audit trails for external resource creation Publishes a newly created ticket, making it visible and triggering any associated notifications. Use after creating a ticket when you need to control the timing of publication separately from creation. **Common use cases:** * Create and configure a ticket across multiple steps before making it visible * Control when notifications are sent for new tickets * Finalize ticket properties before publishing Imports a task template into a ticket, attaching a structured checklist of tasks. The template's tasks, assignees, and ordering are applied to the ticket. **Common use cases:** * Attach onboarding checklists to new hire tickets * Apply standard operating procedures to incident tickets * Add review checklists based on ticket type or category Marks one or more task list items as complete on the trigger ticket. Use this to automatically check off tasks when conditions are met, such as completing an onboarding checklist item after an approval is granted. **Inputs:** | Input | Description | | ------------- | ------------------------------------------------------------------------------------------------------------ | | Task template | The task template whose items should be completed. | | Task items | Which items from the template to mark as done. Select specific items or choose "All" to complete every item. | Searches for tickets matching specified criteria. Returns matching tickets that can be referenced in downstream workflow steps. **Common use cases:** * Find related or duplicate tickets * Look up tickets by requester, status, or custom fields * Check for existing tickets before creating new ones Searches for users in your organization matching specified criteria. Returns a list of user IDs that downstream steps can reference (for example, to add assignees, followers, or approvers, or to iterate over with Loop). **Configuration:** * **User Filter**: One or more filter groups that define which users to return. Filter on user attributes such as name, email, or group membership. Ravenna combines groups with OR and combines conditions inside a group with AND. * **Limit**: Maximum number of users to return (default 50, maximum 50). **Output data:** * `userIds` - Array of user IDs matching the filter **Common use cases:** * Look up the members of a group or team to notify or assign * Find users by attribute for routing decisions * Build a dynamic recipient list for downstream Add Assignee, Add Followers, or Send Email steps * Combine with Loop to run actions per matching user ### Control flow actions **Duration units** accepted by `Wait` and other duration fields: | Unit | Accepted values | | ------ | --------------------------------- | | Years | `years`, `year`, `yrs`, `yr`, `y` | | Months | `months`, `month`, `mo` | | Weeks | `weeks`, `week`, `w` | | Days | `days`, `day`, `d` | | Hours | `hours`, `hour`, `hrs`, `hr`, `h` | Pauses workflow execution for a specified duration. **Common use cases:** * Add delays between actions * Wait for external processes to complete * Create timed follow-ups Pauses workflow execution until a specific date or a date relative to a target. Use this to schedule actions around key dates like onboarding, license renewals, or contract deadlines. **From date:** * The target date the wait calculates from. * Accepts a fixed date or a [dynamic value](/documentation/automate/workflows/workflow-builder#data-flow-and-dynamic-values) from the trigger or a previous step (for example, a date field from a form submission or an action output). * Use a dynamic value when the date depends on ticket data, such as an access start date or a contract end date provided at runtime. **Offset scheduling:** * Set an optional offset to run the workflow relative to the From date. * Positive offsets (e.g., `5d`) wait until after the From date. * Negative offsets (e.g., `-5d`) wait until before the From date. * Example: an offset of `-5d` on an onboarding date of March 20 resumes the workflow on March 15. **Common use cases:** * Send reminders before a deadline or renewal date * Trigger onboarding tasks relative to a start date * Schedule follow-ups after a target date * Coordinate multi-step processes around key milestones Evaluates conditional expressions to branch workflow logic. **Common use cases:** * Branch workflow logic based on ticket properties * Filter actions by conditions * Implement decision trees Provides if/else branching to execute different actions based on conditions. **Common use cases:** * Execute different actions based on ticket properties * Handle multiple scenarios with alternative paths * Create conditional workflow branches Jumps to a specific step in the workflow. **Common use cases:** * Create workflow loops * Skip steps based on conditions * Implement retry patterns Iterates through a collection of items, executing the contained actions for each item. Use loops to process lists of users, tickets, or other data sets within a workflow. **Common use cases:** * Process multiple items from a search result * Send notifications to a list of users * Perform bulk operations across a set of tickets ### AI actions Generates a concise summary of a ticket's conversation history, capturing what happened, what was decided, and what outcomes were achieved. **Common use cases:** * Generate ticket summaries for handoffs * Create executive briefings * Summarize resolution steps Evaluates conditions that require contextual analysis beyond simple rule-based logic. The workflow continues down one of two paths based on the AI's decision. **Common use cases:** * Route tickets based on content analysis * Evaluate sentiment for escalation * Determine appropriate next actions Runs AI reasoning with custom instructions to analyze context, generate responses, or make decisions within the workflow. **Common use cases:** * Draft response messages based on ticket content * Extract structured data from unstructured text * Analyze sentiment or urgency from messages * Generate dynamic next steps from conversation history ### Messaging actions Sends an email to specified users. Configure recipients, subject, and body content with dynamic values from the workflow. **Body formatting:** The body field is a rich text editor. Use the formatting toolbar to add **bold**, *italic*, lists, links, and headings. Type formatted text directly in the editor instead of pasting raw HTML or Markdown. Insert dynamic values from earlier workflow steps to personalize each send. **Recipients added as followers:** When this action sends an email from a ticket, Ravenna automatically adds the recipients as followers on that ticket. This keeps them in the loop on future agent replies. Both resolved Ravenna users and extra email addresses that map to users in your organization are included. * Existing followers, approvers, the requester, assignee, and author are skipped. * Email addresses that don't match a Ravenna user are ignored. * Followers are not added when the ticket is marked as private. * If adding followers fails, the email is still sent and the error is logged. **Inputs:** | Input | Description | | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Sender Name | Optional display name shown on the From address (for example, `Acme Support`). If left blank, Ravenna uses the queue's agent branding name, the workspace bot's first name, or the default bot name in that order. | | Sender Address | Optional local part of the From address (before the `@`). Ravenna appends your verified custom email domain to produce an address like `helpdesk@acme.com`. Requires a [verified email domain](/documentation/platform/organizations/email-domains); the field is disabled otherwise. Characters outside `a-z`, `0-9`, `.`, `_`, `%`, `+`, and `-` are stripped. | | Attachments | Optional file attachments to include with the email. Reference files from the trigger ticket or previous workflow steps. | **Sender address behavior:** * When a verified email domain exists and Sender Address is set, Ravenna sends from `@` for branded From. * When the workflow is bound to a ticket, Ravenna sets Reply-To to the ticket-scoped address (`ticket+@…`) so customer replies still thread back to the same ticket. * When no verified email domain exists, Sender Address is disabled and Ravenna falls back to the default support sender (`support@`) for ticketless sends, or the ticket-scoped address when running on a ticket. **Common use cases:** * Notify external stakeholders who are not in Slack * Send formal communications like approval confirmations or access grants * Deliver summary reports or status updates via email * Loop additional teammates into a ticket by emailing them from a workflow ### Tools actions Calls external APIs to integrate with third-party services. Supports authentication using credentials stored in your organization's Vault. **Configuration:** * **URL** - The API endpoint to call * **Method** - HTTP method: GET, POST, PUT, DELETE, or PATCH * **Headers** - Custom key-value headers to include in the request * **Query parameters** - Key-value pairs appended to the URL * **JSON body** - Request body content (for POST, PUT, PATCH, DELETE) * **Timeout** - Maximum wait time for a response (default: 10 seconds, max: 45 seconds) * **Fail on error** - Whether the step fails when the API call fails (default: enabled). When disabled, the workflow continues to the next step with `isSuccess` set to `false` and the error message available in `Response.Error`. **Authentication methods:** * **None** - No authentication * **API Key** - Sends an API key in a configurable header (default: `X-API-Key`). Select a vault credential to provide the key value. * **Bearer Token** - Sends a token in the `Authorization: Bearer` header. Select a vault credential to provide the token value. * **Basic Auth** - Sends a username and password as a Base64-encoded `Authorization: Basic` header. The password field supports vault credentials. **Output data:** * `isSuccess` - Boolean indicating if the response status code is 2xx * `Response.Body` - The response body from the API * `Response.StatusCode` - The HTTP status code * `Response.Error` - The error message when the call fails and **Fail on error** is disabled **Handling failures:** By default, a failed API call fails the step and stops the workflow. Disable **Fail on error** to continue instead. The step returns `isSuccess: false`, `Response.StatusCode: 500`, and the error message in `Response.Error`, so later steps can branch on the result. For example, a Condition step can check `isSuccess` and post a Slack message with `Response.Error` when the call fails. **Common use cases:** * Send data to external systems * Fetch information from third-party APIs * Trigger actions in other platforms * Integrate with services that lack a native Ravenna integration Ravenna only sends `Content-Type: application/json` when the request actually has a body. A GET, or a DELETE with an empty body, goes out with no `Content-Type` at all, so strict servers that reject a content type on a bodyless request now accept the call. Set the header yourself under **Headers** if an API needs it regardless. Interpolated values in single-line fields such as **URL** are inserted literally. Underscores, asterisks, and other markdown characters in a variable pass through unchanged, so a token like `{{ticket.slug}}` resolving to `my_ticket_id` produces a working URL. ### Third-party integration actions Many integrations provide workflow actions for automating tasks in their systems. See the [Integrations overview](/integrations/overview) to explore available triggers and actions for each integration *** ## Tips * **Use specific trigger filters.** Narrow triggers with channel, priority, status, or user criteria to avoid unnecessary executions. * **Make actions idempotent.** Configure actions so they can be safely repeated without causing problems. This improves reliability when workflows retry after failures. * **Name steps clearly.** Descriptive names make workflows easier to understand and debug. * **Test with realistic data.** Pay attention to edge cases and error conditions. * **Document non-obvious logic.** Add descriptions explaining business rules so team members understand why workflows behave in certain ways. Learn more about [building workflows](/documentation/automate/workflows/workflow-builder) and [monitoring workflows](/documentation/automate/workflows/monitor) ## Trigger selection guide ### Ticket lifecycle triggers | Trigger | When it fires | Best for | | -------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------- | | Ticket Created | New ticket appears | Initial routing, notifications, external system sync | | Form Submitted | Form data submitted or updated on a ticket | Structured request processing, approval flows | | Category Assigned | Category set or changed | Category-based routing, team assignment | | Ticket Status Changed | Status transitions | Status-based notifications, follow-up actions | | Ticket Assigned | Assignee added | Assignment notifications, workload tracking | | Ticket Archived | Ticket archived | Cleanup, final notifications, external sync | | Ticket Tags Changed | Tags added or removed | Tag-based routing, escalation triggers | | Ticket Approval | Approval decision made | Post-approval provisioning, decline handling | | SLA Outcome | SLA attached, alerting, breached, or met | SLA escalations, early-warning notifications, breach handling | | Reminder Expired | A scheduled reminder on a ticket fires | Approval nudges, escalation of stale approvals | | Entitlement Status Changed | An entitlement's provisioning status changes | Access request provisioning notifications, failure handling | | Message Sent | New message on ticket (filterable by author and visibility) | Response monitoring, sentiment analysis, private-note routing | | Task Completed | Task item completed | Task handoffs, sequential workflow progression | | Task Template Applied | Task template applied to a ticket | Onboarding workflows, checklist-driven processes | ### Other triggers | Trigger | When it fires | Best for | | ---------------------- | --------------------------------------------- | -------------------------------------------------------- | | Slack Reaction Added | Emoji reaction added in Slack | Ticket creation from reactions, acknowledgment tracking | | Slack Reaction Removed | Emoji reaction removed | Undo or cleanup workflows | | Cron | Recurring schedule | Periodic reports, stale ticket cleanup, batch operations | | Webhook | Inbound HTTP POST to the trigger's Direct URL | Bridging external systems without a native integration | Microsoft Teams reaction triggers are not yet exposed as workflow triggers. Teams uses a fixed 5-reaction set ([emoji actions](/integrations/microsoft-teams/emoji-actions)) that drive built-in ticket actions but are not available as custom workflow triggers in the current beta. ### Trigger selection tips * **Ticket Created vs Form Submitted:** Use Ticket Created for broad routing. Use Form Submitted when you need to react to specific form types or when form field values drive the workflow logic. * **Form Submitted fires on updates too.** If form field values are changed on an existing ticket, Form Submitted fires again. Design workflows to handle re-triggers gracefully. * **Category Assigned fires on creation too.** If a ticket is created with a category already set, this trigger fires. You do not need both Ticket Created and Category Assigned for the same workflow. * **Tags Changed provides add/remove context.** The trigger output includes which tags were added and which were removed, so you can branch on whether a specific tag was added vs. removed. * **Task Completed includes next-task info.** The output includes the next task in the sequence and its assignees, making it ideal for handoff notifications without additional lookups. * **Cron triggers have no ticket context.** Cron-triggered workflows cannot reference ticket fields. Use them for batch operations, reports, or system maintenance tasks. ### Trigger filters All triggers support filters that narrow when the workflow activates. Filters use AND logic: all conditions must be true for the trigger to fire. If you need OR logic, create separate workflows for each condition. *** ## Action selection guide ### Ticket management | Action | What it does | When to use | | ------------------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | Create Ticket | Creates a new ticket in any workspace you have access to | Follow-up tickets, splitting requests, ticket generation from events, cross-workspace handoffs | | Update Ticket | Modifies ticket properties including requester and parent ticket | Adding context, changing fields, setting parent-child relationships | | Set Status | Changes ticket status | Auto-resolution, stage progression | | Set Priority | Changes ticket priority | Auto-escalation, SLA-based priority adjustment | | Add Assignee | Assigns users or groups | Routing, load balancing with Round Robin | | Add Followers | Adds followers to ticket | Stakeholder notification, cross-team visibility | | Add Approvers | Creates an [approval round](/documentation/tickets/approvals/rounds) with approvers | Approval flow setup | | Add Tags | Adds tags to ticket | Categorization, processing markers | | Move Ticket | Moves ticket between workspaces or channels | Cross-team transfers, department escalation | | Share Ticket | Shares ticket to a queue in another workspace | Cross-team visibility, collaborative resolution | | Send Message | Sends a message on ticket | Status updates, requesting information | | Link Ticket | Attaches external URL to ticket | Linking Jira/Linear issues, audit trails | | Publish Ticket | Publishes a newly created ticket | Controlling notification timing, multi-step ticket setup | | Apply Task Template | Applies a task template to a ticket | Onboarding checklists, standard operating procedures | | Complete tasks | Marks task list items as complete on a ticket | Auto-completing checklist items after approvals or conditions are met | | Search Tickets | Finds tickets matching criteria | Duplicate detection, related ticket lookup, bulk operations | | Search Users | Finds users matching filter criteria | Dynamic recipient lists, group member lookup, attribute-based routing | | Send CSAT | Sends satisfaction survey | Post-resolution feedback collection | ### Wait and monitoring | Action | What it does | When to use | | ---------------------- | --------------------------------------------- | --------------------------------------------------------- | | Wait | Pauses for a duration | Delays between actions, timed follow-ups | | Wait Until | Pauses until a specific date and time | Calendar-based deadlines, date-driven actions | | Wait for Approval | Pauses until approved, declined, or timed out | Approval gates with timeout fallback for stalled requests | | Wait for Message | Pauses until a message is received | Waiting for user input or confirmation | | Wait for Inactivity | Pauses until ticket is inactive | Auto-resolution after no activity | | Monitor Ticket | Watches for conditions | Waiting for specific ticket state changes | | Check for New Messages | Checks for recent messages | Detecting responses in polling-style workflows | ### Control flow | Action | What it does | When to use | | ----------- | ----------------------------- | --------------------------------------------------------------- | | Conditional | Evaluates expressions | Branching based on data values | | If / Else | Binary branching | Simple true/false path selection | | Goto | Jumps to another step | Retry patterns, skipping steps | | Loop | Iterates through a collection | Processing search results, bulk notifications, batch operations | ### AI actions | Action | What it does | When to use | | ----------------- | -------------------------------- | --------------------------------------------------------- | | Summarize Ticket | Generates a conversation summary | Handoff summaries, executive briefings | | AI Decision Maker | AI-powered branching | Content analysis, sentiment-based routing, complex triage | | Custom Prompt | Runs custom AI reasoning | Data extraction, response drafting, dynamic analysis | ### Messaging | Action | What it does | When to use | | ---------- | ------------------------------ | --------------------------------------------------------- | | Send Email | Sends email to specified users | External stakeholder notifications, formal communications | ### Tools | Action | What it does | When to use | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | | HTTP Request | Calls external APIs with configurable URL, method, headers, query params, JSON body, timeout, and auth (None, API Key, Bearer, Basic). Auth fields support vault-stored credentials. Returns isSuccess, Response.Body, Response.StatusCode, Response.Error. Can fail the step on error or continue with failure details. | Custom integrations without native actions, external API calls, webhook triggers | *** ## Action selection tips * **Add Assignee supports Round Robin.** When assigning from a group, Round Robin distributes evenly across members. Use "All" when every member of the group should be assigned. * **Round Robin rotates per step, not per workflow.** Each Add Assignee step has its own rotation counter. A workflow with two Round Robin Add Assignee steps maintains two independent rotations, even when both reference the same group. * **Add Approvers + Wait for Approval work together.** Add Approvers creates an [approval round](/documentation/tickets/approvals/rounds) with the selected approvers. Wait for Approval pauses execution until the round completes. The wait step honors the assignment strategy: All means any one approver can respond, Round Robin means the specific assigned approver must respond. * **Wait for Approval with Auto strategy** approves immediately (system bot). Use this for workflows where approval is conditional and only required in some branches. * **Wait for Approval has a configurable timeout.** Default is 3 days. The step branches into On Approved, On Declined, and On Timeout. Always design the On Timeout path (escalation, auto-close, or notify) so stalled approvals do not leave the workflow stuck. * **Wait for Message filters by author and source.** You can specify which users' messages resume the workflow and which channels (Web, Email, Slack) count. Workflow-generated and AI-generated messages are automatically excluded. * **Wait for Message has a configurable timeout.** Default is 3 days. Always plan for both success and timeout paths. * **Prefer native integration actions over HTTP Request.** Native actions (Jira, Okta, Linear, etc.) handle auth, error handling, and output parsing. Use HTTP Request only when no native action exists. * **AI Decision Maker is for judgment calls, not data checks.** Use Conditional or If/Else for checking field values. Use AI Decision Maker when the decision requires interpreting content, sentiment, or context. * **Custom Prompt is versatile.** Use it to extract structured data from unstructured text, draft responses, analyze sentiment, or generate dynamic content. Its output can drive downstream conditional logic. * **Link Ticket creates bidirectional traceability.** After creating an external issue (Jira, Linear), use Link Ticket to attach the URL back to the Ravenna ticket. This makes it easy to navigate between systems. * **Goto enables retry patterns.** Use Goto with a conditional to create retry loops (e.g., check condition, then if not met: wait, then goto the check step again). Be cautious of infinite loops. * **Loop + Search Tickets work together.** Use Search Tickets to find a set of matching tickets, then Loop to process each result (send notifications, update fields, etc.). * **Search Users feeds downstream people steps.** Pipe the `userIds` output into Add Assignee, Add Followers, Add Approvers, or Send Email to build dynamic recipient lists. Combine with Loop to act on each user individually. * **Wait vs Wait Until.** Wait pauses for a relative duration ("2 hours"). Wait Until pauses until an absolute date and time. Use Wait Until when the timing depends on a date from ticket data (e.g., a start date form field). * **Apply Task Template attaches structured checklists.** Combine with the Task Completed trigger on a separate workflow to create handoff chains between task assignees. * **Send Email for external stakeholders.** Use Send Email when recipients are outside Slack or need formal email communications. For internal team notifications, prefer Slack messages. *** ## Data flow between steps Every trigger and action produces output data that downstream steps can reference. * **Trigger data** includes the full event context: ticket properties, requester info, custom field values, timestamps, and event-specific data (e.g., which tags changed, which task completed). * **Action output** varies by action type: created ticket IDs, API response data, success/failure indicators, AI-generated text. * **Scope:** A step can reference data from any step that is a direct ancestor in the workflow graph. Steps in parallel branches cannot reference each other's data. * **Converging steps** have access to data from all completed parent branches. *** ## Constraints * **Trigger filters use AND logic.** All filter conditions must be true. For OR logic, create separate workflows. * **One trigger per workflow.** You cannot have multiple triggers on a single workflow. * **Assignment strategies are set per action.** Add Assignee and Add Approvers each independently support All or Round Robin. Round Robin rotation state is also tracked per Add Assignee step, so multiple Add Assignee steps in the same workflow do not share a rotation counter. * **Wait for Approval inherits the strategy** from the preceding Add Approvers action. * **Wait for Message excludes automated messages.** Workflow-generated and AI-generated messages do not count as matching messages. # Workflow builder Source: https://docs.ravenna.ai/documentation/automate/workflows/workflow-builder Build automated Ravenna workflows in the visual workflow builder by connecting triggers and actions, configuring data flow, and publishing to run. Create automated workflows using the visual builder. Connect a trigger to one or more actions, configure data flow between steps, and publish to start automating. Use Copilot to build workflows from a natural language description. Describe what you want to automate and Copilot generates the trigger, steps, and connections for you. Copilot cannot publish workflows directly. After Copilot builds a workflow, open the workflow editor to review and publish it. ## Create your first workflow Open **Workflows** from your workspace sidebar, select or create a collection, then click **New → Workflow**. Ravenna creates an untitled draft and opens it in the builder. Rename the workflow from the header once you start designing it. To start from a pre-built structure instead, click **New → Template** (see [Templates](#templates)). Select a trigger that defines what event starts your automation. Add filters to ensure the trigger only activates for relevant events, such as specific channels, ticket properties, or custom field values. Connect actions that perform the tasks you want to automate. Set up each action with the appropriate inputs and use dynamic values to reference data from the trigger or previous steps. Use manual triggers to verify each step works correctly, then [publish](/documentation/automate/workflows/publish) to make the workflow active *** ## Working with triggers and actions Every workflow needs exactly one trigger and at least one action. Triggers respond to events in your workspace, external systems, or run on schedules. Actions perform tasks using information from the trigger and previous steps. **Common trigger types:** * **Ticket triggers**: Activate when tickets are created, updated, assigned, or change status * **Slack triggers**: Respond to reactions or messages in Slack * **Schedule triggers**: Run workflows at specific times or intervals * **Manual triggers**: Start workflows on demand for testing or batch operations **Common action types:** * **Ticket actions**: Create, update, assign, or manage tickets * **Messaging actions**: Send messages to Slack, email, or other channels * **Integration actions**: Create issues in Jira, Linear, or manage users in Okta * **AI actions**: Summarize tickets, make decisions, or run custom prompts * **Control flow**: Branch execution with conditional logic, wait for events, or loop ### Unconfigured steps When you add a step before deciding what it does, Ravenna drops in a placeholder card labeled **Select action event**. Click it to pick the action. You do not have to fill it in before you keep building. A placeholder can take steps below it and can branch, so you can lay out the shape of a workflow first and choose the actions afterwards. Publishing still requires every step to be configured, so any placeholder left behind will be flagged before the workflow can go live. ### Integration requirements Some actions require configured integrations. Actions that depend on third-party services show a Setup Required badge. Hover to see which integration is needed, then connect it from your workspace settings. See all available [triggers and actions](/documentation/automate/workflows/triggers-actions) with detailed configuration options *** ## Converging branches Converging branches merge multiple parallel paths back into a single step. Use them when your workflow branches out for parallel work and then needs to rejoin for a shared next step, like sending notifications through multiple channels before updating a ticket. ### Connect and disconnect steps You can only remove individual connections when a step has multiple parents. If a step has a single parent, delete the step itself to remove it from the workflow. ### Execution behavior ```mermaid theme={"system"} graph TD trigger[Trigger: Ticket created] --> slack[Send Slack message] trigger --> jira[Create Jira issue] slack --> update[Update ticket status] jira --> update style trigger fill:#E2EAEF,stroke:#E2EAEF,color:#000 style slack fill:#E2EAEF,stroke:#E2EAEF,color:#000 style jira fill:#E2EAEF,stroke:#E2EAEF,color:#000 style update fill:#22c55e,stroke:#22c55e,color:#fff ``` **Update ticket status** waits for both **Send Slack message** and **Create Jira issue** to finish before it runs. What happens next depends on how those paths resolved: | Parent path results | Converged step behavior | | ---------------------------- | ------------------------------------------------- | | All parents completed | Executes using data from all paths | | Some completed, some failed | Executes using data from the completed paths only | | Some completed, some skipped | Executes using data from the completed paths only | | All parents failed | Skipped | | All parents skipped | Skipped | A failure in one parallel branch no longer blocks its siblings. As long as at least one immediate parent completes successfully, the downstream step runs and can reference outputs from the parents that did complete. Reference [dynamic values](#data-flow-and-dynamic-values) defensively when a parent path may fail, since the referenced fields will be missing on runs where that branch did not produce outputs. The workflow builder automatically prevents circular dependencies. You cannot create a connection that would cause a step to depend on itself, either directly or through a chain of other steps. *** ## Data flow and dynamic values Reference data from triggers or previous actions using dynamic values. This lets workflows adapt to the specific event that triggered them. ### Trigger data Access information from the event that started your workflow, including ticket properties (title, description, priority, status, Display ID, Short ID), requester information (name, email), custom field values, Slack thread data, and timestamps. **Example:** Use ticket priority from the trigger to determine which Slack channel receives a notification. **Example:** Include the Slack thread link in a webhook payload so external systems can link back to the original conversation. Access it via **Ticket > Slack > Thread > Link**. #### Ticket identifiers Tickets expose three identifiers in the variable picker. Use the one that matches what your downstream system or message expects: | Variable | Example | When to use | | -------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Display ID** | `BUGZ-123` | Human-readable identifier for messages, emails, and external system references. This is what users see in the Ravenna UI and Slack. | | **Short ID** | `abc12345` | Stable 8-character identifier for URLs, deep links, and API lookups. Useful when you need a compact, unique reference that does not change if the ticket moves channels. | | **Ticket ID** | `clx1a2b3c4d5e6f7g8h9i0j` | Full internal CUID. Use for API calls or integrations that require the canonical identifier. | **Example:** Pass the Display ID into a Slack message body so the recipient sees `BUGZ-123` instead of an internal ID. Access it via **Ticket > Display ID**. **Example:** Append the Short ID to an external URL (`https://example.com/?ref=abc12345`) so you can correlate the ticket later without exposing the channel prefix. Access it via **Ticket > Short ID**. ### Action outputs Reference results from previous workflow actions, including created ticket IDs, Jira or Linear issue keys, Okta user IDs, Slack thread links, and API response data. **Example:** Add a Jira issue link to the original ticket after creating it. ### Using the value picker Click a field input in the workflow builder and select from available data sources. Values resolve when the workflow runs. The builder highlights invalid references before you publish. *** ## Managing steps Right-click any step in the workflow builder to open a context menu with quick actions, or use the step menu (three-dot icon) on the step card. ### Reorder steps Drag a step to reposition it in the workflow. Grab a step by its card and drop it onto a highlighted target to move it up or down within a linear chain, or to swap it with another step. Ravenna rewires the surrounding connections for you, so dynamic values from earlier steps keep resolving in the new order. Some steps stay pinned and cannot be dragged: * Trigger and placeholder steps * Loop boundary markers * Branch group roots, such as the top of an If/Else split or an approval branch Reordering a step changes the order actions run in. Check that any [dynamic values](/documentation/automate/workflows/workflow-builder#data-flow-and-dynamic-values) referenced by a moved step still come from a step that runs before it. ### Duplicate a step Copy a single step or an entire branch to reuse configuration: * **Duplicate node** copies the selected step and inserts it directly below the original. Use the context menu or press + D (Mac) / Ctrl + D (Windows/Linux). * **Duplicate tree** copies the selected step and all of its downstream steps, preserving the branch structure. Use the context menu or press + Shift + D (Mac) / Ctrl + Shift + D (Windows/Linux). Steps inside loops cannot be duplicated. ### Delete a step Remove steps from the workflow using the context menu or step menu. When deleting a step that has downstream steps, you can choose: * **Delete node** removes only the selected step * **Delete tree** removes the selected step and all of its downstream steps Steps that other parts of the workflow depend on may be protected from deletion. See all [keyboard shortcuts](/documentation/get-started/shortcuts#workflow-builder-shortcuts) including workflow builder shortcuts *** ## Testing workflows Test workflows before publishing to verify they work correctly. Manually trigger your workflow with test data View detailed logs showing what happened at each step Confirm each action produced the expected results Try different scenarios like missing fields or error conditions Draft workflows can be edited and tested but will not execute automatically. Publish your workflow to make it active. *** ## Templates Start faster with pre-built templates. Templates provide ready-made workflow structures for common IT operations that you can deploy and customize. From the workflows list, click **New → Template** to open the template library. Browse available templates filtered by tags or search by name. Select a template and click **Create Workflow**. The template is copied to your workspace with a pre-filled name and description. Fill in the step-specific inputs for your organization, such as selecting an Okta application, choosing a Google group, or specifying a Slack channel Test the workflow to verify it works with your configuration, then publish to make it active After deploying a template, you have full control over the workflow. Modify steps, add new actions, change the trigger, remove steps that are not needed, or rename the workflow to match your organization's terminology. Templates are starting points. *** ## Tips * **Start simple.** Begin with linear workflows that handle one specific scenario. Add complexity gradually as you confirm each piece works. * **Name steps descriptively.** Clear step names make workflows easier to understand and debug, especially when multiple team members work with them. * **Test with realistic data.** Use data that represents actual conditions. Pay attention to edge cases and error conditions. * **Plan for failures.** Add conditional logic that checks action results. Consider what should happen if external systems are unavailable. * **Keep workflows focused.** Create separate workflows for distinct processes rather than one workflow that handles everything. Learn more about [triggers and actions](/documentation/automate/workflows/triggers-actions), [publishing](/documentation/automate/workflows/publish), and [monitoring workflows](/documentation/automate/workflows/monitor) Copilot can build workflows from natural language descriptions but cannot publish or activate them directly. After Copilot generates a workflow, a human must open the workflow editor to review and publish it. ## Workflow graph model A workflow is a directed acyclic graph (DAG) with one root trigger node. Action nodes connect to the trigger or to other actions via directed edges. Edges can be unconditional (always follow) or conditional (follow when criteria match). The graph must have no cycles, no orphaned nodes, and every action must be reachable from the trigger. **Placeholder nodes:** a step whose action has not been chosen yet is a placeholder, rendered as **Select action event**. Placeholders are ordinary graph nodes: they expose an outgoing connection point, accept child steps, and can be branched from, so a graph can be laid out before its actions are picked. They cannot be dragged to reorder, and they fail the required-fields validation until an action is selected. *** ## Connection patterns **Sequential:** Trigger, then A, then B, then C. Simple pipeline. Use for straightforward automations where each step depends on the previous. **Conditional branching:** Trigger, then Conditional or If/Else, then separate paths. Use If/Else for binary decisions. Use Conditional for expression-based evaluation. **Parallel execution:** Trigger connects to multiple actions that start simultaneously. Use when actions are independent and can run concurrently (e.g., notify Slack AND create Jira issue AND send email). **Parallel with convergence:** Trigger connects to actions A and B in parallel, both connect to action C. C waits for both A and B. Use when parallel work must complete before a shared next step. **Approval gate:** Trigger, then Add Approvers, then Wait for Approval, then branch on approved vs. declined. The Wait for Approval step pauses execution until a human responds. **Wait-and-branch:** Trigger, then action, then Wait for Message, then branch on response-received vs. timeout. Useful for follow-up flows. **Error-handling branch:** Connect a downstream step to a parent that may fail (e.g., an integration call) alongside its normal successor. The workflow engine advances downstream steps on any terminal parent status — `completed` or `failed` — so you can route recovery logic (log the error, notify a channel, open a ticket) off a failing step and gate it with a conditional edge that checks the parent's status or error output. ### Converging branch behavior A converging step waits for its parents to reach a terminal status before running: * **All parents completed:** the step executes with data from every path. * **Some parents completed, some failed or skipped:** the step executes with data from the completed paths only. References to fields on failed or skipped parents resolve to missing values, so guard those references with conditionals when needed. * **All parents failed:** the step is skipped. * **All parents skipped:** the step is skipped. Partial failure in a parallel branch does not cancel its siblings. As long as at least one immediate parent completes, the downstream step still runs. Use [conditional edges](/documentation/automate/workflows/triggers-actions) rather than relying on auto-skip when you need a downstream step to run only for specific parent outcomes. Circular dependencies are not allowed. The workflow engine rejects them at validation time. *** ## Step management operations Workflow steps can be duplicated or deleted to modify the graph structure. ### Duplication * **Duplicate node:** Copies a single step and inserts it directly below the original, between the original and its child steps. The copy inherits all configuration from the original. * **Duplicate tree:** Copies the selected step and all of its downstream steps, preserving the entire branch structure and configuration. Constraints: * Trigger nodes cannot be duplicated. * Some step types may have duplication restrictions. * Duplicated steps are independent copies. Modifying the original does not affect the copy. ### Deletion Steps can be removed from the workflow graph. Steps that other nodes depend on (for example, steps referenced by dynamic values in downstream actions) may be protected from deletion. Remove dependent references first. *** ## Common workflow recipes **Notification on ticket creation:** Trigger: Ticket Created (filtered by channel or priority). Then Send Slack Message to team channel. Then Add Tags for tracking. **Conditional routing:** Trigger: Ticket Created. Then If/Else (check priority). High priority path: Assign to senior team, then Notify manager. Normal priority path: Assign via Round Robin. **Approval gate with provisioning:** Trigger: Form Submitted (access request form). Then Add Approvers (manager, Round Robin). Then Wait for Approval. Approved path: Provision Okta group, then Send confirmation. Declined path: Notify requester with reason. **External system sync with link-back:** Trigger: Ticket Created (filtered by category). Then Create Jira Issue (populated from ticket fields). Then Link Ticket (attach Jira URL to Ravenna ticket). Then Send Slack message with Jira link. **Escalation after inactivity:** Trigger: Ticket Created. Then Wait (2 hours). Then Check for New Messages. If no messages: Reassign to escalation team, then Notify manager. If messages exist: end. **Parallel provisioning:** Trigger: Form Submitted (onboarding form). Then parallel paths: Create Okta account, Add to Google Workspace, Invite to Slack channels. Converge, then Send summary to requester. **Task handoff chain:** Trigger: Task Completed. Then Conditional (has more tasks?). Yes path: Notify next task assignees. No path: Set ticket status to resolved. **Round-robin assignment with notification:** Trigger: Ticket Created. Then Add Assignee (team group, Round Robin). Then Send Slack DM to assignee with ticket details. **Bulk stale ticket reminder (Loop):** Trigger: Cron (daily). Then Search Tickets (status = open, last updated more than 7 days ago). Then Loop through results. Inside loop: Send Message on each ticket reminding the assignee to update or resolve. **Scheduled access expiry (Wait Until):** Trigger: Form Submitted (access request form). Then Provision access (add to Okta group). Then Wait Until (expiry date from form field). Then revoke access (remove from Okta group). Then Send Message notifying the user their access has expired. *** ## Data flow between steps Data from the trigger and from each action's output is available to downstream steps. Reference earlier step data using dynamic value selectors when configuring action inputs. * **Trigger data** includes all event context: ticket fields (including Display ID like `BUGZ-123` and Short ID like `abc12345`), user info, custom field values, timestamps, and event-specific data (e.g., which tags changed, which task completed). * **Action output** varies by action type: created IDs, API response data, success/failure indicators, AI-generated text. * **Scope:** A step can reference data from any step that is a direct ancestor in the graph. Steps in parallel branches cannot reference each other's data. * **Converging steps** have access to data from all completed parent branches. * The builder validates references and highlights broken ones before publish. *** ## Validation rules Before publishing, the workflow engine validates: * **One trigger:** Exactly one trigger node must exist. * **Reachability:** All action nodes must be reachable from the trigger. * **No cycles:** The graph must be acyclic. * **No orphans:** No disconnected action nodes. * **Required fields:** All required fields on each node must be populated. * **Integration status:** Actions requiring integrations must have active connections. * **Valid references:** Dynamic value references must point to existing upstream steps and valid fields. *** ## Templates Templates are pre-built workflow structures for common IT operations. Creating a workflow from a template copies the entire structure (trigger, actions, connections) into a new workflow you can modify freely. Templates are starting points, not constraints. *** ## Integration requirements Actions that interact with external systems (Jira, Okta, Linear, Slack, Google Workspace, PagerDuty, etc.) require configured and authenticated integrations. If an integration is disconnected or credentials have expired, the action fails at runtime even if it passes validation at publish time. Check integration health before publishing workflows that depend on external systems. Prefer native integration actions over HTTP Request. Native actions handle authentication, error handling, and output parsing. Use HTTP Request only when no native action exists for the service you need. # Core concepts Source: https://docs.ravenna.ai/documentation/get-started/concepts Learn the core concepts in Ravenna including organizations, workspaces, channels, tickets, agents, knowledge, and forms that power your service desk. Ravenna is built around key concepts that work together to help you manage internal support requests. Your top-level account that contains all workspaces, members, integrations, and settings. Dedicated spaces for each team or department to manage their own tickets, channels, and workflows. Organize tickets by team, topic, or workflow. Each channel has its own settings, prefix, and integrations. The core unit of work in Ravenna. Created from Slack messages, emails, or forms, then tracked and resolved. AI assistants that answer questions from knowledge bases, create tickets, and escalate to humans when needed. Automate ticket routing, tagging, and actions with visual workflow builder. No code required. Connect Notion, Confluence, Google Drive, and other sources to power AI responses with accurate information. Collect structured information with custom fields when creating tickets to reduce back-and-forth. Create and manage tickets directly in Slack with native workflows and AI-powered responses. Track request volume, response times, and team performance to identify patterns and improve processes. Connect to Jira, Linear, Okta, and more. Bidirectional ticket replication keeps systems in sync. Create custom views to filter and organize tickets by workspace, channel, assignment, or status. Access quick actions and search across your workspace with keyboard shortcuts. The browser experience at app.ravenna.ai, with Admin for teams and a Portal for self-service. # What is Ravenna? Source: https://docs.ravenna.ai/documentation/get-started/overview Ravenna is a Slack-native, AI-powered service desk built for internal IT, HR, and operations teams to turn conversations into resolved requests. Ravenna Interface ## Internal support that works where your team works Teams rely on Slack, Notion, Linear, and other modern tools to get work done. Traditional service desks force you to leave these tools, create tickets in separate portals, and lose context in the process. Ravenna brings service desk capabilities directly into Slack, where your team already communicates. Most internal support starts informally in DMs, threads, or channel messages, not through formal ticket submission forms. ## Why Ravenna Ravenna is built for internal support teams managing IT, HR, operations, and RevOps requests. It combines Slack-native workflows, AI automation, and traditional service desk capabilities without the friction of legacy systems. Create and manage tickets directly in Slack without portals or context switching. Agents answer common questions and route complex requests automatically. Surface answers from Notion, Confluence, Slack history, and documentation. Track metrics, identify trends, and improve processes with analytics. ## Core capabilities Turn any Slack message into a ticket using shortcuts, emoji reactions, or slash commands. Work in public channels for transparency or use private flows for sensitive requests. All context stays in the original thread where requesters and responders can collaborate naturally. Deploy Agents that answer questions from your knowledge base, trigger workflows, and escalate to humans when needed. Configure Agent behavior with natural language rules and connect them to your tools. Learn more about [AI Agents](/documentation/automate/agents/overview) and their capabilities. Connect Notion, Confluence, Google Drive, Coda, Guru, Zendesk, Slack channels, and websites as knowledge sources. Ravenna indexes your documentation so Agents can provide accurate, up-to-date answers. Control exactly what gets indexed to maintain accuracy and relevance. Set up knowledge sources in [Knowledge](/documentation/automate/knowledge/overview). Automate ticket routing, tagging, status updates, and escalations. Build workflows that integrate with external tools and trigger actions based on ticket properties or events. Build automation with [Workflows](/documentation/automate/workflows/overview). Organize tickets with channels, tags, categories, and custom views. Each team sees only relevant tickets filtered by workspace, channel, or assignment. Support scales across departments without creating noise. Track request volume, response times, resolution rates, and team performance. Identify patterns and bottlenecks to improve processes. Explore metrics in [Analytics](/documentation/measure/analytics). ## How Ravenna works Ravenna connects to your Slack workspace and integrates with your existing tools. Users create tickets directly in Slack, AI Agents respond when they can, and your team handles complex requests with full context. Install Ravenna in your Slack workspace and configure channels for receiving requests. Create channels to organize tickets by team, topic, or workflow. Connect documentation sources, create custom forms for ticket submission, and set up categories to organize requests. Automate ticket routing, tagging, and actions with workflows that trigger based on ticket properties or events. Configure Agents with rules, knowledge sources, and workflows to automate responses. Users create tickets from Slack messages, and Agents respond or route to your team. Get started with our [setup guides](/guides/day-one/overview). ## Built for growing teams Ravenna scales from small teams to enterprise organizations. Start with basic ticket management in Slack and expand into AI automation, custom workflows, and multi-workspace deployments as your needs grow. Whether you support 50 employees or 5,000, Ravenna adapts to your processes without forcing you into rigid workflows. # Shortcuts Source: https://docs.ravenna.ai/documentation/get-started/shortcuts Keyboard shortcuts for the Admin: navigate workspaces, create and triage tickets, open the command launcher, and trigger common actions. Ravenna supports keyboard shortcuts for navigating your workspace, managing tickets, and accessing common actions. Shortcuts that use a modifier key work across platforms: on Mac maps to Ctrl on Windows and Linux, and (Option) on Mac maps to Alt on Windows and Linux. ## Global shortcuts These shortcuts work from anywhere in the Admin. Single-key shortcuts are disabled when you are focused on a text input. | Mac | Windows / Linux | Action | | --------------------------- | ------------------------------ | ---------------------------------------------------------------------------------- | | + K | Ctrl + K | Open the command launcher | | C | C | Create a new ticket | | ] | ] | Toggle the Copilot panel | | \[ | \[ | Toggle the left sidebar | ## Command launcher Press + K (Mac) or Ctrl + K (Windows/Linux) from anywhere in Ravenna to open the command launcher. The launcher provides search and quick actions in a single overlay. ### Search Start typing in the search field to find tickets, channels, and views across your workspace. Results appear as you type. **Navigate results:** * arrow keys to move through results * Enter to open the selected result * Esc to close the launcher ### Quick actions The following shortcuts are available globally and also close the command launcher if it is open. | Mac | Windows / Linux | Action | | --------------------------- | ----------------------------- | -------------- | | + 1 | Alt + 1 | Create ticket | | + 2 | Alt + 2 | Create channel | | + 3 | Alt + 3 | Invite members | | + 4 | Alt + 4 | Open settings | Learn more about creating tickets through the web interface in [Admin](/documentation/platform/admin). ## Ticket shortcuts These shortcuts are available when viewing a ticket. | Mac | Windows / Linux | Action | | ------------------------------- | ---------------------------------- | --------------------------------------------------- | | R | R | Open the composer for a public reply, or close it | | P | P | Open the composer as a private note, or close it | | D | D | Mark the ticket as done, or undo it | | A | A | Open the assignee picker in the dock | | S | S | Open the status picker in the dock | | Esc | Esc | Close the composer and return to the dock's actions | | + A | Ctrl + A | Archive ticket | | M | M | Move ticket to a different channel | | + T | Alt + T | Assign tags | | | | Open the previous ticket in the current view | | | | Open the next ticket in the current view | | + Enter | Ctrl + Enter | Send message or submit form | The previous and next ticket shortcuts follow the order of the view you opened the ticket from. Open a ticket from a channel or saved view to enable them. The on-screen arrows next to the ticket title do the same thing. A and S only work while the dock is showing its actions, not while the composer is open. The single-key shortcuts are disabled whenever you are typing in the composer, the title, or the description. ## Workflow builder shortcuts These shortcuts are available when a step is selected in the [workflow builder](/documentation/automate/workflows/workflow-builder). | Mac | Windows / Linux | Action | | ---------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------- | | + D | Ctrl + D | Duplicate the selected step | | + Shift + D | Ctrl + Shift + D | Duplicate the selected step and all downstream steps | Right-click any step to open a context menu with duplicate and delete actions. ## All shortcuts | Mac | Windows / Linux | Action | Scope | | ---------------------------------------------- | ------------------------------------------------- | ----------------------------------------- | ----------------------------- | | + K | Ctrl + K | Open command launcher | Global | | C | C | Create ticket | Global (not in inputs) | | ] | ] | Toggle Copilot panel | Global (not in inputs) | | \[ | \[ | Toggle left sidebar | Global (not in inputs) | | + 1 | Alt + 1 | Create ticket | Global | | + 2 | Alt + 2 | Create channel | Global | | + 3 | Alt + 3 | Invite members | Global | | + 4 | Alt + 4 | Open settings | Global | | R | R | Reply (open or close the composer) | Ticket view | | P | P | Private note (open or close the composer) | Ticket view | | D | D | Mark as done / undo | Ticket view | | A | A | Assign | Ticket view (composer closed) | | S | S | Set status | Ticket view (composer closed) | | Esc | Esc | Close the composer | Ticket view (composer open) | | + A | Ctrl + A | Archive ticket | Ticket view | | M | M | Move ticket | Ticket view | | + T | Alt + T | Assign tags | Ticket view | | | | Previous ticket in the current view | Ticket view | | | | Next ticket in the current view | Ticket view | | + Enter | Ctrl + Enter | Send message / submit form | Text inputs | | + D | Ctrl + D | Duplicate step | Workflow builder | | + Shift + D | Ctrl + Shift + D | Duplicate step and downstream steps | Workflow builder | # AI briefs Source: https://docs.ravenna.ai/documentation/measure/ai-briefs Schedule AI-generated dashboard summaries and deliver them to Slack channels daily, weekly, or monthly to keep stakeholders informed automatically. Automatically generate AI-powered summaries of custom dashboard data and deliver them to Slack channels on a scheduled basis. AI Briefs transform complex analytics into digestible insights, with customizable prompts to tailor content and tone for your team. AI Briefs deliver to Slack channels today. Delivery to Microsoft Teams channels is not yet supported in the current beta. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview). Set up automated daily, weekly, or monthly briefs to keep stakeholders informed with data-driven insights without manual reporting effort. AI Briefs are only available for custom dashboards, not prepackaged system dashboards. You must have at least one custom dashboard with widgets to use this feature. **AI Briefs vs. Copilot-built scheduled reports.** Use AI Briefs when you want an AI-generated narrative summary of custom dashboard widgets on a recurring schedule. If you instead want a recurring Slack message containing raw ticket data (for example, "DM me my top 5 open tickets by priority every day at 9 AM"), ask Copilot to [build a scheduled workflow](/documentation/automate/copilot/build-automations#walkthrough-scheduled-slack-reports-of-ticket-data). Learn more about [creating custom dashboards](/documentation/measure/analytics#custom-dashboards) *** ## Setting up AI Briefs Navigate to any custom dashboard you've created in Analytics. Click the **AI Brief** button in the dashboard header to open the configuration modal. Set up your delivery preferences including Slack channels, cadence, and custom instructions. *** ## Configuration Configure where, when, and how your AI briefs are generated and delivered. Control where your AI briefs are sent and how often they're generated. **Slack delivery channels** (required) * Select one or more Slack channels where the AI brief will be delivered * Send the same brief to multiple channels simultaneously * The Ravenna bot must be a member of the selected channels to post briefs **Delivery cadence** (required) * **Daily**: Brief sent every day at the specified time * **Weekly**: Brief sent once per week on the selected day * **Monthly**: Brief sent once per month on the selected date Set the specific timing for when briefs are generated and delivered. **Time (UTC)** (required) * Set the specific time when the brief will be sent * Use 24-hour format in UTC timezone (for example, `09:00` for 9:00 AM UTC) * Calculate the appropriate time for your team's timezone **Day of week** * Available for weekly cadence only * Choose which day of the week the brief will be sent (Sunday through Saturday) **Day of month** * Available for monthly cadence only * Choose which day of the month the brief will be sent (1st through 31st) Tailor the AI brief's tone, focus, and format for your specific audience. **Prompt** (optional) * Provide custom instructions to guide the AI's tone, focus, or format * Tailor the brief for specific audiences or emphasize particular aspects of the data * Example prompts: * "Summarize each widget, highlight standout numbers, and keep the tone clear and professional" * "Focus on week-over-week changes and provide actionable insights for leadership" * "Use a casual tone suitable for the engineering team and emphasize technical metrics" * "Highlight any concerning trends and provide context for decision-making" *** ## How AI Briefs work AI Briefs analyze your custom dashboard data and generate structured summaries delivered to Slack. ### Content generation process The system analyzes all widgets in your dashboard and generates insights for each one. AI combines individual widget insights into a cohesive executive summary. If you provide a custom prompt, the AI rewrites the brief according to your specific instructions. The formatted brief is sent to all specified Slack channels. ### Brief structure Each AI brief contains two main sections: **Executive summary** * 3-5 sentence overview highlighting key metrics and trends from across all dashboard widgets **Widget insights** * Bullet points for each dashboard widget containing: * Widget name (automatically included) * Key metrics and data points * Notable trends or changes * Top performing metric (when applicable) ### Data coverage AI Briefs analyze all widgets within your custom dashboard based on the dashboard's configured date range, including key metrics, trends, performance indicators, and comparative analysis where relevant. *** ## Managing AI Briefs Update or remove AI brief schedules directly from the dashboard configuration modal. ### Edit schedules Navigate to the dashboard with an active AI brief. Click the **AI Brief** button in the dashboard header. Make your changes to timing, channels, or prompt. Click **Update** to save changes. ### Delete schedules Open the AI brief configuration modal from the dashboard header. Click the trash icon in the form. Confirm deletion to remove the schedule. Deleting an AI brief schedule cannot be undone. The automated delivery will stop immediately and you'll need to recreate the schedule if you want to resume briefs. *** ## Best practices Optimize your AI briefs for maximum impact and team engagement. Create effective custom prompts that guide AI to generate actionable insights. * **Be specific**: Instead of "make it casual," try "use a friendly tone appropriate for the customer success team" * **Focus on outcomes**: Guide the AI toward actionable insights rather than just data recitation * **Consider your audience**: Tailor language and emphasis for executives, operators, or technical teams * **Test and iterate**: Refine your prompts based on the quality of generated briefs Choose timing and frequency that maximizes visibility and impact. * **Time zones**: All times are in UTC, so calculate the appropriate time for your team's timezone * **Slack activity**: Schedule briefs for times when your team is likely to see and act on them * **Data freshness**: Ensure your dashboard's date range captures the most relevant recent data * **Frequency balance**: Choose a cadence that provides value without overwhelming recipients Structure your custom dashboard to generate meaningful briefs. * **Meaningful widgets**: Include widgets that tell a complete story about your metrics * **Clear naming**: Use descriptive widget names that will make sense in the brief context * **Appropriate date ranges**: Configure dashboard date ranges that provide relevant insights for your cadence # Analytics Source: https://docs.ravenna.ai/documentation/measure/analytics Track service desk performance with prepackaged and custom dashboards covering tickets, agents, SLAs, CSAT, AI Outcome, and team productivity. Track service desk performance through prepackaged dashboards and custom analytics. Monitor ticket lifecycles, agent performance, customer satisfaction, SLA compliance, and operational efficiency to understand and improve support operations. Use seven prepackaged dashboards for immediate insights or create custom dashboards for specific reporting needs. Analytics captures data across all aspects of your service desk to support data-driven decisions. ## Accessing analytics Navigate to analytics dashboards from the left sidebar to explore service desk data. From your workspace, click **Analytics** in the left sidebar. Select from seven prepackaged dashboards: **Tickets**, **Agents**, **Efficiency**, **Forms**, **SLAs**, **CSAT**, and **Knowledge Base Analytics**, or create custom dashboards. Use date ranges, channel filters, and other parameters to focus on relevant data. *** ## Drilling into chart values Click any data point on a chart powered by the **Tickets** data source to open a drill-down modal listing the individual tickets behind that value. Use it to investigate spikes, audit a segment, or jump to a specific ticket without leaving the dashboard. The drill-down is available on metric, grouped, and trend visualizations. The modal title reflects the segment you clicked (for example, the status name on a grouped chart or the series label on a time-series chart) and shows the total ticket count. **To drill in:** Hover a clickable segment, bar, slice, or data point. The cursor switches to a pointer when drill-down is available. Click to open the modal. Type in the search box to filter the result set, or click a column header to sort. The modal keeps the chart's filters (group, date range, and any dashboard filters) in place. Click any row to open that ticket in a new tab so you keep your place on the dashboard. Click the external-link icon in the header to open the same result set in the main tickets list, where you can apply additional filters, bulk-edit, or export. Drill-down is available on widgets that use the **Tickets** data source. Charts built on **Messages** or **Workflow Runs** are not clickable. *** ## Organizing dashboards Keep analytics organized using collections. Group related dashboards by team, business function, or reporting purpose as your analytics needs grow. ### Creating collections Open **Analytics** from your workspace sidebar Click **New** and select **Folder** to create a collection Provide a clear name and description that explains what dashboards belong in this collection Optionally set a parent collection to create hierarchical organization ### Moving dashboards and collections Reorganize dashboards and collections as your reporting structure evolves. Use drag-and-drop or bulk operations to maintain organized analytics. Drag dashboards or collections to move them between locations. **Single item:** 1. Click and hold on a dashboard or collection 2. Drag to the target collection or breadcrumb 3. Release to move **Multiple items:** 1. Select multiple dashboards or collections using checkboxes 2. Drag any selected item 3. All selected items move together **Create new collection during move:** Drag items to the "Move to new folder" button to create and move in one action. Move multiple dashboards at once using bulk actions. 1. Select dashboards or collections using checkboxes 2. Click the **Move** action in the toolbar 3. Select the target collection 4. Confirm the move Bulk move is ideal for reorganizing analytics or restructuring your collection hierarchy. Some moves are prevented to maintain system integrity: * Collections cannot be moved into their own subcollections (prevents circular references) * Moving a collection also moves all dashboards and subcollections within it Prepackaged dashboards cannot be moved or deleted. These system dashboards remain in their default location. *** ## Prepackaged dashboards Seven ready-to-use dashboards provide immediate insights into service desk operations. Monitor ticket volume, status distribution, and lifecycle patterns. * Overall ticket counts and trend indicators * Active tickets requiring attention * Tickets awaiting assignment * Tickets being worked on by agents * Successfully completed tickets * Time-series visualizations of creation patterns and status transitions * **Automation status**: AI-powered classification of resolved tickets as **automated** (handled without human intervention), **automatable** (could be automated with additional configuration), or **non-automatable** (requires human judgment). Use this metric to measure Ravenna's impact and identify opportunities to automate more of your support volume. You can also add **Automation status** as a card condition to scope a widget to one bucket, such as counting only **automated** tickets in a Metric card. * **AI Outcome**: AI-powered classification of tickets where an AI agent participated. There are four values: **Resolved** (the agent handled the ticket end-to-end), **Assisted** (a human used or built on the agent's work to resolve the ticket), **Escalated** (the agent's output was unusable and a human resolved the ticket independently), and **Not Applicable** (nobody asked for help, such as spam, bounced email, or a monitoring alert). Tickets the classifier has not reached yet show as **Not Computed**. Acknowledgments, assignments without action, and approving an automated step do not count as substantive human involvement. **Escalated** requires evidence that the agent's output could not be used: all tool calls failed, a drafted reply was discarded, the agent only sent a bare greeting, or the human's resolution contradicted the agent's answer. When the record does not show whether a human used the agent's output, the ticket is classified as **Assisted** rather than **Escalated**. A ticket where the agent followed an admin-configured rule always reports at least **Assisted**, even when the classifier would otherwise say **Escalated** or **Not Applicable**. The classifier covers every ticket that reaches a **Done** or **Closed** status. It also covers unpublished (AI-only) conversations regardless of status, running them through the same classifier: a substantive request the agent handled is classified as **Resolved**, while a conversation with no actionable request, such as a greeting with a reply, lands in **Not Applicable**. Publishing a conversation clears its outcome, and Ravenna reclassifies it under the normal rules once it closes. Classifier updates also reclassify previously closed tickets, so historical AI Outcome values can shift. Use this metric to track how much of your volume AI handles, and add **AI Outcome** as a card condition to focus a widget on a single value. Clicking a segment of an AI Outcome chart opens the tickets behind it. The tickets list cannot display unpublished conversations, so segments that include them open fewer tickets than the chart counts, and AI Outcome filters on ticket views miss them. * **Resolution path**: Deterministic classification of resolved tickets by who handled them: **human touched** (an agent made a qualifying manual action such as a status change, message, assignment, priority change, form submission, or approval), **AI resolved** (no human touch, but an AI agent participated), **workflow only** (no human touch and no AI agent, but a workflow acted), or **unclassified** (no signal in the event log). Precedence is human touched > AI resolved > workflow only, so any qualifying human action wins even if it happens after an automated resolution. Requester replies on their own ticket are not counted as human touch. Use this metric to see how much of your resolved volume runs end-to-end without human involvement, and group **Resolution path** on any Tickets widget to break down the mix. Learn more about [ticket statuses](/documentation/tickets/organize/statuses) and [channels](/documentation/tickets/channels) Measure AI agent impact using the [AI Outcome](#prepackaged-dashboards) classification defined in the **Tickets** dashboard. Every widget on this dashboard is scoped to *classified* tickets: tickets whose AI Outcome is **Resolved**, **Assisted**, or **Escalated**. Tickets with an outcome of **Not Applicable** or **Not Computed** are excluded from every rate, count, and trend on this dashboard. * **Resolved**: Percentage of classified tickets the AI agent handled end-to-end * **Assisted**: Percentage of classified tickets where a human used or built on the AI agent's work to resolve the ticket * **Escalated**: Percentage of classified tickets where the AI agent's output was unusable and a human resolved the ticket independently * **AI Outcome Trend**: Stacked-bar chart of classified ticket volume by AI Outcome over time * **Agent Tickets**: Count of classified tickets where an AI agent participated * **Total Tickets**: Count of classified tickets (the denominator for the three rates above) Learn more about [AI agents](/documentation/automate/agents/overview) and [ticket roles](/documentation/tickets/roles) Track operational efficiency and process optimization metrics. * Average response time across all tickets * Ticket assignment speed * Overall resolution performance metrics * Efficiency trend analysis over time When building custom cards on this dashboard, choose which clock to report: * **SLA Time to First Response**, **SLA Time to Resolution**, and **SLA Time to Close** honor business schedules, pause statuses, and superseded targets, and only cover tickets an SLA policy applies to. * **Time to First Response**, **Time to Resolution**, and **Time to Close** measure wall-clock time from ticket timestamps and cover every ticket with the timestamp set, including tickets without an SLA. Response time and resolution metrics help identify bottlenecks and process improvement opportunities. Existing saved widgets continue to report the SLA-clock values under their new **SLA** labels. No numbers move. Understand request patterns and analyze how different forms perform across your service desk. Learn more about [creating and managing forms](/documentation/tickets/forms/overview) Monitor service level agreement performance across all priority levels. * First response times by priority (Total, Urgent, High, Medium, Low) * Resolution performance breakdown by priority level * Historical trend visualization * Closure time analysis across priority categories * Compliance breakdown by SLA, status (Met or Breached), or target type (SLA Time to First Response, SLA Time to Resolution, SLA Time to Close) when building custom cards * Combined target-and-outcome filtering with the **SLA Target Outcome** condition, which binds one target to one outcome (for example, **Time to Resolution breached**) in widget conditions and dashboard filters. Add two of these conditions to isolate tickets that met one target but breached another, which separate target and outcome filters cannot express. Supports the **is**, **is not**, **is one of**, and **is not one of** operators. When building custom cards, pick the aggregation field that matches what you want to measure: * **SLA Time to First Response**, **SLA Time to Resolution**, and **SLA Time to Close** read from the SLA target record. They honor business schedules, pause statuses, and superseded targets, and only include tickets an SLA policy covers. * **Time to First Response**, **Time to Resolution**, and **Time to Close** measure straight from ticket timestamps (`respondedAt`, `resolvedAt`, `closedAt`). They run on wall-clock time and include every ticket with the timestamp set, whether or not an SLA policy applies. Existing saved widgets keep pointing at the SLA-clock fields (now labeled with the **SLA** prefix), so their values do not change. Learn more about [configuring SLAs](/documentation/automate/slas) and [setting priorities](/documentation/tickets/organize/priorities) Track customer satisfaction patterns and feedback trends. * Overall customer satisfaction scores across all tickets * Satisfaction scores by priority levels * Time-series analysis showing satisfaction trends CSAT data is only available for channels where customer satisfaction surveys have been enabled and tickets have been resolved with customer feedback. Learn more about [customer satisfaction surveys](/documentation/measure/csat) Measure knowledge base effectiveness and article performance to understand how documentation impacts resolution rate and user self-service. * Total users interacting with knowledge base articles * AI Outcome metrics showing requests resolved through self-service * Ticket escalation rates when knowledge base cannot resolve requests * Top 10 most viewed articles across all categories * Top 10 articles with highest resolution rates * Top 10 articles with highest escalation rates * Knowledge base usage trends over time Knowledge Base Analytics helps identify which articles effectively resolve user questions and which topics require improved documentation or additional support resources. Learn more about [configuring knowledge sources](/documentation/automate/knowledge/overview) ## Custom dashboards Create tailored dashboards using the flexible dashboard builder for specific reporting needs beyond the prepackaged dashboards. ### Building custom dashboards Click **Add Card** from the top left of any analytics page to start building a custom dashboard or widget. Select from three card types: * **Metric**: Display single values and grouped categorical data * **Trend**: Create time-series visualizations showing data changes over time * **Table**: List individual tickets that match a set of conditions Provide a **Name** and **Description** for your widget to make it easily identifiable to your team. Select your data source: * **Tickets**: Primary service desk data including status, priority, assignments * **Messages**: Ticket message data for analyzing communication patterns * **Workflow Runs**: Workflow execution data for tracking automation performance Set up your widget with grouping, aggregation, and time interval options based on your selected card type and data source. ### Card types Use Metric cards to display key performance indicators with single values or grouped categorical data. **Best for:** * Current totals and counts * Categorical breakdowns * Snapshot views of current state * Comparing values across groups Use Trend cards to create time-series visualizations showing how your data changes over time. **Best for:** * Historical pattern analysis * Identifying trends and seasonality * Tracking progress toward goals * Comparing performance across time periods Use Table cards to surface a list of individual tickets that match a set of conditions, ranked by the field you choose. Unlike Metric and Trend cards, which aggregate values, Table cards show ticket-level detail directly on the dashboard. **Best for:** * Watchlists of tickets that need attention (for example, oldest open, highest priority unassigned) * Surfacing top or bottom rows by a field such as created date, updated date, or due date * Sharing a queue or backlog snapshot on an executive or team dashboard **Configuration:** * **Data**: Select the data source. Table cards currently support the **Tickets** data source. * **Max Tickets**: Set the maximum number of rows to display. Defaults to 10. * **Sort By**: Select the field used to order results (for example, **Created**, **Updated**, or **Due Date**). * **Sort Order**: Select **Descending** to show the highest or most recent values first, or **Ascending** to show the lowest or oldest first. * **Conditions**: Add filter groups to narrow results to the tickets you care about, using the same condition builder as ticket views. By default, each row shows the ticket's priority, key, status, title, and requester, and clicking a row opens the ticket. Ask Copilot or an MCP client to change the columns, including custom fields and ticket attributes, when you need a different set. See [Add widget to dashboard](/documentation/automate/mcp/tools#analytics) for the column syntax. Table cards are sized wider than Metric and Trend cards by default so ticket rows have room to render. Resize the widget on the dashboard grid if you need to fit more or fewer rows on screen. ### Data sources and grouping Group your analysis by key dimensions depending on the data source you select. Primary service desk data including status, priority, and assignments. **Status and assignments** * Ticket status * Assignee * Requester * Author **Categories** * Priority levels (Urgent, High, Medium, Low) * Channels * Forms * Tags **Customer feedback** * CSAT score (1-5 stars, plus a "No CSAT" bucket for tickets that have not been rated) **Service level agreements** * **SLA**: Group tickets by the SLA attached to them to compare performance across policies * **Status**: Group tickets by SLA outcome, either **Met** or **Breached**, to monitor overall compliance * **Target**: Group tickets by SLA target type (**SLA Time to First Response**, **SLA Time to Resolution**, or **SLA Time to Close**) to compare how each commitment is performing **Dates** * Created * Updated * Start date * Due date * Approved * Declined * Archived dates **AI involvement** * Whether human agents or AI agents participated in ticket resolution Ticket message data for analyzing communication patterns. **Authors and sources** * Message author * Source tracking * Associated ticket **AI analysis** * Human vs AI-generated messages * Message feedback comparison **Message types** * Public messages * Private messages * Response categorization * Time-based analysis Workflow execution data for tracking automation performance and reliability. **Workflow details** * Workflow name * Run status (completed, failed, running) * Collection * Workspace **Related ticket data** * Channel * Ticket status * Assignee * Priority * Source * Category Workflow Runs only supports count aggregation. Average, sum, min, and max aggregation types are not available for this data source. ### Configuration options Configure how your custom dashboard aggregates and displays data. Select how to calculate values for your analytics cards. **Count** * Total number of records in your dataset * Best for: Ticket volume, message counts, activity tracking **Average** * Mean value calculation for numeric data * Best for: Response times, resolution times, satisfaction scores **Sum** * Total of all numeric values * Best for: Total time spent, cumulative values **Min and Max** * Minimum or maximum values in your dataset * Best for: Fastest/slowest response times, date ranges **Percent of** * Shows a percentage: with a **Group by**, each group's share of the total, so the values sum to 100%; without a **Group by**, a single value between 0 and 100 for the share of the filtered population that matches the widget's conditions * Available on the **Tickets** data source Pick the grouping that matches the rate you want to see: * **SLA compliance rate**: Group by **SLA > Outcome** to see the share of tickets that were **Met** versus **Breached** (tickets with no SLA appear as their own slice) * **AI outcome rate**: Group by **AI Outcome** to see the share of tickets that were **Resolved** by AI, **Assisted**, **Escalated** to a human, or **Not Applicable** (tickets with no outcome yet appear as **Not Computed**) * **Resolution mix**: Group by **Resolution Path** to see the share of tickets resolved with **Human Touched**, **AI Resolved**, or **Workflow Only** involvement * **General breakdowns**: Group by status, priority, channel, assignee, or any other dimension to show its distribution as percentages * **Single-value share**: Leave **Group by** empty and add conditions to see one percentage, the share of the filtered population that matches those conditions. For example, on an AI Outcome widget scoped to **Resolved**, add a condition for **Priority = High** to see "share of tickets in range that are high priority AND Resolved by AI." The denominator stays all tickets in the filtered population, so the value always reads 0–100. Widget conditions on a **Percent of** aggregation scope the numerator only. The denominator stays the full filtered population set by the dashboard filters and date range, so adding a condition tightens what counts toward the percentage without shrinking what it is measured against. Grouped percentages are capped so they cannot exceed 100. **Hide Empty Values and the denominator** Turn on **Hide Empty Values** to change the denominator of a **Percent of** widget from the full filtered population to only the tickets the metric actually classifies. When grouping by a metric like **AI Outcome** or **Resolution Path**, the setting drops tickets with no computed value and tickets classified as **Not Applicable** (for example, spam or monitoring alerts on **AI Outcome**). The remaining classified tickets become the denominator, so the percentages describe the share of the classified population rather than the share of every ticket in range. Best for: SLA compliance rates, AI outcome reporting, and showing the share of tickets that meet a set of conditions as a single percentage or as a grouped breakdown. Without a widget condition, every ticket in the filtered population is counted in a grouped **Percent of**, including tickets with no SLA or no computed outcome. They show up as their own slice (for example **No SLA** or **Not Computed**) rather than being excluded from the math. Add a widget condition to scope only the numerator. The denominator still counts the same full population. To exclude unclassified and **Not Applicable** tickets from the denominator entirely, enable **Hide Empty Values** on the widget. Time intervals determine how your data is grouped and displayed over time in Trend cards. **Hourly** * Granular intra-day analysis for high-volume monitoring * Best for: Real-time operations, incident response tracking, workflow run monitoring **Daily** * Detailed short-term analysis with individual data points * Best for: Recent activity monitoring, identifying daily patterns **Weekly** * Medium-term trend analysis grouped by weeks * Best for: Sprint cycles, weekly performance reviews **Monthly** * Long-term pattern analysis ideal for identifying seasonal trends * Best for: Monthly reporting, quarterly planning **Quarterly and annual** * Business reporting cycles and year-over-year performance tracking * Best for: Executive reporting, long-term trend analysis Select time intervals based on your analysis needs. Shorter intervals provide more detail but may include more noise, while longer intervals reveal broader trends. Switch any Metric or Trend card from a chart to a data table using the **Table** option in the widget's view mode toggle. Use the table view to read exact values, scan a long list of groups, or compare numbers side by side when a chart becomes hard to interpret. **Best for:** * Inspecting precise values behind a chart * Widgets with many groups that crowd a bar or pie chart * Sharing exact numbers in screenshots or reviews **How it appears:** * Metric cards display each group on its own row with a value column. * Trend cards display one row per time bucket with a column per series. * Group labels render with the same badges, avatars, and icons used in the rest of Ravenna so values stay easy to recognize. **To switch views:** 1. Open the dashboard containing the widget. 2. In the view mode toggle on the widget header, select the **Table** icon. 3. Switch back to a chart at any time by selecting another view (Bar, Stacked Bar, Line, or Pie). Table view is available on both Metric and Trend cards. The selection is per widget, so different cards on the same dashboard can use different views. Pin a custom date range on any widget so it stays fixed while you change the dashboard date picker. Use this to keep a "last 90 days" trend card next to a "this week" snapshot without switching back and forth. Open a widget's settings and select a date range under **Date Range Override**. The widget's chart, table view, insights, drill-downs, and exports all use the overridden range. Widgets without an override continue tracking the dashboard picker as before. Enable **Compare Previous Period** on a Trend card to overlay data from the immediately preceding period on the same chart. Use the overlay to see whether a metric is improving or regressing against the equivalent prior window. The comparison window is derived from the widget's effective date range (its override if set, otherwise the dashboard's selected range). For example, if the effective range covers the last 7 days, the overlay shows the 7 days before that. **Best for:** * Week-over-week or month-over-month performance reviews * Spotting regressions after a process or staffing change * Validating the impact of new workflows, agents, or SLAs **How it appears:** * On line charts, the previous period appears as a dashed, semi-transparent line behind the current series. * On bar charts, the previous period appears as faded bars next to the current bars. * The legend continues to reflect only current-period series. **To enable it:** 1. Open or create a Trend card. 2. In the configuration panel, toggle **Compare Previous Period** on. 3. Save the card. The overlay updates automatically as you change the dashboard's date range. Comparison overlays are only available on Trend cards. They follow the widget's effective date range, so changing the dashboard picker shifts the comparison window only for widgets that do not have their own date range override. ### Exporting widget data Download the underlying data for any Metric or Trend card as a CSV file. Use exports to share data with stakeholders who do not use Ravenna, run additional analysis in a spreadsheet, or attach point-in-time snapshots to reports. On any dashboard, select the actions menu in the top-right corner of the widget. Select **Export** from the menu. Ravenna fetches the widget's data using its effective date range (the widget's override if set, otherwise the dashboard's current range) and filters. The browser downloads a CSV named after the widget (for example, `ticket_volume_export.csv`). Open it in any spreadsheet tool. The exported file reflects the data currently driving the widget: * **Metric cards without a group** include a single value row. * **Metric cards with a group** include one row per group with the group label and aggregated value. * **Trend cards** include one row per time bucket with a column for each series. Exports honor the widget's effective date range and the dashboard's filters, so refining either before exporting controls the rows that appear in the CSV. # CSAT survey Source: https://docs.ravenna.ai/documentation/measure/csat Collect customer satisfaction feedback from ticket requesters automatically with 5-star Slack surveys triggered on resolution and tracked in analytics. Automatically collect customer satisfaction feedback from ticket requesters when tickets are resolved. CSAT surveys use a 5-star rating system delivered via Slack. Customers rate their experience and provide optional feedback, helping you measure service quality and identify improvement opportunities. CSAT surveys deliver as Slack messages today. CSAT delivery via Microsoft Teams is not yet supported in the current beta; tickets opened from Teams will not receive an in-Teams CSAT prompt. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview). Configure CSAT surveys at the channel level to control which support channels collect satisfaction feedback. All responses are tracked in Analytics for performance monitoring and trend analysis. Learn more about [CSAT analytics](/documentation/measure/analytics#prepackaged-dashboards) and [channels](/documentation/tickets/channels) *** ## Enabling CSAT surveys Configure CSAT surveys for your support channels to start collecting customer feedback. From your workspace, go to the channel where you want to enable CSAT surveys and click **Settings**. In the left settings navigation, click **Slack** to access Slack-related configurations. Find the **Send CSAT on Ticket Resolution** card and toggle the setting to **enabled**. Your CSAT settings are automatically saved. CSAT surveys will now be sent to requesters when tickets in this channel are resolved. CSAT can be enabled or disabled independently for each channel, allowing you to customize which support channels collect satisfaction feedback. *** ## How CSAT surveys work CSAT surveys automatically trigger when tickets are marked as resolved, sending interactive rating messages to requesters via Slack. ### Survey delivery When an agent changes a ticket status to **Done**, Ravenna automatically triggers the CSAT survey process. Ravenna immediately sends a CSAT survey message to the ticket requester via Slack. The requester receives an interactive Slack message with 5-star rating buttons and can optionally provide additional feedback. Once submitted, the requester receives confirmation and the feedback is recorded in the ticket timeline and Analytics. ### Survey experience When their ticket is resolved, requesters receive a Slack message notification asking them to rate their satisfaction. * Click 1-5 stars to rate satisfaction with the service * Optionally provide additional feedback through a modal that opens after rating * Receive confirmation that feedback was successfully recorded Agents receive notifications when CSAT responses are submitted and can view feedback directly in the ticket. * Receive notifications when customers submit CSAT responses * View feedback directly in the ticket timeline * See CSAT data in ticket events for complete context *** ## Find tickets by CSAT score Each ticket stores its final CSAT rating directly on the ticket, so you can sort, filter, and report on satisfaction without leaving the ticket list. Use the **CSAT score** filter in any view to narrow tickets by their rating: * Pick one or more star ratings (1-5) to focus on specific scores. * Filter for tickets without a score to find resolved tickets that have not yet received feedback. * Combine with other filters (such as **Channel** or **Assignee**) to investigate satisfaction patterns for a specific team or topic. In table views, enable the **CSAT score** column from the column visibility menu to see each ticket's rating at a glance. The column displays the rating as stars, with an empty value for tickets that have not yet been rated. Sort the column ascending or descending to surface your highest or lowest-rated resolutions. A ticket's CSAT score updates as soon as the requester submits their rating. If a requester resubmits feedback, the ticket reflects the latest score. *** ## CSAT data and analytics All CSAT responses are available in Analytics to help you measure and improve service quality. ### Available metrics * Overall customer satisfaction scores across all tickets * Satisfaction scores by priority levels * Response rates and trends over time * Filter data by date ranges, channels, and ticket priorities * Identify patterns and opportunities for service improvement * Group custom dashboards by **CSAT score** to see ticket distribution across each rating (1-5 stars) plus a "No CSAT" bucket for unrated tickets CSAT data is only available for channels where customer satisfaction surveys have been enabled and tickets have been resolved with customer feedback. Learn more about [CSAT analytics dashboard](/documentation/measure/analytics#prepackaged-dashboards) # Admin Source: https://docs.ravenna.ai/documentation/platform/admin Use Ravenna Admin to view and respond to tickets, configure channels and forms, and manage workspaces from a complete browser interface. Admin is the full Ravenna application for organization admins and workspace members who manage and respond to tickets. Access your workspace, view tickets, respond to requests, and configure settings through the browser at `app.ravenna.ai`. Looking for the self-service experience end users see? See the [Portal](/documentation/platform/portal). ## Overview View, respond to, and manage all tickets in your workspace from one interface. Configure workspaces, channels, forms, and integrations through the settings panel. Use keyboard shortcuts and command launcher for fast ticket creation and navigation. Switch between workspaces and manage tickets across your entire organization. ## Access Admin Access Admin at your organization's unique URL. Navigate to your organization's Ravenna URL: ```text wrap theme={"system"} https://app.ravenna.ai ``` Sign in with your organization credentials or SSO provider. Access Admin directly from Slack using the Ravenna app home or ticket links. Ticket links in Slack open the corresponding ticket in the Admin for detailed management. Access tickets from the embedded **My Tickets** tab in the Ravenna Microsoft Teams app, or follow ticket deep links from Adaptive Cards. See the [My Tickets tab](/integrations/microsoft-teams/my-tickets-tab) docs. ## Key features View and manage all tickets in your workspace: * View tickets by channel, assignment, or custom filters * Respond to tickets with comments and internal notes * Update ticket status, priority, and assignments * Track ticket history and activity * Create new tickets using the New button or command launcher Configure workspace and organization settings: * Access workspace settings for SLAs, statuses, tags, custom fields, and integrations * Manage organization settings (admins only) for branding, notification policies, and SSO * Set up forms and custom fields * Configure integrations with Slack, Jira, Linear, and more * Manage workspace and organization members Track workspace performance and ticket metrics: * View ticket volume and trends * Monitor response and resolution times * Analyze team performance * Generate custom reports Explore detailed metrics in [Analytics](/documentation/measure/analytics). Use keyboard shortcuts for fast navigation and actions: Press + K (Mac) or Ctrl + K (Windows/Linux) to open the command launcher. Learn more about keyboard shortcuts in [Shortcuts](/documentation/get-started/shortcuts). ## Access control Access to the Admin is scoped to organization admins and workspace members who manage and respond to tickets. Full access to all organization settings, workspaces, and tickets. Can: * Manage organization-wide settings and billing * Create and configure workspaces * Manage all members and permissions * Access all tickets across the organization Access to assigned workspaces for managing and responding to tickets. Can: * View and respond to tickets in their workspace * Create tickets on behalf of users * Configure workspace settings (if granted permission) * Manage channels and integrations within their workspace End users and organization guests do not work tickets in the Admin. Instead, they use the [Portal](/documentation/platform/portal) for self-service, or interact with Ravenna through: * Slack channels and DMs * Email * Microsoft Teams Learn more about the [Portal](/documentation/platform/portal) and how to enable it. # Groups Source: https://docs.ravenna.ai/documentation/platform/groups Create user groups manually in Ravenna or sync them from identity providers like Okta and Google Workspace to manage access and assignments. User groups organize workspace members into collections for easier collaboration and management. Create groups manually or sync them automatically from identity providers like Google Workspace to coordinate work and manage access within your workspaces. *** ## Understanding user groups User groups provide flexible ways to organize your organization members for collaboration, access control, and workflow management. Create and manage groups directly in Ravenna. Add any organization member to a group regardless of their workspace membership. Use manual groups for project teams, departments, or any custom organizational structure. Automatically sync groups from identity providers like Google Workspace. Synced groups maintain their membership from the external system, keeping your Ravenna groups up to date with your organization's identity provider. Synced groups appear alongside manual groups in the Groups UI. *** ## Create user groups Go to **Members** in your workspace sidebar navigation, then click the **Groups** tab. Click **+ Group** to open the group creation dialog. Provide a **Name** for your user group (required) and add an optional **Description** to clarify the group's purpose. Click **Save** to create the user group. User group names must be unique within your organization. You can edit the name and description later. *** ## Edit a group Edit a group's name, description, and membership directly on the group details page. Changes save automatically when you confirm each field, so you do not need to open a separate edit dialog. Go to **Members** → **Groups** in your workspace, then click the group you want to edit to open its details page. Click the **Name** or **Description** field to edit it inline. Press **Enter** or click outside the field to save, or press **Escape** to discard your changes. Add or remove members from the **Members** section. You can add users from across your organization, not just workspace members. Membership changes save automatically. Synced groups are read-only in Ravenna. To change a synced group's name or membership, update it in the source identity provider. *** ## Synced groups Sync groups automatically from identity providers to maintain consistent group membership across your organization and Ravenna. ### How group syncing works When you connect an identity provider integration like Google Workspace, Ravenna automatically syncs groups from the external system. Groups are created in Ravenna with matching names and membership is kept in sync. Group membership is synchronized from the identity provider. When users are added or removed from groups in your identity provider, those changes automatically reflect in Ravenna. Synced groups appear alongside manually created groups in the Groups UI. You can use synced groups for access control, workflow assignments, and collaboration just like manual groups. Synced groups show their source integration, making it clear which groups are managed externally versus manually in Ravenna. ### Supported identity providers Sync Google Workspace groups automatically when you connect the Google Workspace integration. All groups from your Google Workspace organization are synced and kept up to date. Learn how to set up [Google Workspace integration](/integrations/google-workspace/overview) }> Sync Okta groups automatically when you connect the Okta integration. All groups from your Okta organization are synced and kept up to date. Learn how to set up [Okta integration](/integrations/okta/overview) Sync Slack user groups automatically when you connect the Slack integration. User groups are synced during the initial OAuth authentication and kept up to date. Learn how to set up [Slack integration](/integrations/slack/setup) Group sync from Microsoft Teams is **not yet supported** in the current beta. To sync Entra ID security and Microsoft 365 groups, use the [Microsoft Entra ID integration](/integrations/microsoft-entra/overview) instead. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview) for beta scope. ### Managing synced groups Synced group membership is managed in your identity provider. Changes made there automatically sync to Ravenna. You cannot manually edit membership for synced groups in Ravenna. **What you can do with synced groups:** * Use them in access levels for automated provisioning * Assign them as approvers in workflows and ticket approval rounds * Reference them in custom fields and forms * View their membership in Ravenna **What gets synced:** * Group name * Group membership (users in the group) * Membership changes (additions and removals) *** ## Using groups User groups enable consistent access management and collaboration across your organization. Map groups to access levels in applications for automated provisioning. When users gain access to an application at a specific level, they're automatically added to the corresponding group in your identity provider. Learn about [application access levels](/documentation/automate/access-provisioning/applications#access-levels) Use groups as approvers in workflows and ticket approval rounds. Assign approval tasks to entire groups instead of individual users, enabling flexible approval processes. When user groups are selected as approvers for ticket approval rounds, they are automatically expanded into individual users server-side when saved. Reference groups in custom fields like user group select fields on forms and tickets. You can configure an allowlist on user group select fields to restrict which groups appear as options. Use groups to control who can see and submit specific forms. When a form's audience is set to "User Groups", only members of the selected groups can access that form in the Portal, Slack, and ticket creation flows. Learn more about [form audience settings](/documentation/tickets/forms/overview#audience-settings) ## Mental model User groups are collections of organization members. They serve as reusable references for access control, workflow assignments, and form fields. Groups can be created manually or synced automatically from identity providers (Okta, Google Workspace, Slack). Groups are organization-scoped. A group exists at the organization level. However, which groups appear in form fields depends on the workspace. Manually created groups only appear in workspaces they are assigned to. Groups synced from identity providers (Okta, Google Workspace, Slack) appear in all workspaces. *** ## Manual vs synced groups | Aspect | Manual groups | Synced groups | | --------------------------------- | -------------------------- | ------------------------------------------------- | | **Source** | Created in Ravenna | Imported from IdP (Okta, Google Workspace, Slack) | | **Membership management** | Edited directly in Ravenna | Managed in the IdP, synced to Ravenna | | **Membership editing in Ravenna** | Yes | No (read-only in Ravenna) | | **Sync behavior** | N/A | Automatic membership updates from IdP | | **Source indicator** | None | Shows source integration | Both types can be used identically in access levels, workflows, forms, and custom fields. *** ## Groups in the platform **Access level mapping**: Groups map to access levels on applications. When a user is granted access at a specific level, they can be added to the corresponding IdP group via workflow actions, enabling automated provisioning. **Workflow approvers**: Assign a group as the approver pool for workflow approval steps. Any member of the group can approve. **Ticket approval rounds**: Select user groups when creating approval rounds on tickets. Groups are immediately expanded into individual users server-side when saved, unlike approval templates which persist group IDs. This maintains the existing approval round behavior where only concrete users are stored as approvers. **Form fields**: The "User group select" custom field type lets requesters select a group when creating a ticket. Admins can configure an **allowlist** on the field to restrict which groups appear as options, and optionally filter groups by **source** (e.g., only Okta groups or only Ravenna-native groups). These constraints are enforced in both the form UI and the agent tool when the agent resolves groups conversationally. **Form audience access control**: Groups can define form audiences. When a form's audience type is set to "Specific" (User Groups), only members of the selected groups can see and submit that form. This filtering is server-side and applies to the Portal, Slack form selection, and ticket creation flows. **Agent rules**: Groups can be referenced in agent rules when the agent needs to identify team membership or route requests. The Group Lookup tool respects workspace visibility, allowlist, and source constraints configured on form fields. *** ## Constraints and gotchas * Group names must be unique within the organization. * Synced group membership cannot be edited in Ravenna. Changes must be made in the source identity provider. * Groups are organization-scoped, but their visibility in user group select fields is workspace-aware. Manually created groups only appear in workspaces they are assigned to, while synced groups are visible across all workspaces. * Synced groups appear alongside manual groups in the UI with a source indicator. * Multiple identity providers can sync groups simultaneously. Okta groups, Google Workspace groups, and Slack user groups can all coexist. * Deleting a group that is referenced in access levels, workflows, or forms may break those references. * When duplicating a form across workspaces, any allowlist and source filter configured on user group select fields are stripped because group IDs may differ between workspaces. # My settings Source: https://docs.ravenna.ai/documentation/platform/my-settings Configure your personal Ravenna user settings including profile, notification preferences, theme appearance, and connected app integrations. Configure your personal Ravenna settings. Access user settings through the settings menu to customize your profile, preferences, appearance, and app integrations. Click your profile icon in the top right corner and select **Settings**. Select from Profile, Preferences, Appearance, or Connected Apps in the left sidebar. Update your settings and save. Most changes apply immediately. Organization admins can configure some user settings on behalf of members through the member management interface. *** ## Profile Manage your profile information including name and profile image. ### Profile fields Upload a profile picture to personalize your account. Your profile image appears throughout Ravenna in ticket assignments, comments, and user mentions. **Requirements:** * Maximum file size: 1 MB * Supported formats: PNG, JPG, JPEG, WebP * Maximum dimensions: 512x512 pixels * Image cropper available to adjust framing Click **Upload profile image** and select a file from your device. Use the crop tool to adjust the framing and select the best portion of your image. Click **Save** to update your profile image across Ravenna. Your first and last name display throughout Ravenna in tickets, assignments, and team directories. **Fields:** * **First Name** (required): Your given name * **Last Name** (required): Your family name Name changes reflect immediately across all tickets, assignments, and mentions throughout the platform. *** ## Preferences Configure operational preferences including delegate assignment and default workspace. ### Delegate Assign a delegate to handle tickets when you're away. Delegates receive ticket assignments and approvals on your behalf, ensuring continuity when you're unavailable. Go to **Settings → Preferences**. In the User Delegate section, select your delegate from the dropdown: * **Manager**: Automatically assigns your direct manager (requires Okta integration) * **Specific user**: Select any organization member as your delegate * **No Delegate**: Remove delegate assignment Your delegate assignment saves automatically. When you select "Manager" as your delegate, Ravenna automatically resolves your direct manager from your Okta integration. This option appears only when your organization has configured Okta integration. **Benefits:** * Automatic resolution based on organizational hierarchy * No manual updates needed when reporting structure changes * Maintains proper escalation paths Select a specific organization member as your delegate. You can select any admin or member from your organization to handle tickets during your absence. **When to use:** * No Okta integration configured * Prefer specific colleague over manager * Cross-functional delegation needs When a delegate is assigned: * Ticket assignments directed to you route to your delegate * Approval requests forward to your delegate * Your delegate receives notifications for tickets you would normally handle * Delegation persists until you change or remove it Delegation doesn't transfer existing tickets. It only affects new assignments and approvals while the delegation is active. ### Out of office Control your availability status to automatically redirect ticket assignments and approvals to your delegate when you're unavailable. Go to **Settings → Preferences**. Select how your out of office status is determined: * **Manual**: Manually toggle your OOO status on and off * **Slack Status**: Automatically sync from your Slack status * **Manual mode**: Toggle the Out of Office switch to mark yourself as unavailable * **Slack mode**: Set a Slack status that indicates you're away (for example, "OOO until Friday", "On PTO", "Vacationing 🏖️") to automatically mark yourself as unavailable Manually control your out of office status with a simple toggle. Use this mode when you want direct control over your availability or when you don't use Slack. **How it works:** * Toggle Out of Office on when you're unavailable * Toggle back to Available when you return * Status persists until you manually change it * Requires delegate assignment for ticket redirection Manual mode gives you precise control over when tickets are redirected to your delegate, independent of any external systems. Automatically sync your out of office status from Slack. When enabled, Ravenna monitors your Slack status and updates your availability in real-time. **How status is detected:** Ravenna uses AI to interpret your Slack status text, so you don't need to use a specific phrase. Common examples that mark you as out of office include: * Vacation and time off: "Vacationing", "On vacation", "Holiday", "Beach mode 🏖️" * Sick leave: "Out sick", "Sick day", "Under the weather" * Out of office: "OOO", "OOO until Friday", "Out of office", "Away" * Paid time off: "PTO", "On PTO", "PTO until 6/15" * Extended leave: "On leave", "Parental leave", "Sabbatical", "Bereavement" * Day off: "Off today", "Taking the day off", "Personal day" You stay marked as **available** for focus and work-mode statuses like "WFH", "Heads down", "In a meeting", "On call", "BRB", or "Lunch". You also stay available for statuses that reference someone else's absence (for example, "Covering for Alex who is OOO") or a future or past absence (for example, "OOO next week" or "Back from PTO"). **How sync works:** * Status changes are detected in real-time via Slack events * When your Slack status indicates you're away, you're automatically marked as unavailable * When your Slack status clears or changes to something else, you're marked as available * Supports status expiration - automatically becomes available when Slack status expires * Works across multiple connected Slack workspaces - if you're OOO in any workspace, you're marked as OOO Slack status sync requires you to have a delegate configured. Without a delegate, status changes won't redirect tickets. Microsoft Teams presence sync is not available in the current beta. Use manual OOO mode if you primarily work in Microsoft Teams. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview). When you're marked as out of office (either manually or via Slack sync), new ticket assignments and approval requests automatically redirect to your delegate. **What gets redirected:** * New ticket assignments * Approval requests * Notifications for redirected items **What doesn't change:** * Existing ticket assignments remain with you * Historical ticket records * Your role in past tickets **Delegation chains:** If your delegate is also out of office, Ravenna follows the delegation chain to find an available person. For example, if you delegate to Person B who delegates to Person C, assignments will go to Person C if Person B is also unavailable. Delegation chains prevent tickets from getting stuck when multiple team members are unavailable simultaneously. ### Rapid ticket creation Skip the ticket creation modal and instantly create tickets from Slack message shortcuts. When enabled, the message you shortcut becomes the first message on the ticket, and Ravenna auto-generates a title and description from the conversation. The workspace you pick here is your **primary workspace** (sometimes called your primary teamspace). It only affects Slack rapid ticket creation. It does not change which workspace loads first in the Ravenna UI or override workspace defaults for other users. Go to **Settings → Preferences**. In the Rapid Ticket Creation section, click **Select** and choose the workspace where rapid-created tickets should land. This enables the feature and sets your primary workspace. To turn off rapid creation, open the **⋯** menu on the Workspace row and select **Remove**. You can also edit the selection and clear the workspace picker. Either way, Slack shortcuts will show the full ticket creation form again. Each member picks their own primary workspace. There is no organization-wide default that admins can preset on behalf of members. The selected workspace must have a default queue configured. If no default queue exists, Ravenna falls back to the standard ticket creation modal. Learn more about [creating tickets from Slack](/integrations/slack/creating-tickets) *** ## Notifications Control when and how you receive updates about tickets, assignments, and team activity. Configure delivery preferences for Slack and email independently. Learn more about [notification settings](/documentation/platform/notifications) *** ## Appearance Customize how Ravenna looks with your theme preference. ### Theme Select between light, dark, or system-based theme preferences: Light theme uses bright backgrounds optimized for well-lit environments. Best for daytime use or bright office settings. Dark theme uses dark backgrounds that reduce eye strain in low-light conditions. Ideal for evening work or dim environments. System theme automatically matches your operating system's theme preference. Switches between light and dark based on your OS settings. Theme changes apply immediately without requiring a page refresh. *** ## Connected apps Link external applications to your Ravenna account for enhanced integration capabilities. ### Slack Connect your Slack identity so messages sent from Ravenna appear as you in Slack instead of the Ravenna bot. After interacting with Ravenna in Slack, your Slack profiles become available to connect in user settings. Create or comment on a ticket through the Ravenna Slack integration. This registers your Slack profile. Go to **Settings → Connected Apps**. Click **Connect** next to your Slack workspace to authorize the connection. Once connected, replies you send from Ravenna will appear as your Slack user in Slack threads rather than as the Ravenna bot. If your organization uses multiple Slack workspaces, you can connect each workspace separately. Each connection requires individual authorization. **Multi-workspace support:** * Connect to multiple Slack workspaces * Each workspace requires separate authorization * Disconnect individual workspaces without affecting others Disconnect your Slack identity to revoke Ravenna's ability to post as you in Slack. Go to **Settings → Connected Apps**. Locate the connected workspace you want to disconnect. Click **Disconnect** and confirm your choice. After disconnecting, messages sent from Ravenna will appear as the Ravenna bot instead of your Slack user until you reconnect. Learn more about [Slack integration](/integrations/slack/overview) *** ## Admin management Organization admins can configure some user settings on behalf of members through the member management interface. Go to **Settings → Organization → Members**. Click a member's row to open their profile drawer. Click **Edit** in the Ravenna section to modify delegate assignment and other settings. Changes apply immediately to the user's preferences. Learn more about [managing organization members](/documentation/platform/organizations/overview#managing-organization-members) # Notifications Source: https://docs.ravenna.ai/documentation/platform/notifications Manage Ravenna notifications in a unified inbox with granular controls for Slack and email delivery across approvals, assignments, and comments. Configure notification preferences to control when and how you receive updates about tickets, assignments, approvals, and team activity. Organization admins set default preferences in organization settings while individual users customize their own notification settings. ## Notification center View and manage all your Ravenna notifications in one place. Approvals, assignments, comments, and team activity surface in a single view, helping you stay focused without jumping between channels and individual tickets. ![Notification center](https://d1kzozfjh72w00.cloudfront.net/documentation/screenshots/platform/notifications/centre.png) *** ## Notification events Control which types of updates generate notifications. Each event type can be enabled or disabled for Slack and email delivery independently. Notifications when tickets or tasks are assigned or unassigned to users. * New ticket assignments * Ticket reassignments between users * Removal from ticket assignments * Task assignments and unassignments on tickets you work on * [Assignment reminders](/documentation/tickets/reminders#assignment-reminders) sent while a ticket is still assigned to you Enabled by default for both Slack and email notifications. Rapid assign/unassign changes on the same task are consolidated into a single notification to reduce noise. Assignment reminders are delivered privately to the current assignee and are gated by this group's Slack and email preferences. Notifications when you become the requester on a ticket. * Tickets you create yourself * Tickets created on your behalf (for example, by an agent or a workflow) * Tickets where you are later set as the requester Enabled by default for both Slack and email notifications. Use this preference to control whether you receive a confirmation when a ticket lands in your name. Approval-related notifications for sign-off workflows. * Approval requests for tickets requiring sign-off * Approval decisions (approved/declined) * Changes to approval requirements * [Approval reminders](/documentation/tickets/reminders#approval-reminders) sent while your approval is still pending on a round **Slack**: Approval notifications are always delivered and cannot be toggled off by users or organization admins. This ensures approvers never miss time-sensitive requests. Approval reminders inherit this gating and are delivered privately to each pending approver. **Email**: Approval notifications are configurable and enabled by default. Approval reminder emails follow the same email preference. Communication and collaboration updates. * New messages on tickets you're following * Follower additions and removals * @ mentions in ticket conversations * File attachments and updates Enabled by default for both Slack and email notifications. Ticket lifecycle notifications. * Status changes (open, in progress, resolved, closed) * Ticket resolutions and closures * Reopened tickets * Archive and unarchive actions Enabled by default for both Slack and email notifications. Service level agreement notifications. * SLA breach warnings * SLA violation alerts * Time-based escalations Enabled by default for both Slack and email notifications. Learn more about [configuring SLAs](/documentation/automate/slas) Granular property change notifications. * Priority changes * Tag additions and removals * Channel transfers * Custom field updates * Due date changes Disabled by default to reduce notification volume. Enable only for users who need detailed property change tracking. *** ## Delivery channels Notifications deliver through Slack and email. Configure delivery preferences for each notification event type independently. The current Microsoft Teams beta does not yet expose a dedicated notification-channel selector. Approvals are delivered as Adaptive Cards in the approver's chat (see [Microsoft Teams approvals](/integrations/microsoft-teams/approvals)); thread-level events post into the ticket's connected Teams channel. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview) for beta scope. Direct messages provide private, focused notifications for individual users. Configure when Ravenna sends DMs: * **For Slack-originated tickets**: Select between thread notifications, DM notifications, or both * **For web and email tickets**: Enable DM notifications for non-Slack originated tickets * **Approval workflows**: Approval requests always generate Slack notifications regardless of user preferences or origin. This cannot be disabled Learn more about [Slack integration](/integrations/slack/overview) Public channel notifications are controlled by channel settings: * **Request channels**: Controlled by Silent Mode and Granular Updates settings * **Triage channels**: Team notifications for ticket management * **Ephemeral messages**: Contextual notifications visible only to specific users **Silent Mode**: When enabled in channel settings, silent mode prevents ticket mirrors from appearing in request channels and automatically excludes requesters from email notifications. This reduces notification noise while keeping followers, assignees, and other stakeholders informed. Learn more about [Slack channels](/integrations/slack/overview) and [triage channels](/integrations/slack/triage-channel) Email notifications provide backup delivery and offline access: * Digest emails for daily and weekly summaries * Critical alert emails for high-priority issues * Backup delivery when Slack is unavailable **Requester exclusion**: When silent mode is enabled in channel settings, requesters are automatically excluded from email notifications. This prevents users from receiving email updates about tickets they created, reducing notification volume while keeping other participants informed. Learn more about [email integration](/integrations/email/overview) *** ## Configuring notifications Configure notification preferences at the organization level to set defaults for all users, or at the individual user level to customize personal notification settings. ### Organization admin configuration Organization admins set default notification preferences for all members. These defaults provide a baseline experience while allowing individual users to customize their own settings. Go to **Settings → Organization → Notification Policies**. Set organization-wide defaults for Slack and email notifications for each event type. Changes apply immediately to users who haven't customized those specific settings. **Understanding organization defaults** When managing organization notification policies, keep these behaviors in mind: * **User customizations persist**: If a user has customized a specific setting, changing the organization default won't affect them * **Per-setting granularity**: Customization is tracked individually for each notification type (for example, "Assignments" for Slack) * **No bulk reset**: You cannot force all users back to organization defaults. Users must individually reset their customized settings ### User configuration Individual users customize notification preferences to control when and how they receive updates. Go to **Settings → Notifications** in your user profile. Settings marked with "Using default" follow your organization's policies. Toggle any setting to customize it. Your preference persists even if organization defaults change. Click the reset icon next to any customized setting to revert to your organization's default. Once you customize a notification setting, your preference takes precedence over organization defaults until you manually reset it. *** ## Troubleshooting If you're not receiving expected notifications: Verify your individual notification settings in **Settings → Notifications**. Check that you are properly assigned or following relevant tickets. Ensure the specific notification type is enabled for your preferred delivery channel (Slack or email). Check with your admin if organization-level defaults have changed recently. If you're receiving too many notifications: Turn off "Ticket properties" notifications to reduce volume significantly. Disable notification types that aren't relevant to your role or responsibilities. Consider using email digest notifications instead of real-time Slack notifications for less urgent updates. Unfollow tickets that no longer require your attention. Slack approval notifications have special handling that differs from other notification types: * Always delivered via Slack regardless of user or organization preferences * Cannot be toggled off in Slack notification settings (not shown as a configurable option) * Include action buttons for quick responses * Update automatically when decisions are made Email approval notifications remain configurable and can be enabled or disabled like other notification types. Slack approval notifications always deliver because they require timely action. If you're receiving approval notifications inappropriately, review your role assignments and approval workflows. ## Mental model Notifications are event-driven messages sent to users when ticket activity occurs. Notifications deliver through two channels: Slack (DMs and channel messages) and email. Each notification event type can be independently enabled or disabled for each delivery channel. Notifications are controlled at two levels: 1. **Organization defaults**: Set by organization admins. These are the baseline for all users. 2. **User overrides**: Individual users can customize any setting. Once customized, the user's preference persists even if the organization default changes. This is a "default with override" model. The organization sets sensible defaults, and users opt in or out of specific notification types as needed. *** ## Notification event types | Event type | Default (Slack) | Default (Email) | Notes | | ------------------------------ | -------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Assignments** | Enabled | Enabled | Ticket assigned/unassigned/reassigned, task assigned/unassigned, and private [assignment reminders](/documentation/tickets/reminders#assignment-reminders) | | **Ticket created** | Enabled | Enabled | Fires for the requester when a ticket is created or when they are later set as the requester | | **Approvals** | Always on (cannot disable) | Enabled (configurable) | Slack approval notifications are forced-on for timeliness. Includes private [approval reminders](/documentation/tickets/reminders#approval-reminders) sent to pending approvers | | **Messages and collaboration** | Enabled | Enabled | New messages, follower changes, @mentions | | **Status updates** | Enabled | Enabled | Status changes, resolutions, closures, reopens | | **SLA alerts** | Enabled | Enabled | SLA breach warnings and violations | | **Ticket properties** | Disabled | Disabled | Priority, tag, channel, custom field, due date, requester changes | Key behavior: Slack approval notifications cannot be disabled by users or organization admins. This is a system-level guarantee that approvers always receive approval requests promptly. *** ## Notification recipients Who receives notifications depends on the ticket role: | Role | Receives notifications | | -------------------------- | ----------------------------------------------------------------------------------------------------------- | | **Assignee** | Assignment changes, new messages, status updates, SLA alerts | | **Followers** | New messages, status updates (based on preferences) | | **Requester** | Ticket created or requester set on a ticket, status changes, new public messages (unless silent mode is on) | | **Approvers** | Approval requests (always via Slack), approval decisions | | **Workspace admins** | SLA alerts and breaches | | **Channel auto-assignees** | SLA alerts when no specific assignee exists | *** ## Channel notification settings Channel-level settings affect how notifications appear in Slack: **Silent mode**: When enabled on a channel, ticket mirrors do not appear in the request Slack channel, and requesters are excluded from email notifications. Triage channel notifications and DM notifications for assignees/followers still work normally. **Granular updates**: When enabled on a channel, detailed property change notifications (snooze, priority changes) are sent to the triage channel. These settings interact with user preferences. Silent mode reduces noise in public channels while maintaining internal team visibility. *** ## Constraints and gotchas * Slack approval notifications are always delivered and cannot be disabled at any level. This is by design. * User customizations are per-setting. Changing one notification type does not affect others. * There is no bulk reset for user customizations. Each user must individually reset their preferences to return to organization defaults. * Silent mode affects both Slack channel notifications and email notifications for requesters. It does not affect DM notifications to assignees or followers. * "Ticket properties" notifications are disabled by default because they generate high volume. Enable selectively for users who need detailed change tracking. * Organization default changes only affect users who have not customized that specific setting. Users with overrides are not affected. * Email notifications serve as backup delivery when Slack is unavailable and for digest summaries. * [Approval and assignment reminders](/documentation/tickets/reminders) are delivered as private, per-recipient notifications on three channels (in-app, Slack DM, email). Each channel is gated by the recipient's effective preference for the **Approvals** or **Assignments** group. The underlying `REMINDER_SENT` ticket event maps to `null` in `TICKET_EVENT_TO_NOTIFICATION_GROUP`; the reminder handler resolves the group from `reminderType` via `reminderNotificationGroup` and dispatches each channel directly. Reminders are only delivered on published tickets. # Audit log Source: https://docs.ravenna.ai/documentation/platform/organizations/audit-log Review a tamper-evident record of admin activity in your Ravenna organization, including configuration changes, integrations, and access policies. The audit log captures admin activity across your Ravenna organization. Use it to review who changed what and when, investigate incidents, and produce evidence for compliance reviews. *** ## Get started Click your organization name in the top left, then select **Settings** from the dropdown menu. Click **Audit log** in the left sidebar. The audit log requires the organization admin role. Members and guests cannot view audit events. *** ## What gets logged Ravenna records admin actions that change the configuration of your organization or workspaces. Each event captures the actor, target resource, action, timestamp, and a structured snapshot of the inputs. Events are recorded for areas including: * **Integrations** — connecting, configuring, or removing third-party integrations. * **Knowledge bases** — creating, updating, syncing, or deleting knowledge sources. * **Forms** — publishing, editing, archiving, or deleting forms and fields. * **Agent models** — selecting or updating the LLM provider and model used by agents. * **Agents** — creating, updating, or deleting agents. * **Rules** — creating, updating, or deleting agent rules that govern automated behavior. * **Workflows** — creating, updating, deleting, activating, or deactivating workflows. * **SLAs** — creating, updating, or deleting service level agreements. * **Applications** — creating, updating, deleting, archiving, or unarchiving applications, including bulk actions and workspace assignment changes. * **Access and roles** — changes to admin roles and permission policies. * **Members** — adding or removing workspace members, updating organization or workspace member roles, and changes to user profiles. The audit log captures admin configuration changes. Day-to-day ticket activity (comments, status changes, assignments) is recorded on individual tickets, not in the audit log. *** ## Review events The audit log displays each event as a row with the actor, action, resource, and timestamp. ### Filter events Use the filter bar above the table to narrow results: * **Actor** — the user who performed the action. * **Resource type** — the kind of object changed (for example, integration, knowledge base, form, agent, rule, workflow). * **Resource** — a specific resource by name. * **Event name** — the action performed (for example, *Integration created*, *Form updated*). * **Date range** — restrict events to a specific time window. * **Outcome** — show only successful or failed actions. Filters combine with `AND` logic. Inline text filters save automatically when you click outside the input. ### Inspect an event Click any row to open the detail panel. The panel shows: * **Summary** — actor, action, resource, and outcome. * **Inputs** — the request payload submitted with the action, with sensitive values redacted. * **Context** — the originating IP address, user agent, and request ID. * **Errors** — the error message and code, when an action failed. Use the request ID when contacting Ravenna support. It links the audit event to the underlying request trace. *** ## Export events Export a filtered view of the audit log for offline review or to share with auditors. Narrow the audit log to the events you want to export. The export respects your active filters. Click **Export** in the top right of the audit log page. Ravenna generates a CSV file containing the filtered events and downloads it to your browser. Each row includes the event timestamp, actor, action, resource type, resource name, outcome, and a JSON snapshot of the action inputs. Exports are scoped to the events visible to you. Events older than your organization's retention window are not included. *** ## Common use cases * **Investigate an unexpected change** — filter by resource and date range to find the actor and action that produced the change. * **Review admin activity for a user** — filter by actor to see every configuration change a specific admin has made. * **Provide evidence for compliance** — export events for a defined window and share the CSV with auditors. * **Detect failed admin actions** — filter by outcome `failed` to identify permission errors or misconfigurations. ## Overview | Property | Detail | | -------- | ---------------------------------------------------- | | Scope | Organization | | Access | Organization admin only | | Location | Settings > Audit log | | Purpose | Tamper-evident record of admin configuration changes | *** ## Event model ### Properties | Field | Description | | ------------- | ------------------------------------------------------------------------------------------- | | Actor | The user who performed the action. | | Action | The operation performed (create, update, delete, sync, and so on). | | Resource type | The category of the affected object (integration, knowledge base, form, agent model, role). | | Resource | The specific object affected, by ID and display name. | | Outcome | `success` or `failed`. Failed events include the error message and code. | | Inputs | A redacted JSON snapshot of the request payload. | | Timestamp | When the event was recorded, in UTC. | | Request ID | Identifier that links the event to the originating request trace. | ### Tracked resources | Resource type | Example actions | | -------------------- | ------------------------------------------------------------ | | Integration | Connect, disconnect, update configuration | | Knowledge base | Create, update, sync, delete | | Form | Create, publish, archive, delete, update fields | | Agent | Create, update, delete | | Agent model | Update LLM provider or model selection | | Rule | Create, update, delete | | Workflow | Create, update, delete, activate, deactivate | | SLA | Create, update, delete | | Application | Create, update, delete, archive, unarchive (single and bulk) | | Role / access policy | Update admin role assignments | | Workspace member | Add, remove, bulk remove, update role | | Organization member | Update role, bulk remove | | User | Update profile | ### Constraints * Events are recorded automatically by the platform. Admins cannot create, edit, or delete events. * Bulk actions (such as bulk delete or bulk archive) write one event per affected resource so each item can be traced individually. * Sensitive values (credentials, secrets, tokens) are redacted before the event is stored. * Events are retained according to your organization's retention policy. * Only organization admins can read or export events. *** ## Export | Format | Contents | | ------ | -------------------------------------------------------------------------------------------------------- | | CSV | One row per event with timestamp, actor, action, resource type, resource name, outcome, and JSON inputs. | Exports honor the filters applied to the audit log view at the time of export. # Custom email domains Source: https://docs.ravenna.ai/documentation/platform/organizations/email-domains Configure a custom email domain so outbound messages from Ravenna use your organization's domain instead of mail.ravenna.ai. By default, Ravenna sends outbound email from `mail.ravenna.ai`. Configure a custom email domain to send from your own domain instead, improving brand recognition and email deliverability. ## Prerequisites Before you start, confirm you have: * Organization admin access in Ravenna * Access to your domain's DNS management (e.g., Cloudflare, Route 53, GoDaddy) * The domain you want to send from (e.g., `support.yourcompany.com`) You can configure a subdomain (like `support.yourcompany.com`) or your root domain. Subdomains are recommended so existing email delivery is not affected. *** ## Add a custom domain Navigate to **Organization Settings > Email** from the settings sidebar. Click **Add domain** and enter the domain you want to send from. Ravenna generates the DKIM DNS records you need to add. Ravenna displays the DKIM records (CNAME entries) required for verification. Copy each record's name and value. Log in to your DNS provider and create the CNAME records shown in Ravenna. The exact steps vary by provider, but you typically navigate to DNS settings for your domain and add each record as a new CNAME entry. Return to Ravenna and click **Verify**. Ravenna checks that the DNS records resolve correctly. If verification fails, wait a few minutes for DNS propagation and try again. *** ## Verification status After adding DNS records, your domain moves through these states: | Status | Meaning | | ------------ | --------------------------------------------------------------------------------------- | | **Pending** | DNS records have not been verified yet. Click **Verify** to check. | | **Verified** | All DNS records are correctly configured. The domain is ready to use. | | **Failed** | Verification could not confirm the DNS records. Check your DNS configuration and retry. | DNS changes can take up to 48 hours to propagate, though most providers propagate within minutes. If verification fails immediately after adding records, wait and retry. *** ## Use a verified domain Once verified, your custom domain becomes available as the sender for email channels. Configure it in your workspace's channel settings: 1. Navigate to **Workspace Settings > Channels** 2. Select or create an email channel 3. Choose your verified domain as the outbound sender address All outbound email from that channel (replies, notifications, and automated messages) will use your custom domain. *** ## Troubleshooting **Verification keeps failing:** * Confirm the CNAME records match exactly (no trailing dots unless your provider requires them) * Check that you added records to the correct domain or subdomain * Wait at least 15 minutes after adding records before verifying * Use a DNS lookup tool to confirm the records are publicly resolvable **Email delivery issues after verification:** * Ensure your domain does not have conflicting SPF or DMARC records that reject messages from Ravenna's sending infrastructure * Check that the domain is not on any blocklists *** ## Remove a domain To remove a custom domain, navigate to **Organization Settings > Email**, find the domain, and click **Delete**. Channels using that domain revert to sending from `mail.ravenna.ai`. Removing a verified domain immediately affects all channels using it. Update your channel settings before removing a domain to avoid sending disruptions. # Organizations Source: https://docs.ravenna.ai/documentation/platform/organizations/overview Organizations are the top-level container in Ravenna that hold workspaces, members, integrations, billing, and shared settings for your company. An organization represents your company in Ravenna. It is the top-level container that holds all of your workspaces, members, integrations, and settings. Every Ravenna user belongs to at least one organization. ## How organizations and workspaces relate Your organization contains one or more workspaces. Each workspace is a separate space for a team or department to manage their own support requests, with independent channels, tickets, forms, and settings. Settings are split between the two levels: * **Organization settings** apply across your entire account, including branding, SSO, notification policy defaults, and member management. * **Workspace settings** are scoped to individual teams, including channels, ticket statuses, SLAs, workflows, and API keys. Learn more about [organization settings](/documentation/platform/organizations/settings) and [workspace settings](/documentation/platform/workspaces/settings). ## Organization roles An organization role is a person's baseline across the entire account. Everyone has exactly one: * **Admins** have full control over organization settings, integrations, and member management. * **Members** reach public workspaces automatically with requester access, which lets them file and track their own tickets. They cannot manage organization-level settings. To work a workspace's queue, a member must be added to that workspace. * **Guests** have no automatic workspace access, even to public workspaces. They reach a workspace only when explicitly added. By default, guests cannot see your organization in their workspace switcher. Admins can enable guest visibility in **Organization Settings > General**, which also lets guests use the Portal. The organization role is only the baseline. What someone can do inside a specific team is decided by their workspace access on top of it. For how organization roles combine with workspace access, and the full capability matrix, see [Roles and access](/documentation/platform/roles-access). ## How people join your organization People are added to your organization automatically. There is no manual "invite to organization" step. Someone becomes an organization member in one of these ways: * **Single sign-on**: the first time a person signs in through your SSO connection, Ravenna creates their organization membership. * **Identity provider or HRIS sync**: people synced from an integration are added automatically. * **Added to a workspace**: when a workspace admin adds someone by email who is not yet in the organization, their organization membership is created at the same time (see [Add someone to a workspace](/documentation/platform/workspaces/overview#add-someone-to-a-workspace)). * **Submitting a request**: when someone new sends a request by email, Slack, or Teams, Ravenna creates them as a guest so the request can be tracked. People whose email matches your company domain join as **Members**. People synced from an integration on a different email domain join as **Guests**. Enable **Guest visibility** in organization settings before guests can sign in. ## Managing organization members Go to organization settings and click the **Members** tab. Click the menu on a member's row and select **Edit** to change their organization role or set a delegate. See [organization roles](/documentation/platform/roles-access#organization-roles) for what each role can do. Select members and use the bulk action bar to remove them from the organization. Changing someone's organization role changes their baseline everywhere: promoting a member to admin grants organization-wide control, and downgrading an admin to guest removes their automatic access to public workspaces. It does not change any explicit workspace memberships they already hold. Removing someone from the organization also removes them from every workspace, because [organization membership is required before workspace membership](/documentation/platform/roles-access). Ravenna prevents removing the last organization admin so administrative access is never lost. ### Block and unblock users Organization admins can block members to immediately revoke their access to the organization. A blocked user's active sessions are invalidated on their next request, and they cannot log in until unblocked. **To block a user:** Go to **Organization Settings > Members**. Locate the member you want to block and open their profile. Click **Block user** and confirm the action. **To unblock a user:** Go to **Organization Settings > Members**. Blocked users remain in the member list with a blocked status indicator. Click **Unblock user**. Blocking a user immediately prevents access. Any in-progress work or active sessions are terminated. Use this for security incidents or when you need to revoke access urgently. **What happens when a user is blocked:** * Active sessions are invalidated on the next API request. * The user cannot log in to the organization. * Their existing ticket assignments and ownership remain intact. * They are removed from active workflow assignments. * Unblocking restores login access but does not restore previous session state. ### Set member delegates Assign a delegate to receive a member's ticket assignments and approvals while they are unavailable. * **Manager**: uses the member's direct manager (requires the Okta integration for manager data) * **Specific user**: any organization member * **No delegate**: removes delegation Members can set their own delegates in [user settings](/documentation/platform/my-settings). Admin changes override a member's own setting. ## Access controls Organization admins can configure access in **Organization Settings > General**: * **Workspace creation**: Restrict who can create new workspaces (admins only or all members). * **Guest visibility**: Let organization guests see and sign in to your organization and use the Portal. Off by default. Learn more about [organization settings](/documentation/platform/organizations/settings) and adding people to a team in [Workspaces](/documentation/platform/workspaces/overview#add-someone-to-a-workspace). # Organization settings Source: https://docs.ravenna.ai/documentation/platform/organizations/settings Configure organization-wide settings including branding, notification policies, integrations, vault credentials, and member management Organization admins access Settings to configure organization-wide policies, manage integrations, and control member access. These settings affect your entire organization and are only accessible to users with the organization admin role. ## Access organization settings Click your organization name in the top left, then select **Settings** from the dropdown menu. Use the left sidebar to navigate between different settings sections: General, Portal, Notification Policies, Integrations, SSO, Email, Vault, Applications, Workspaces, and Members. Organization settings require the organization admin role. Organization members and guests cannot access these settings. *** ## General Configure your organization's basic information and access controls. **Organization branding:** * **Organization name**: Display name shown throughout Ravenna * **Organization logo**: Custom logo appears in navigation and login screens **Access controls:** * **Direct login URL**: Unique URL for your team to access Ravenna directly (e.g., `app.ravenna.ai/login?organization=your-org`) * **Workspace creation**: Restrict who can create new workspaces (admins only or all organization members) * **Guest visibility**: Control whether guest members can see and access your organization. When disabled (default), guests cannot see your organization in their workspace switcher or log in. Enable this setting to allow guest users to access your organization and use the Portal. * **Slack Direct Message Routing**: Automatically route Slack direct messages to the right workspace based on the question. When enabled, the first message a user sends to the Ravenna app in Slack is classified by an AI agent and directed to the workspace whose Agent is the best fit. When disabled, users confirm which workspace to use before chatting, unless only one workspace is available, in which case it is selected automatically. Only workspaces with an agent connected to their DM channel are eligible for routing. Changes to organization name and logo apply immediately across all workspaces. *** ## Portal Brand the Portal that end users and guests see. Changes save automatically as you edit. **Branding options:** * **Primary color**: Accent color applied across the Portal * **Welcome message**: Greeting headline shown on the Portal home (up to 120 characters) * **Organization logo**: Show your logo in the Portal header * **Gradient banner**: Show or hide the colored banner behind the greeting * **Cover image**: Upload a wide header image * **Suggested questions**: Up to six starting prompts for the Portal chat, each with an icon, color, label, and optional custom agent prompt **Chat routing:** * **Ravenna AI in Portal**: Route platform questions in Portal chat to Ravenna AI instead of creating a ticket. When enabled, questions about the requester's own tickets or pending approvals — such as "show me my tickets" or "do I have any approvals?" — are answered by Ravenna AI without opening a ticket. Real support requests still route to the workspace's AI agent and create a ticket. Ravenna AI in Portal only reads the signed-in requester's own tickets and approvals; questions that ask about other users are denied. Off by default. Turning the setting off applies to conversations that are already in flight on their next message. Which workspaces appear in the portal is controlled per workspace with the **Available in Portal** toggle in workspace settings. Learn more about the [Portal](/documentation/platform/portal), including access, chat, and forms. *** ## Notification policies Set default notification preferences that apply to all users and new members in your organization. Individual users can override these defaults with their own preferences. **Policy configuration:** * **Default Slack notifications**: Enable or disable Slack notifications by event type (assignments, messages, status updates, SLA alerts) * **Default email notifications**: Enable or disable email notifications by event type (assignments, approvals, messages, status updates, SLA alerts) * **New user defaults**: These settings automatically apply to new organization members Slack approval notifications are always delivered and cannot be toggled off. This ensures approvers never miss time-sensitive approval requests. Email approval notifications remain configurable. **User customization:** Users can customize their own notification preferences in their personal settings. Organization policies serve as the starting point but don't prevent users from adjusting their preferences. Learn more about notification events and user preferences in Notifications. *** ## Integrations Connect and manage third-party integrations for your organization. **Browsing integrations:** * Use the category sidebar to filter integrations by type (Chat, Ticketing, HRIS, Incident Management, and more) * Each integration tile shows its connection status **Integration management:** * View connected integrations and their status * Configure integration settings and permissions * Add or remove integration connections **Connection status badges:** Each connected integration tile displays a status badge that reflects the most recent health check: | Badge | Meaning | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Connected** | The most recent health check succeeded. Credentials are valid and the integration is reachable. | | **Failing** | The most recent health check failed. Credentials may be expired, revoked, or the external service is unreachable. Reconnect or refresh credentials to restore the integration. | | **Not Tested** | No health check has been recorded yet. The integration is configured but its connection has not been verified. Open the integration to run a connection test. | Workflows and rules that depend on a **Failing** integration will fail at runtime. Resolve failing integrations before running automations that rely on them. Learn more about [available integrations](/integrations/overview) *** ## SSO Configure Single Sign-On authentication for your organization. * Connect your identity provider (Okta, Azure AD, Google Workspace, SAML, OIDC) * Manage SSO connections and domain settings * Enforce SSO-only authentication Learn more about [setting up SSO](/integrations/sso/setup) *** ## Email Manage custom email domains for outbound messages sent from Ravenna. By default, replies and notifications are sent from `mail.ravenna.ai`. Configuring a custom domain lets outbound mail appear to come from a domain you control (for example, `support@yourcompany.com`), which improves brand consistency and deliverability. **Domain management:** * Add the domain you want to send from * Follow the DNS instructions shown in settings to verify ownership and authorize sending * Once verified, the domain becomes available for channels to use as their outbound sender Only organization admins can manage custom email domains. DNS records can take time to propagate after you add them. *** ## Vault Store encrypted credentials for use in workflows and integrations. Vault credentials are encrypted at rest and can only be managed by organization admins. **Credential management:** * Create credentials with a name and secret value * Values are encrypted immediately and cannot be viewed after creation * A hint (first and last characters) helps identify credentials * Edit credential names or rotate values * Delete credentials that are no longer needed Deleting a credential may break workflows or integrations that reference it. Verify no active workflows use a credential before removing it. Learn more about [Vault](/documentation/platform/organizations/vault) *** ## Applications View and manage your application catalog, including both manually created applications and those synced from integrated identity providers. **Application types:** * **Manual applications**: Applications you create and manage directly in Ravenna * **Synced applications**: Applications automatically imported from Okta, Google Workspace, or other supported integrations **Application management:** * Define access levels for each application * Configure approval workflows for access requests * Set application owners and details * Map access levels to identity provider groups Learn how to set up applications and access levels in Applications. *** ## Workspaces View and manage all workspaces within your organization, including both public and private workspaces. **Workspace overview:** * See all workspaces regardless of your membership status * View workspace privacy settings (public or private) * Access workspace settings and configuration * Navigate directly to any workspace **Workspace management:** As an organization admin, you can: * Create new workspaces * Configure workspace settings * Manage workspace members and permissions * Archive or delete workspaces Organization admins see all workspaces in this view but still need explicit membership to access private workspace content. *** ## Members Manage organization membership, roles, and permissions for all users in your organization. **Member management:** * View all organization members (admins, members, guests) * Invite new members to your organization * Modify member roles and permissions * Remove members from the organization * Access individual member profiles to view workspace memberships **Member profiles:** Click any member to view their profile, which includes: * Organization role and permissions * Workspace memberships * Contact information * Recent activity Learn about roles and permissions in Roles and access. *** ## Admin audit log Track administrative actions across your organization with a searchable audit log. The audit log records changes made by admins to agents, integrations, knowledge bases, and forms. **Viewing audit events:** * Navigate to **Settings > Admin Audit Log** in your organization settings * Browse events in the table view with timestamp, event type, actor, and resource columns * Click any event to expand a detail panel with full context, including before and after values **Filtering and searching:** * Search events by keyword * Filter by event type, actor, resource, or date range * Group events by actor, event type, resource type, or date for pattern analysis **Exporting:** * Export filtered audit events to CSV for compliance reporting or external analysis The audit log automatically captures actions on agents, integrations, knowledge bases, and forms. No additional configuration is required. # Vault Source: https://docs.ravenna.ai/documentation/platform/organizations/vault Store API keys, tokens, and secrets in the encrypted organization Vault and reference them securely from Ravenna workflows and integrations. Vault provides encrypted credential storage at the organization level. Use it to securely store API keys, tokens, and other secrets that your workflows and integrations can reference at runtime. *** ## Get started Click your organization name in the top left, then select **Settings** from the dropdown menu. Click **Vault** in the left sidebar. Vault requires the organization admin role. Organization members and guests cannot access or manage credentials. *** ## Manage credentials ### Create a credential Click **Add Credential** on the Vault page. Provide a **Name** to identify the credential and the secret **Value** (API key, token, or password). Click **Save**. The value is encrypted immediately and cannot be viewed again after creation. A hint showing the first and last few characters of the value is displayed to help you identify credentials later. Credential names must be unique within your organization. Vault stores static values only. Ravenna does not fetch secrets at runtime from external secret managers such as AWS Secrets Manager, HashiCorp Vault, or Google Secret Manager. When a credential rotates, edit it in Ravenna to update the stored value. ### Edit a credential Navigate to **Settings > Vault** and locate the credential you want to update. Click the credential to open its details. Change the **Name** or enter a new **Value**. The previous value is never pre-filled for security reasons, so you must re-enter it if updating. Click **Save** to apply your changes. ### Delete a credential Navigate to **Settings > Vault** and locate the credential you want to delete. Click the delete option and confirm the deletion. Deleting a credential may break workflows or integrations that reference it. Verify no active workflows use a credential before removing it. *** ## Use credentials in workflows Vault credentials are available in two places: the **HTTP Request** workflow action and secret inputs on Foundry functions. ### HTTP Request action When configuring authentication, select a credential from the dropdown to securely provide the secret value. Supported authentication methods: * **API Key** - Select a vault credential for the API key value * **Bearer Token** - Select a vault credential for the bearer token value * **Basic Auth** - Select a vault credential for the password field ### Foundry function secret inputs When a Foundry function declares a secret-typed input (an API key, token, or password), select a vault credential for that field in the workflow builder instead of pasting the value. This works for secret fields at any nesting depth, including inside objects and arrays. The stored workflow configuration keeps only the credential reference. Ravenna decrypts the value in memory when the function executes and scrubs it from execution logs. You can still paste a plaintext value directly if you prefer; plaintext values pass through unchanged. Credentials are decrypted only at runtime during execution and are never exposed in the workflow builder or logs. Learn more about the [HTTP Request action and other workflow actions](/documentation/automate/workflows/triggers-actions), or how to [use Foundry functions in workflows](/documentation/automate/foundry/using-actions) *** ## Security Vault credentials are protected with multiple layers of security: * **Encryption at rest** - Values are encrypted using AES-256-GCM envelope encryption * **Write-only storage** - Values are never returned by the API or displayed in the UI after creation * **Organization-scoped isolation** - Credentials are only accessible within the organization that created them * **Admin-only access** - Only organization admins can create, edit, or delete credentials ## Overview | Property | Detail | | -------- | -------------------------------------------------------------------------------------- | | Scope | Organization | | Access | Organization admin only | | Location | Settings > Vault | | Purpose | Encrypted storage for API keys, tokens, and secrets used by workflows and integrations | *** ## Credential model ### Properties | Field | Description | | ---------- | ------------------------------------------------------------------------------------------------ | | Name | Unique identifier within the organization. Used to select credentials in workflow configuration. | | Hint | First and last few characters of the value, displayed for identification purposes. | | Type | The kind of credential stored (API key, token, password). | | Created at | Timestamp when the credential was first created. | | Updated at | Timestamp of the most recent update to the credential. | ### Operations | Operation | Access level | Notes | | ----------- | ------------------ | -------------------------------------------------------------------------- | | Create | Organization admin | Name must be unique per organization. Value is encrypted immediately. | | Read (list) | Organization admin | Returns name, hint, and metadata only. Values are never returned. | | Update | Organization admin | Can change name or value. Value must be re-entered (never pre-filled). | | Delete | Organization admin | Permanent. May break workflows or integrations referencing the credential. | ### Constraints * Credential names must be unique within an organization. * Values cannot be viewed after creation. Only a character hint is available for identification. * Only organization admins can manage vault credentials. * Deleting a credential does not automatically update workflows or integrations that reference it. Verify usage before deletion. * Credentials are encrypted at rest using AES-256-GCM envelope encryption. *** ## Workflow integration Vault credentials can be referenced in two places: the HTTP Request workflow action's authentication fields, and secret-typed inputs on Foundry functions. **HTTP Request authentication types:** | Auth type | Vault-eligible field | Header format | | ------------ | -------------------- | -------------------------------------------------- | | API Key | API key value | Configurable header name (default: `X-API-Key`) | | Bearer Token | Token value | `Authorization: Bearer ` | | Basic Auth | Password | `Authorization: Basic ` | **Foundry function secret inputs:** * Any secret-typed input field on a Foundry function accepts a vault credential reference, including secret fields nested inside objects and arrays. * References resolve wherever the function executes, including workflow runs and test runs from the Foundry Test tab. * Stored configurations and execution logs retain only the reference form, never the decrypted value. * Plaintext values entered directly in a secret field pass through unchanged. Credentials are decrypted in memory at runtime only during execution. They are never exposed in the workflow builder, logs, or API responses. # Portal Source: https://docs.ravenna.ai/documentation/platform/portal The Portal is a branded, self-service home where end users and guests open requests, chat with an AI agent, track tickets, and act on approvals and tasks. The Portal is the self-service home for people who need help but do not work tickets themselves. End users and organization guests use it to open requests, chat with an AI agent, track their tickets, and act on approvals and tasks, all from a branded page you control. Admins and workspace members who work tickets use [Admin](/documentation/platform/admin) instead. *** ## Who the Portal is for The Portal is built for people who are not workspace members: * **Organization guests** who submit and follow their own requests. * **Members of other teams** who belong to your organization but have not joined a given workspace. They land in the Portal for that team instead of hitting a dead end. Organization admins and workspace members skip the Portal and open [Admin](/documentation/platform/admin) to manage tickets. *** ## Access and sign in Requesters sign in the same way as everyone else, through your organization's login and SSO provider. There is no separate guest login. After signing in, Ravenna sends requesters to the Portal home rather than the agent workspace. Requesters who can reach more than one team land on the organization home first. It lists the workspaces that have the Portal turned on as cards, plus an organization-level AI chat when one is configured. Selecting a workspace opens that team's portal home. Each team has its own Portal home with that workspace's branding, forms, and AI agent. Requesters with access to a single team land here directly. Organization guests can only reach the Portal when an admin enables **Guest visibility**. See [Guest access](#guest-access). *** ## The Portal home The Portal home opens with a branded greeting, an AI chat box, and a set of tabs that gather everything a requester needs in one place. Shows the forms featured for the Portal, so requesters can jump straight into the most common requests. Requesters can also browse the full catalog of available forms. Quick access to the forms a requester uses most, so repeat requests take one click. A list of the requester's recent tickets. Selecting a request opens its conversation so they can read replies and respond. Pending approvals where the requester is an approver. They can approve or decline inline without leaving the Portal. Tasks assigned to the requester. They can mark a task complete with an inline checkbox. *** ## Chat with the AI agent When a workspace connects an AI agent to its Portal, requesters can describe what they need in plain language from the chat box on the home page. The agent answers from your knowledge, and when a request needs a ticket, it creates one and routes it to the right team. * **Suggested questions** give requesters a starting point. Admins configure these prompts as part of Portal branding. * **Knowledge answers** resolve common questions without opening a ticket. * **Ticket creation** happens in the conversation when the agent determines a request needs human follow-up. Portal chat requires a connected agent. Without one, requesters submit requests through forms instead. Learn how to configure the agent that powers Portal chat in [Configure agents](/documentation/automate/agents/configure). ### Ravenna AI for platform questions When **Ravenna AI in Portal** is turned on, Portal chat sends platform questions about a requester's own data to Ravenna AI instead of creating a ticket. Support questions still route to the workspace's AI agent and create a ticket as before. Ravenna AI answers questions like: * "Show me my tickets from this week." * "Do I have any approvals waiting on me?" * "What's the status of my access request?" * "Make me a chart of my tickets by status." Real support requests continue to route to the right workspace and create a ticket: * "My laptop won't connect to Wi-Fi." * "I need access to the marketing drive." * "Reset my VPN password." Ravenna AI in Portal is scoped to the requester. It only reads that requester's own tickets and approvals. Questions that ask about another user's data are denied. Turn the setting on in **Organization Settings > Portal**. When it is off, every Portal chat question routes to a workspace agent and creates a ticket, matching the prior behavior. Turning the setting off applies to conversations that are already in flight starting on the next message. *** ## Submit a request with a form Forms turn a generic request into a structured ticket with the right fields and routing. Requesters reach forms two ways: The **Start new request** tab shows only the forms an admin has chosen to feature in the Portal, keeping the most common requests front and center. Requesters can browse every form available to them, organized into folders. Search narrows the list, and private folders stay hidden. When a requester opens a form, they fill in its fields and submit. Ravenna creates the ticket, sets the requester as the person who submitted it, and shows a confirmation with a link to the new request. Forms can be shared as direct links that open straight to the form. Links can also prefill fields, so a request arrives with context already filled in. Learn how to build and feature forms in [Forms](/documentation/tickets/forms/overview). *** ## Track requests, approvals, and tasks The Portal keeps requesters connected to their work after submission: * **Requests** open into the ticket conversation, where requesters read replies, add messages, and see attachments. * **Approvals** show inline approve and decline actions for any round where the requester is an approver. * **Tasks** assigned to the requester appear with a checkbox to mark them done. Learn how ticket participation works in [Roles](/documentation/tickets/roles). *** ## Notifications Requesters stay informed by email. Ravenna sends an update when a ticket is created, when a new message is posted, and when they are added as an approver. The portal itself does not have a separate notification inbox, so email is the primary channel for Portal-only requesters. Learn more about notification events in [Notifications](/documentation/platform/notifications). *** ## Set up and customize the Portal Setting up the Portal takes two decisions: which workspaces appear in it, and how it looks. ### Turn on the Portal for a workspace Go to **Settings > General** in the workspace you want to expose. Turn on **Portal** to let this workspace's agents respond to questions in the portal and to list the workspace on the organization home. Learn more about [workspace settings](/documentation/platform/workspaces/settings). ### Brand the Portal Organization admins style the portal in **Organization Settings > Portal**. Changes save automatically as you edit. Set a **primary color** that applies across the Portal, and choose whether to show a **gradient banner** behind the greeting. Set a short **welcome message** (up to 120 characters) shown as the greeting headline. Choose whether to show your **organization logo**, and upload a **cover image** for the header (cropped to a wide banner ratio). Add up to six **suggested questions** that appear as starting points in the chat. Each has an icon, color, and label (up to 80 characters), plus an optional custom prompt (up to 500 characters) that steers the agent. Drag to reorder them. ### Connect an agent For chat to work, connect a published AI agent to the portal. When no agent is connected, admins see a setup prompt to select one. ### Turn on Ravenna AI in Portal Enable **Ravenna AI in Portal** in **Organization Settings > Portal** to let Portal chat answer platform questions about a requester's own tickets and approvals without creating a ticket. Real support requests continue to route to the workspace's agent. The setting is off by default and applies across every workspace with the Portal turned on. ### Feature forms To surface a form on the **Start new request** tab, open the form and enable **Feature in Portal**. Forms that are not featured still appear in the full catalog if the requester has access. Learn how audience settings control who sees a form in [Forms](/documentation/tickets/forms/overview#audience-settings). ### Preview as a guest Workspace admins can toggle **View as Guest** on the Portal home and forms pages to see the Portal exactly as a non-admin requester would, without changing their own role. *** ## Guest access By default, organization guests cannot see your organization at all. To let guests use the Portal, an admin enables guest access. Go to **Organization Settings > General**. Turn on **Guest Member Access** so guests can view the organization, view their tickets, and submit new requests through the Portal. Guest visibility is off by default. Guests can create tickets and send public messages, but they cannot edit ticket properties or access workspace settings. Learn more about guest permissions in [Roles and access](/documentation/platform/roles-access) and [Organization settings](/documentation/platform/organizations/settings). ## Mental model The Portal is the self-service surface for users who are not workspace members. It shares one sign-in with Admin; a user's role decides which surface they land on. * **Organization admins and workspace members** open the Admin. * **Organization guests and non-members** open the Portal. The Portal has two entry points: * **Organization home** (`/home`): lists Portal-enabled workspaces plus an optional organization-level chat. * **Workspace home** (`/{workspace}/home`): the branded home for a single team, with chat and the Start new request, Favorites, My requests, My approvals, and Tasks tabs. Tickets created through the Portal are recorded with a **Portal** source. *** ## What gates visibility Three independent settings control what a requester sees: | Setting | Level | Controls | | ------------------------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | **Guest visibility** | Organization | Whether guests can access the organization and its Portal at all. Off by default. | | **Ravenna AI in Portal** | Organization | Whether Portal chat routes platform questions about the requester's own data to Ravenna AI instead of creating a ticket. Off by default. | | **Portal** | Workspace | Whether a workspace appears in the portal and its agent can answer portal chat. | | **Feature in Portal** | Form | Whether a form appears on the **Start new request** tab. Non-featured forms still show in the full catalog. | Form audience settings apply on top of this. Only published forms whose audience includes the requester appear, and private folders are hidden. *** ## Chat and ticket creation Portal chat is powered by a connected published agent. The agent answers from knowledge, and when a request needs a ticket, it creates one and routes it to the appropriate workspace. Without a connected agent, requesters rely on forms. When a Portal conversation is routed to an agent, that agent is shown as the **Working on it** owner on the resulting ticket until it is published to a human channel. Learn how the **Working on it** owner behaves in [Roles](/documentation/tickets/roles#working-on-it-agent-owner). ### Ravenna AI routing for platform questions When **Ravenna AI in Portal** is enabled in **Organization Settings > Portal**, the router adds Ravenna AI as a candidate alongside the workspace's agents. Questions that ask about the requester's own tickets, own pending approvals, or charts of their own ticket data route to Ravenna AI and are answered without creating a ticket. Everything else — real support requests — still routes to a workspace agent and creates a ticket exactly as before. Ravenna AI in Portal is scoped to the signed-in requester: * Lookups are limited to tickets and approvals the requester owns or is an approver on. * Questions that ask about another user's tickets or approvals are denied. * Sessions persist so a requester can ask follow-up turns, but each turn re-checks the org toggle. Turning the setting off cuts in-flight conversations off on their next message, and that message re-routes to a workspace agent. *** ## Notifications Portal-only requesters are notified by email: on ticket creation, on new messages, and when added as an approver. There is no in-portal notification inbox. *** ## Constraints and gotchas * Guest visibility is off by default. Guests cannot reach the Portal until an admin enables it. * A workspace only appears in the portal when its **Available in Portal** toggle is on in the **Visibility** card under **Workspace Settings > General**. * The **Start new request** tab shows only featured forms. Other accessible published forms appear in the full catalog. * Portal chat requires a connected published agent. Without one, only forms are available. * **Ravenna AI in Portal** is off by default. When on, it answers a requester's own-data questions without creating a ticket; when off, every question routes to a workspace agent and creates a ticket. * Ravenna AI in Portal never returns data for another user. Cross-user lookups are denied even when the setting is on. * Requesters cannot edit ticket properties such as status, priority, or assignee. They create requests and add public messages. * The Portal has no notification inbox. Updates reach requesters by email. # Roles and access Source: https://docs.ravenna.ai/documentation/platform/roles-access Understand how organization roles, workspace roles, and workspace visibility combine to control what each person can see and do in Ravenna. Two things decide what someone can do in Ravenna: 1. Their organization role, which is their baseline across the whole company. 2. Their access to each workspace, which controls what they can do inside a specific team's space. Access to any given workspace is the combination of the two. *** ## How access is decided Access to a workspace depends on whether you were added to it, your organization role, and, for a workspace you were not added to, whether it is reachable through the Portal. Follow the questions from the top. ```mermaid theme={"system"} graph TD Q1{Added to this
workspace?} Q1 -->|Yes| Q2{Which workspace role?} Q1 -->|No| Q3{Organization role?} Q2 -->|Admin| Admin(Workspace Admin) Q2 -->|Member| Member(Workspace Member) Q3 -->|Admin or Member| Q4{Workspace public,
or in the Portal?} Q3 -->|Guest| None(No access) Q4 -->|Public, or private
with Portal on| Implicit(Requester access) Q4 -->|Private with
Portal off| None classDef question fill:#E2EAEF,stroke:#165d6e,stroke-width:1px,color:#0f172a classDef full fill:#165d6e,stroke:#165d6e,color:#ffffff classDef partial fill:#269cbd,stroke:#269cbd,color:#ffffff classDef blocked fill:#F1F5F9,stroke:#94a3b8,color:#475569 class Q1,Q2,Q3,Q4 question class Admin,Member full class Implicit partial class None blocked ``` | Outcome | What it means | Portal | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | **Workspace Admin or Member** | See and work on every ticket in the workspace: view, edit, assign, and resolve. | Admin | | **Requester access** | Submit requests and follow your own tickets. Cannot see or edit other people's tickets. Applies to any public workspace, and to a private workspace whose Portal is on. | Portal | | **No access** | Cannot reach the workspace or see anything in it. Applies to a private workspace whose Portal is off. | Not shown | **Requester access** is a level of access, not a role you assign. It describes what an organization admin or member can do in a public workspace they have not been added to. The only roles you assign are Admin and Member, at the organization level and inside each workspace. The easiest way to picture requester access is the surface it puts you in. The Admin adapts to your access for the workspace you are looking at: * In a workspace you **work in** (as a workspace admin or member), you see the full Admin: the queue, other people's tickets, and everything you can edit. * In a public workspace you **don't work in**, you see the Portal: a self-service home to file and follow your own requests. That Portal experience *is* requester access. Because the view follows the workspace, one person can be in the Admin for a team they work on and the Portal for a team they don't, in the same session. Organization guests only ever see the Portal. The rest of this page explains each part: organization roles, workspace access, and how the two combine. *** ## Organization roles An organization role is a person's baseline across the entire company account. Everyone has exactly one. | Role | What it means | | ---------- | ---------------------------------------------------------------------------------------------------------------------------------- | | **Admin** | Full control of the organization. Manages settings, integrations, SSO, and members. Automatically reaches public workspaces. | | **Member** | A standard internal user (for example, an employee). Automatically reaches public workspaces. Cannot manage organization settings. | | **Guest** | An external or limited user (for example, a contractor). No workspace access at all unless explicitly added to a workspace. | Full control over organization-wide configuration. **Capabilities:** * Manage organization settings, branding, and notification policies * Manage integrations and SSO * Invite, edit, and remove organization members * Reach every public workspace automatically * Reach a private workspace only when added as a workspace member Ravenna prevents removing the last organization admin so administrative access is never lost. The default role for your internal team. **Capabilities:** * Reach every public workspace automatically (see [workspace access](#workspace-access) for what that access includes) * Reach a private workspace only when added as a workspace member * Create new workspaces, unless your admin restricts creation to admins A limited role for people outside your company, such as contractors or vendors. **Capabilities:** * No automatic workspace access, even to public workspaces * Reach a workspace only when explicitly added as a workspace member * Use the Portal to submit and track their own requests * Interact with tickets where they are the requester, assignee, or follower Admins must enable **Guest visibility** in organization settings before guests can see or sign in to your organization or use the Portal. Guest visibility is off by default. New users whose email matches your company domain become organization **Members** automatically. Users synced from an integration with a different email domain become organization **Guests** for security. You can change either afterward. *** ## Workspace access Every workspace is either **public** or **private**. What that setting controls is the **queue**: who can browse the workspace and see other people's tickets in it. * **Public**: anyone in your company can open the workspace and submit a request to that team, with requester access. Good for teams that serve everyone, such as IT or People Ops. * **Private**: only workspace members can browse the queue or see other people's tickets. Good for sensitive teams such as HR, Legal, or Security. Private controls the **queue**, not the workspace's existence or the ability to file. If a private workspace has its Portal toggle (**Available in Portal** in the **Visibility** card under **Workspace Settings > General**) turned on, it still appears in the [Portal](/documentation/platform/portal), where anyone in your organization can submit a request to it and track their own tickets. What stays hidden is everyone else's tickets and the queue itself. To hide a workspace entirely, turn its **Available in Portal** toggle off. Within a workspace, access falls into one of three tiers. You assign two of them, **Admin** and **Member**. The third, **requester access**, is automatic for organization admins and members in any workspace they can reach but have not joined, and needs no setup. Automatic for organization admins and members in any workspace they can reach but have not been added to: every public workspace, plus any private workspace whose Portal is on. It covers submitting and following your own requests, not working the team's tickets. **Can:** * Create tickets in the workspace * Add public comments to tickets * See and track their own tickets (as requester, assignee, follower, or approver) * Approve or decline tickets when they are an approver **Cannot:** * See other people's tickets * Edit ticket properties such as status, priority, or assignee (including assigning a ticket to themselves) * Post private notes * Move or delete tickets * Use Copilot * Open workspace settings This is the Portal experience: for this team, the person sees the self-service home, not the agent workspace. To let someone triage and edit tickets in the workspace, add them as a workspace member. A member of the team that works this workspace. Add people here when they actively work tickets. **Can:** * See and work every ticket in the workspace, including private tickets * Edit ticket properties, assign tickets, and post private notes * Use Copilot * View workspace settings **Cannot:** * Change workspace settings * Add, remove, or change the roles of other workspace members * Delete the workspace Full control of the workspace. **Can:** * Do everything a workspace member can * Change workspace settings (SLAs, statuses, tags, and more) * Add, remove, and change the roles of workspace members * Delete the workspace Ravenna prevents removing the last workspace admin. *** ## Master capability matrix The columns combine both layers. "Org Guest" is the organization role. "Requester access" is an organization admin or member in a public workspace they have not been added to. "Workspace Member" and "Workspace Admin" are the two roles you assign inside a workspace. allowed    not allowed | Capability | Org Guest | Requester access | Workspace Member | Workspace Admin | | ------------------------------------------------- | :----------------------------------: | :-----------------------------------: | :-----------------------------------------: | :------------------------------------------: | | **Organization** | | | | | | Manage organization settings | | | | | | Manage organization members | | | | | | **Workspace access** | | | | | | Reach a public workspace | | | | | | Reach a private workspace | | | | | | See other people's tickets | | | | | | **Tickets** | | | | | | Create tickets | | | | | | Public comments | | | | | | Edit status | | | | | | Edit priority | | | | | | Edit assignee (assign to anyone) | | | | | | Assign a ticket to yourself | | | | | | Edit tags, category, type | | | | | | Edit custom fields | | | | | | Private notes | | | | | | Move or delete tickets | | | | | | Use Copilot | | | | | | **Workspace management** | | | | | | View workspace settings | | | | | | Change workspace settings | | | | | | Manage workspace members | | | | | | Delete workspace | | | | | | **Portal** | | | | | | Portal they land in | Requester (if Guest visibility on) | Requester | Admin | Admin | Organization admins are not shown as a separate column because their org role does not by itself grant ticket or workspace-management powers inside a workspace. In a public workspace they have requester access; in any workspace, working tickets requires an explicit workspace membership. Reaching a private workspace always requires being added. The **portal** row shows the surface each tier signs in to. Workspace admins and members work the queue in [Admin](/documentation/platform/admin). Everyone else uses the [Portal](/documentation/platform/portal) to submit and track their own requests. Organization guests only reach the Portal when an admin enables Guest visibility. A small number of workspaces may still show a legacy **Guest** workspace role from before it was retired. Guest can no longer be assigned to new members. If you see it, edit the member and switch them to Member or Admin. *** ## Who can edit a ticket's fields There is one rule for editing a ticket, and it is worth stating plainly: To edit **any** field on a ticket, you must be an **admin or member of that ticket's workspace**. Nothing else grants it. This is deliberately strict. Editing a field means changing status, priority, assignee, tags, category, type, or any custom field, and it also covers assigning the ticket to yourself. * **Organization role does not grant it.** An organization admin has no ability to edit fields in a workspace they have not joined, even a public one. Their org role controls organization settings and members, not ticket fields. * **Requester access does not grant it.** Organization admins and members with requester access can create a ticket and add public comments, but they cannot change its fields, not even to assign it to themselves. * **Organization guests cannot edit fields.** They can only participate through the [ticket roles](/documentation/tickets/roles) they hold (requester, assignee, follower, approver). * **Workspace admins and members can edit every field** on any ticket in their workspace, including [private tickets](/documentation/tickets/private-tickets). The **Edit** rows in the [capability matrix](#master-capability-matrix) above show this rule field by field. The **Assignee options** workspace setting controls who can be *picked* from the assignee list, not who is allowed to assign. Even if that setting is set to "Organization members," a person still needs workspace membership to change the assignee. See [workspace settings](/documentation/platform/workspaces/settings). *** ## How requests reach a workspace People rarely submit a request by opening a workspace and clicking **New ticket**. They use whichever surface is most convenient, and Ravenna routes the request to the right team for them. This works even for a private workspace they cannot open themselves: * A Slack request channel connected to the workspace * A direct message to the Ravenna app in Slack * An email address that belongs to the workspace * A form that belongs to the workspace * The AI agent, which reads the request and sends it to the best-fit team The person who submits becomes the ticket's requester and can follow their own ticket in the Portal, but they do not join the workspace or see the rest of its tickets. What keeps a team's tickets restricted is **workspace membership**: only members see other people's tickets in a workspace. To restrict a single sensitive ticket inside an otherwise busy workspace, use a [private ticket](/documentation/tickets/private-tickets), which limits that ticket to its requester, assignee, followers, approvers, and the workspace's members and admins. *** ## Choosing the right access Assign the least-privileged access that still lets people do their jobs. Members automatically reach public workspaces and can file requests everywhere. You do not need to add everyone to every workspace just so they can open tickets. Add people to a workspace when they need to triage, edit, assign, or resolve tickets in it. Make the people who configure the workspace Admins, and the rest Members. For contractors or vendors on a different email domain, keep them as organization Guests and enable Guest visibility. They can file and track their own tickets without gaining access to your teams' queues. When only one team should work a queue, make the workspace private and add only that team. People outside the team can still submit requests to it through Slack, email, or a form. You do not need to add people as workspace members just to let them file tickets. Requester access already covers filing and tracking their own requests in public workspaces. Reserve workspace membership for people who work the queue. Manage people where they live: [organization members and delegates](/documentation/platform/organizations/overview#managing-organization-members) and [adding people to a workspace](/documentation/platform/workspaces/overview#add-someone-to-a-workspace). See also the [Admin and Portal](/documentation/platform/portal). *** ## Examples Common situations and the access that results. Your IT workspace is **public**. An employee is an organization **Member** but was never added to the IT workspace. They have **requester access**: they can open a ticket in the IT workspace and follow their own request, but they cannot see anyone else's tickets, change a ticket's status, or assign it. When they sign in, they land in the [Portal](/documentation/platform/portal), not the agent workspace. Make the HR workspace **private** and add only the HR team as workspace members. The queue is then limited to those members. Anyone else, including organization admins who have not been added, cannot browse or work its tickets. Employees can still submit HR requests through email, a Slack request channel, a form, or the agent. Their request lands in the workspace, and they can follow their own ticket, without seeing the rest of the team's tickets. Making the workspace private does not hide it from the Portal. If HR's **Available in Portal** toggle (in the **Visibility** card under **Workspace Settings > General**) is on, the HR workspace still shows up as a place people can submit requests, they just cannot see the queue. To hide HR entirely, turn its **Available in Portal** toggle off. Keep them as an organization **Guest** and enable Guest visibility. They sign in to the [Portal](/documentation/platform/portal), where they file and track their own requests without gaining access to any team's queue. You do not need to add them to a workspace unless they will actively work tickets there. Add them to the IT workspace as a **Member**. Members work the whole queue: they see every ticket, edit properties, assign, post private notes, and use Copilot. Make them an **Admin** instead only if they also need to change workspace settings or manage the workspace's members.
## Mental model Access is the combination of two independent layers, both using the same three role names but with different meaning: 1. **Organization role** (`OrganizationMember.role`): the baseline across the whole account. Values: Admin, Member, Guest. 2. **Workspace access**: what you can do inside one workspace. Only Admin and Member are assignable. A third state, requester access, applies to organization admins and members in a public workspace they have no explicit membership in. You must be an organization member before you can be a workspace member. Workspace membership always sits on top of organization membership. The Admin at `app.ravenna.ai` adapts to your access **for the workspace you are viewing**. In a workspace where you are an admin or member, you see Admin (the queue). In a public workspace you have only requester access to, you see the Portal (self-service). The same user can move between the two surfaces in one session as they switch workspaces. Organization guests only ever see the Portal. See [Portal](/documentation/platform/portal). *** ## Organization roles | Role | Public workspace | Private workspace | Org settings | Member management | | ---------- | ------------------------------------- | --------------------------------- | ------------ | ----------------- | | **Admin** | Requester access (automatic) | Only if added as workspace member | Full | Full | | **Member** | Requester access (automatic) | Only if added as workspace member | None | None | | **Guest** | None unless added as workspace member | Only if added as workspace member | None | None | New users on your company email domain default to Member. Users synced from an integration on a different domain default to Guest. Guests cannot see or sign in to the organization unless Guest visibility is enabled in organization settings. *** ## Workspace access tiers There are three tiers, but only two are assignable. | Tier | How you get it | Portal | See others' tickets | Create tickets | Edit properties / assign | Private notes | Copilot | Settings | | ---------------------------- | ------------------------------------------------- | --------- | :-----------------: | :------------: | :----------------------: | :-----------: | :-----: | :-------: | | **Requester (not a member)** | Org Admin/Member in a public workspace, not added | Requester | No (own only) | Yes | No | No | No | No | | **Member** | Explicitly added | Agent | Yes | Yes | Yes | Yes | Yes | View only | | **Admin** | Explicitly added or promoted | Agent | Yes | Yes | Yes | Yes | Yes | Full | Key behaviors: * **Requester access** is the default state for most of the organization in public workspaces. It permits filing and tracking your own tickets and public comments, nothing more. It does not permit editing ticket properties, self-assigning, private notes, moving/deleting, or Copilot. * **Only workspace Admins** can add, remove, or change the roles of workspace members. Workspace Members cannot. * The **Guest workspace role is deprecated** and can no longer be assigned. Only Admin and Member are selectable. Any remaining Guest rows are legacy data. * New workspaces are **private by default** when created through the API without specifying visibility. * **Editing any ticket field requires workspace admin or member** of that ticket's workspace. Org role alone, requester access, and guest never permit it, including self-assignment. This is the single rule behind the "Edit ..." rows in the matrix. * **Portal view follows the tier per workspace**: in a workspace you are an admin or member of you see Admin; in a public workspace you only have requester access to you see the Portal (`/{workspace}/home`). The view is a rendering of your permissions, not the thing that grants them. *** ## Public vs private workspaces Visibility controls the **queue** (who can browse the workspace and see other people's tickets), not the workspace's existence or the ability to file. * **Public**: org Admins and Members get requester access automatically. Org Guests get nothing unless explicitly added. * **Private**: only workspace members browse the queue or see other people's tickets, org admins included. Requests still reach a private workspace through its intake surfaces (request channel, DM routing, email, forms, agent). The requester becomes the ticket requester and follows their own ticket, but does not join the workspace or see the rest of the queue. **Private is not the same as hidden.** A private workspace with its **Available in Portal** toggle on still appears in the Portal, where any org user can submit a request to it and track their own tickets. Privacy hides the queue and other people's tickets, not the workspace itself. To hide a workspace from the portal entirely, turn its **Available in Portal** toggle off. The boundary that restricts a queue is **workspace membership**: only members see other people's tickets in a workspace. For a single sensitive ticket inside a busy workspace, use a private ticket. *** ## Three layers of access, top to bottom Ravenna has a third, ticket-scoped layer on top of the two above: 1. **Organization role**: baseline across the account. 2. **Workspace access**: what you can do inside a workspace. 3. **Ticket roles** (requester, assignee, follower, approver): control access to individual tickets, especially private ones. For private tickets, workspace admins and members always retain access regardless of ticket roles. Everyone else needs a qualifying ticket role. Learn more about [ticket roles](/documentation/tickets/roles) and [private tickets](/documentation/tickets/private-tickets). *** ## Constraints and gotchas * Organization membership is required before workspace membership. You cannot add someone to a workspace without first making them an organization member. * The last organization admin and the last workspace admin cannot be removed. * **Editing any ticket field (status, priority, assignee, tags, category, type, custom fields) requires being an admin or member of that ticket's workspace.** Org role alone, requester access, and guest do not permit it, including self-assignment. Even an organization admin cannot edit fields in a workspace they have not joined. To grant editing, add the person as a workspace member. * Requester access (org admin or member, no workspace membership) permits creating tickets and public comments only. * Only workspace Admins can manage workspace members. Members cannot add, remove, or re-role others. * The workspace Guest role is deprecated and cannot be assigned. Existing Guest rows are legacy. * A private workspace limits its queue to workspace members, but requests can still be routed in through its intake surfaces (channel, DM, email, form, agent). Filing a request is not the same as joining the workspace. * **Private is not hidden.** Privacy scopes the queue, not the workspace's existence. A private workspace with its **Available in Portal** toggle on still appears in the Portal (see [Public vs private workspaces](#public-vs-private-workspaces) above). Turn that setting off to hide it entirely. * Private tickets are visible to all workspace members. Use a private ticket to restrict a single ticket inside a workspace; use workspace membership to restrict a whole queue. * Guest visibility must be enabled in organization settings before organization guests can see or sign in to the organization. # Workspaces Source: https://docs.ravenna.ai/documentation/platform/workspaces/overview Workspaces are dedicated spaces for IT, HR, finance, or other teams to manage their own channels, tickets, forms, and workflows independently. A workspace is a dedicated space within your organization for a specific team or department to manage their support requests. Each workspace has its own channels, tickets, forms, workflows, and settings. ## When to create a workspace Create a new workspace when a team or department needs its own support workflow. Common examples: | Team | Purpose | | -------------------------- | ------------------------------------------------------ | | **IT Operations** | Software access, equipment, account management | | **People Operations / HR** | Benefits, onboarding, leave requests, policy questions | | **Finance** | Expense reports, procurement, budget approvals | | **Legal** | Contract reviews, compliance questions | | **Security** | Incident reports, access reviews, policy exceptions | | **RevOps / Sales Ops** | CRM support, deal desk, tooling requests | Each workspace operates independently, so teams can configure their own categories, forms, SLAs, and agent rules without affecting other teams. You do not need a separate workspace for every Slack channel or project. Workspaces are best suited for distinct teams with their own support processes. Use channels within a workspace to organize tickets by topic or workflow. ## Create a workspace Click the workspace name in the top-left corner of the Ravenna Portal. Click **Create workspace** at the bottom of the workspace list. Enter a clear, descriptive name that reflects the team or function (e.g., "IT Operations" or "People Ops"). Set up channels, forms, categories, and other settings to match your team's support process. Write a clear workspace description in **Workspace Settings > General**. The AI agent uses this description to route requests to the correct workspace. Organization admins can restrict workspace creation to admins only. If you do not see the option to create a workspace, contact your organization admin. ## Visibility Workspaces can be **public** or **private**. Toggle visibility in **Workspace Settings > General**. Visibility controls the **queue**: who can browse the workspace and see other people's tickets in it. * **Public**: organization admins and members reach the workspace automatically with requester access, which lets them file and track their own tickets. Working the queue (editing, assigning, private notes) requires being added as a workspace member. * **Private**: only workspace members can browse the queue or see other people's tickets. Private workspaces are useful for teams handling sensitive requests like HR or Security. Private is not the same as hidden. If a private workspace has its **Available in Portal** toggle (in the **Visibility** card under **Workspace Settings > General**) on, it still appears in the [Portal](/documentation/platform/portal), where any org user can submit a request to it and track their own tickets. Privacy hides the queue and other people's tickets, not the workspace itself. To hide a workspace from the portal entirely, turn its **Available in Portal** toggle off. Learn more about [roles and access](/documentation/platform/roles-access), including the three workspace access tiers. ## Add someone to a workspace Add people to a workspace when they need to work its tickets. This is done by a workspace admin, and it is also the way to bring a brand-new person into your organization. In the workspace, click the **Members** tab to see everyone in it. Click **+ Member**. Choose an existing organization member, or type an email address to add someone new. Adding a new email creates their organization membership at the same time. Assign **Admin** or **Member**. The **Send invitation email** toggle is on by default. Turn it off to add someone without emailing them. Click a member's row to open their details, then click **Edit** to change their role or remove them from the workspace. You do not need to add people to a workspace just so they can submit requests. Anyone in your company can already file requests to a public workspace. Add someone as a member only when they need to work its tickets. See [roles and access](/documentation/platform/roles-access). The workspace **Guest** role is deprecated and can no longer be assigned. Only Admin and Member are selectable. If a workspace still shows a legacy Guest, edit that member and switch them to Member or Admin. ### Manage invitations When you add members, Ravenna sends invitation emails by default. * **Skip invitation emails**: turn off the **Send invitation email** toggle in the add member dialog. Useful when setting up a workspace before it is ready, or when onboarding in bulk. * **Resend in bulk**: select members in the table, then click **Resend invite** in the bulk action bar. Ravenna reports how many were sent and flags any failures. Bulk resend requires the admin role: workspace admins for workspace invitations, organization admins for organization invitations. Adding or removing a workspace member takes effect immediately. ## Switching workspaces Use the workspace switcher in the top-left corner to move between the workspaces you have access to. Ravenna remembers the last workspace you visited in each organization, so when you switch between organizations you return to where you left off instead of a default landing workspace. If you belong to multiple organizations, opening Ravenna takes you back to the organization and workspace you used most recently. Switching organizations from the workspace switcher restores that organization's last workspace as well. Learn more about [workspace settings](/documentation/platform/workspaces/settings) for channels, SLAs, statuses, tags, and other configuration. ## Mental model A workspace is the primary organizational boundary in Ravenna. Everything operational is workspace-scoped: channels, tickets, forms, workflows, SLAs, categories, tags, statuses, knowledge folders, agents, and task templates. One organization contains many workspaces. Each workspace operates independently with its own configuration. Key relationships: * One organization has many workspaces. * One workspace has many channels, forms, workflows, agents, and knowledge folders. * Tickets belong to exactly one workspace (but can be moved between workspaces). * Parent-child ticket relationships can cross workspace boundaries. * Applications are organization-scoped but visible in specific workspaces. *** ## When to create vs not create a workspace **Create a new workspace when:** * A team needs its own forms, categories, SLAs, or agent rules that differ from other teams. * The team handles a distinct type of support request (IT vs HR vs Finance). * Access control requires separation (e.g., HR tickets should not be visible to IT team members). **Do NOT create a new workspace for:** * Different Slack channels within the same team. Use Ravenna channels within a workspace instead. * Different ticket categories or tags. Use categories/tags within a workspace. * Different projects. Use channels or tags within the same workspace. A workspace is for a team, not for a topic. Use channels and tags within a workspace to organize topics. *** ## Workspace visibility Visibility scopes the **queue** (who browses the workspace and sees other people's tickets), before roles decide what they can do inside it. * **Public**: organization admins and members get requester access automatically. Requester access lets them file and track their own tickets, but not work the queue. Organization guests get no access unless explicitly added as workspace members. * **Private**: only workspace members browse the queue or see other people's tickets, regardless of organization role, including organization admins. If the workspace's **Available in Portal** toggle is on, it still appears in the Portal, where any org user can submit to it and track their own tickets. Privacy scopes the queue, not the workspace's existence. Turn the **Available in Portal** toggle off to hide it entirely. Private workspaces are appropriate for teams handling sensitive requests (HR, Security, Legal). For the full access model, see [Roles and access](/documentation/platform/roles-access). *** ## Workspace description for agent routing The workspace description (set in Workspace Settings > General) is used by the AI agent to determine where to route requests. A clear, specific description helps the agent send tickets to the correct workspace. Good description: "IT Operations handles software access requests, equipment provisioning, account management, VPN issues, and technical support for internal tools." Poor description: "IT workspace." *** ## Constraints and gotchas * Tickets belong to exactly one workspace but can be moved between workspaces (with caveats: new ticket ID, possible follower loss, assignee reassignment). * Parent-child ticket relationships work across workspaces. * Knowledge folders are workspace-scoped. There is no cross-workspace knowledge sharing. * Task templates are workspace-scoped. * SLAs are workspace-scoped. * Applications are organization-scoped and can be surfaced in specific workspaces via form configuration. * Organization admins can restrict workspace creation to admins only. * Workspace admins and members always have access to private tickets within their workspace. * Only workspace admins can add, remove, or re-role workspace members. The workspace **Guest** role is deprecated and cannot be assigned. * Adding a new email through the add-member dialog creates the organization membership and the workspace membership together. A user cannot be a workspace member without first being an organization member. * Workspace membership changes take effect immediately. When adding members, the `sendInvitation` flag defaults to `true`; set it to `false` to skip invitation emails. # Workspace settings Source: https://docs.ravenna.ai/documentation/platform/workspaces/settings Configure workspace-specific settings including Slack integration, SLAs, statuses, tags, tasks, custom fields, API keys, and webhooks As a workspace admin or member, you can open Settings to configure workspace-specific policies, integrations, and ticket management tools. These settings apply to a single workspace. ## Access workspace settings Select the workspace from the workspace switcher in the top left. Click **Settings** in the left sidebar to access workspace configuration. Use the left sidebar to navigate between different settings sections: General, Slack, SLAs, Business Schedules, Automation, Statuses, Tags, Tasks, Fields, API Keys, Webhooks, and Categories. Workspace settings require workspace admin or member role. Workspace guests cannot access settings. *** ## General Configure basic workspace information, defaults, and preferences. ### Workspace details * **Icon and name**: Set a display name and icon with custom color for the workspace. Select any icon from the full [Lucide](https://lucide.dev/icons) library, or search by name in the icon picker. * **Workspace URL**: The URL identifier for your workspace. Changing it redirects old URLs automatically. * **Description**: Describe the purpose of the workspace and the type of requests it handles. The agent uses this description for intelligent request routing. When users submit requests, the agent analyzes the description to determine which workspace should handle the request. Write descriptions that clearly define scope and responsibilities. Example: *"This is the IT workspace. We handle requests related to software access, equipment, Slack channels, and group management."* * **Private workspace**: Toggle whether the workspace is private (accessible only by workspace members) or public (accessible to all organization members). ### Default channel Select the default channel for the workspace. When a default is set, tickets that don't match a specific channel are routed here. ### Default form Select the default form for the workspace. When a default is set, new tickets use this form unless the submitter selects a different one. ### Workspace settings Configure who can be *selected* as the assignee on tickets in this workspace. * **Organization members**: Any member of the organization can be picked as an assignee. * **Workspace members**: Only members of this workspace can be picked as an assignee. **Default:** Organization members This setting controls who appears in the assignee picker. It does not grant the ability to assign tickets. Performing an assignment still requires workspace membership, so a user with [requester access](/documentation/platform/roles-access) cannot assign tickets even to themselves. Control whether third-party Slack bot users (e.g., Claude, Jira, GitHub bots) can interact with your workspace. When enabled: * **Message sync**: Messages sent by third-party bots in Slack threads are synced into the corresponding Ravenna tickets. * **Mentions**: Bot users appear in mention and tag dropdowns across tickets, workflows, and rules. When disabled, bot messages from Slack are not synced and bot users do not appear in mention dropdowns. Only message events from bots are synced. Other bot activity like reactions and channel joins are never synced, regardless of this setting. Ravenna's own bot messages are always excluded to prevent message loops. **Default:** Disabled ### Visibility Control where this workspace appears as an option when users file tickets. Show this workspace as an option when users file tickets from Slack (home tab workspace picker). **Default:** Enabled Show this workspace as an option when users file tickets from the Portal create-ticket form. Learn more about the [Portal](/documentation/platform/portal) and how to brand it. **Default:** Disabled Visibility only controls filing surfaces. Direct message routing follows Agent presence: any workspace with an Agent connected to its **Slack** channel can receive DM conversations, regardless of these toggles. ### Workspace ID A read-only identifier for your workspace used in API integrations and support requests. ### Danger zone * **Leave workspace**: Remove yourself from the workspace and lose access to its data. You cannot leave if you are the last member or last admin. * **Delete workspace**: Permanently delete the workspace and all of its data, including tickets, channels, settings, and member access. This action requires workspace admin permissions and cannot be undone. *** ## Slack Connect and configure Slack integration for your workspace. Slack settings are organized into four tabs: Connections, Mirrors, Appearance, and Emoji Actions. For Microsoft Teams, channel and tenant connection is managed in the workspace's Microsoft Teams settings. The current beta does not yet expose per-channel mirror, appearance, or emoji customization. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview). ### Connections Configure which Slack channels are connected to your workspace. **Triage channel:** Connect a Slack channel to use as your triage channel for reviewing and managing incoming requests. **Request channels:** Connect one or more Slack channels where users can submit requests. Messages in these channels can automatically create tickets. Learn how to set up Slack integration in Slack. Workspace visibility toggles live in the **Visibility** card under **Workspace Settings > General**. See [Visibility](#visibility). ### Mirrors Control which fields appear on ticket mirrors in Slack channels and the order they display. These settings apply workspace-wide across all channels. **Field ordering:** Drag fields to reorder how they appear on ticket mirrors in Slack. The order you set here determines the top-to-bottom layout of fields on every ticket mirror in the workspace. **Field visibility controls:** Display the status field on ticket mirrors. **Default:** Shown Display the priority field on ticket mirrors. **Default:** Shown Display the description field on ticket mirrors. **Default:** Hidden Display the assignee field on ticket mirrors. **Default:** Shown Display the requester field on ticket mirrors. **Default:** Shown Display the approvers field on ticket mirrors. **Default:** Shown Display the source field on ticket mirrors. **Default:** Shown Display custom fields from forms on ticket mirrors. **Default:** Shown These settings control field visibility in channel mirrors. Ticket mirrors in Slack Home and flexpane views always display all fields regardless of these settings. ### Appearance Customize how the Ravenna bot appears in your Slack workspace. * **Bot icon**: Upload a custom image for the Ravenna bot avatar in Slack. Accepts PNG, GIF, or WebP format (max 1MB, 512px). * **Bot username**: Set a custom display name for the Ravenna bot in Slack messages. These settings apply to all messages sent by the Ravenna bot in this workspace, including ticket mirrors, notifications, and automated responses. ### Emoji actions Customize the emoji reactions used to trigger ticket actions in Slack. Each action has a default emoji that you can change to match your team's preferences. Learn more about [emoji actions](/integrations/slack/emoji-actions). *** ## SLAs Define and monitor service level agreements for your workspace tickets. **SLA configuration:** * Create response time targets * Set resolution time commitments * Configure closure deadlines * Set up early warning alerts before breaches * Filter SLAs by ticket properties (priority, category, form) * Track SLA compliance through visual indicators * Attach a business schedule so timers respect working hours * Select pause statuses that stop the timer while waiting Learn about SLA targets and monitoring in SLAs. *** ## Business schedules Define the timezone and weekly working hours that SLAs use to measure response, resolution, and close times. **Schedule configuration:** * Set a timezone (IANA, for example `America/New_York`) * Define weekly working hours per day, in 24-hour `HH:MM` format * Mark one schedule as the workspace default * Share a schedule across multiple SLAs * Archive schedules that are no longer in use When an SLA references a schedule, its timers only advance during the schedule's working windows. Time outside those windows is excluded from SLA measurement. An SLA with no schedule continues to use wall-clock time. **Archiving and deleting schedules:** A schedule must have no connected SLAs before you can archive or delete it. If any SLA still references the schedule, Ravenna blocks the action and shows how many SLAs are affected. Update each of those SLAs to use a different schedule (or no schedule) first, then retry. To delete the workspace default schedule, promote another schedule to default first. [Approval reminders](/documentation/tickets/reminders) and [assignment reminders](/documentation/tickets/reminders) can also reference a business schedule. The schedule is selected per policy in **Automation** settings rather than inherited from the workspace default. If a reminder would fire outside the selected schedule's working windows, Ravenna defers it to the next working window. Policies with no schedule selected send reminders on a wall-clock interval. Learn how schedules combine with SLA targets in SLAs. *** ## Automation Configure automated actions that run per workspace, including reminder policies and intelligent ticket reopens. ### Reminder policies Each reminder policy has an enable toggle, a reminder interval, a maximum reminder count, and an optional business schedule. * **Approval reminders**: nudge pending approvers when an approval round has been waiting too long. * **Assignment reminders**: nudge the current assignee when an assigned ticket has been sitting in an open status. Learn how to configure cadence, business-hours behavior, and escalation in [approval reminders](/documentation/tickets/reminders#approval-reminders) and [assignment reminders](/documentation/tickets/reminders#assignment-reminders). ### Re-Open Tickets **Intelligent Reopen** automatically moves a resolved ticket back to **Open** when the requester or a follower sends a new message that reads as a genuine request. This works across every channel Ravenna supports — email, Slack, Microsoft Teams, the Admin, and the Portal — so tickets do not stay closed while someone is still asking for help. The setting is **on by default**. Toggle it off from the **Re-Open Tickets** card if your team prefers to leave reopens fully manual. A reopen only fires when **all** of the following are true: * The ticket is currently in a terminal status group (**Done** or **Closed**, including any custom sub-statuses under those groups). * The new message was sent by the ticket's requester. Messages from agents, other collaborators, or unrelated users do not reopen the ticket. * The sender is a real user. Bot-authored messages (including replies from other integrations) never trigger a reopen. * Ravenna's classifier determines the message is a request rather than a "thanks", an acknowledgement, or an out-of-office reply. When a reopen happens, Ravenna: 1. Moves the ticket to **Open**. 2. Posts a private system note on the ticket explaining that the ticket was reopened automatically because a new message arrived after it was resolved. The note is only visible to agents. ### Close ticket task policy The **Unfinished Tasks** card controls what Ravenna does with open tasks when a ticket is moved into a terminal status group (**Done** or **Closed**). Choose one of two options from **When a ticket closes with open tasks**: * **Keep tasks open** (default): tasks stay in their current state when the ticket is resolved or closed. Agents can still cancel individual tasks by hand from the ticket. * **Cancel remaining tasks**: when an agent moves a ticket from a non-terminal status into **Done** or **Closed**, Ravenna prompts for confirmation and, if confirmed, cancels every open task on the ticket. Cancelled tasks can be restored from the ticket's task list. The policy only applies to non-terminal to terminal transitions. Moving a ticket between two terminal statuses (for example, from **Done** to **Closed**) does not re-run the prompt. ### Inactivity auto-close Configure rules to automatically close tickets when requesters stop responding. Auto-close prevents stale tickets from accumulating in your queues. **To set up inactivity auto-close:** In workspace settings, select **Automation** from the left sidebar. Toggle on the inactivity auto-close policy in the **Inactivity Auto-Close** card. Configure how long to wait after the last requester message before closing the ticket. Enable nudge notifications to alert the assignee before a ticket is auto-closed, giving them a chance to intervene. **How auto-close works:** * The timer starts after the last message from the requester. * Agent messages and internal notes do not reset the timer. * Before closing, Ravenna can notify the assignee so they can intervene. * When the threshold is reached, the ticket is automatically moved to a closed status. * Requesters receive a notification that their ticket was closed due to inactivity. * If the requester replies after auto-close, the ticket reopens automatically. Auto-close only applies to tickets waiting on requester response. Tickets actively being worked on by agents are not affected. Automation settings require workspace admin access. *** ## Statuses Configure ticket lifecycle statuses for your workspace. **Status management:** * Use five system statuses (Open, In Progress, Waiting, Done, Closed) * Create custom sub-statuses under each system status * Assign custom statuses to specific forms Learn about status configuration in Statuses. *** ## Tags Create and manage flexible labels for organizing tickets. **Tag configuration:** * Create workspace-specific tags * Set tag names, descriptions, and colors Learn about tag management in Tags. *** ## Tasks Configure task settings and subtask workflows. **Task management:** * Create task templates for recurring workflows * Define task steps and requirements * Apply templates to tickets Learn about ticket tasks in Tasks. *** ## Fields Create and manage custom fields for ticket forms. **Custom field configuration:** * Create custom fields (text, dropdown, checkbox, date, etc.) * Assign fields to specific forms * Configure required vs. optional fields Learn about custom fields in Custom fields. *** ## API keys Generate and manage API keys for programmatic workspace access. **API key management:** * Create API keys for workspace integration * Optionally restrict a key to one or more IP ranges (CIDR notation) * Edit the IP ranges on an existing key * Revoke API keys The API keys table shows each key's creation date, last usage timestamp, and its current IP restrictions. A key with no ranges configured is usable from any IP address; a restricted key shows either its single range or a count of ranges (for example, `3 ranges`). **Restrict a key to specific IP ranges:** Add one or more CIDR ranges in the **Allowed IP ranges** field when you create a key, or open an existing key's menu and choose **Edit IP ranges**. Requests from outside the allowed ranges are rejected with `403 Forbidden`. Both IPv4 (`203.0.113.0/24`) and IPv6 (`2001:db8::/32`) are accepted, and each key can hold up to 50 ranges. See the [API overview](/api/overview#restrict-a-key-to-specific-ip-ranges) for the full notation reference and how the caller IP is resolved. API keys provide programmatic access to workspace data. Store keys securely. *** ## Webhooks Configure webhooks to receive real-time notifications about workspace events at an external HTTP endpoint. **Create a webhook:** In workspace settings, select **Webhooks** from the left sidebar. Click **Create** to open the webhook dialog. Enter: * **Name**: a friendly label used to identify the webhook in the list. * **URL**: the endpoint where Ravenna sends event payloads. Each URL can only be used by one webhook in the workspace. If another webhook already delivers to the same URL, Ravenna rejects the request with a `WEBHOOK_URL_EXISTS` conflict error and points to the existing webhook. Update the existing webhook instead of creating a duplicate. Submit the form to create the webhook and open its detail page. On the detail page, configure the following fields: * **URL**: change the destination endpoint at any time. Changing the URL to one another webhook already uses is rejected with the same `WEBHOOK_URL_EXISTS` error. * **Secret key**: shared secret used to sign each delivery with HMAC-SHA256, sent in the `X-Ravenna-Signature` header so your endpoint can verify requests came from Ravenna. Ravenna does not deliver events until a secret is set. * **Ticket events**: toggle on to receive all ticket events. * **Message events**: toggle on to receive all message events. * **Active**: toggle off to pause delivery without deleting the webhook. Field changes save automatically. Rename the webhook by editing the title at the top of the page. **Manage existing webhooks:** * Each webhook on the Webhooks list shows its URL and an **Active** or **Inactive** status badge. * Click a row to open the detail page, or use the row actions to view, edit, or delete a webhook. * Deleting a webhook stops event delivery immediately and cannot be undone. Admins can also list, create, and update webhooks and set or rotate signing secrets by chatting with Copilot. See [Configure your workspace with Copilot](/documentation/automate/copilot/configure-workspace#outbound-webhooks). Deleting a webhook is only available here in workspace settings. *** ## Categories Organize workspaces and content with categories. **Category management:** * Create categories for organizing tickets * Assign tickets to categories * Use categories for filtering and agent routing * Set category colors, descriptions, and example utterances * Add categories from templates Learn about categories in Categories. # Approvals Source: https://docs.ravenna.ai/documentation/tickets/approvals/overview Require structured approval on tickets before work proceeds, with flexible policies, multi-stage rounds, and notifications across web and Slack. Approvals let you gate ticket progress behind one or more approval decisions. Add approvers to a ticket, choose a policy that determines when the approval is satisfied, and track the outcome across web and Slack. Approvals use a rounds-based system where each round has its own approvers and policy. Rounds are grouped into stages that run in order, and rounds inside the same stage run in parallel. A single round covers simple use cases, sequential stages support multi-step workflows like manager approval followed by security review, and grouping rounds into one stage lets independent approvers act at the same time. *** ## How approvals work When you add approvers to a ticket, Ravenna creates an approval round and notifies each approver. The round stays active until the policy is satisfied or an approver declines. Each round uses one of these policies to determine when it completes: * **Any can approve**: The round is approved as soon as any single approver approves. If any approver declines, the round is declined. * **All must approve**: Every approver must approve. If any approver declines, the round is declined. * **Threshold**: A specific number of approvers must approve (for example, 2 out of 5). The round is declined if it becomes mathematically impossible to reach the threshold. The ticket itself tracks an overall approval status based on the progress of its rounds: * **In progress**: At least one round is active or pending * **Approved**: All rounds completed successfully * **Declined**: A round was declined by an approver * **Force approved**: An admin approved the ticket, bypassing remaining rounds Each round moves through these states: 1. **Not started**: The round is created but waiting for a previous stage to complete 2. **In progress**: The round is active and awaiting approver decisions 3. **Approved**: The round's policy was satisfied 4. **Declined**: An approver declined the round Rounds inside the same stage activate together, and the next stage only starts once every round in the current stage is decided. When the final stage is approved, the ticket's approval status changes to **Approved**. *** ## Where to approve and decline Approvers can act on approval requests from multiple surfaces. When added as an approver, you receive notifications with action buttons. Open the ticket detail page and use the **Approve** or **Decline** buttons in the approval rounds section. When declining, you can provide an optional reason. Approval requests are delivered as Adaptive Cards in the approver's Microsoft Teams chat. The card includes an **Approve** and **Decline** action. Approval updates are also posted into the ticket's connected Teams channel thread. Learn more about [Microsoft Teams approvals](/integrations/microsoft-teams/approvals) Approvers receive a DM with the ticket details and approval buttons. You can approve or decline directly from the message. If your workspace requires biometric verification, the buttons redirect you to the Admin to verify your identity before completing the action. Approval updates are also posted to the ticket's Slack thread so the team stays informed. *** ## Adding approvers Add approvers to tickets from several places: * **Ticket sidebar**: Use the Approvers field to search and add users or user groups * **Approvals section**: Click **Add round** to create a new round with approvers and a policy * **Workflows**: Use the **Add Approvers** action to assign approvers automatically based on conditions * **Approval templates**: Import a pre-configured set of rounds and approvers When you select a user group as an approver, the group is automatically expanded into individual users when saved. Only the individual users are stored as approvers on the round. *** ## Admin actions Workspace admins have additional controls for managing approvals on tickets. Approve a ticket immediately, bypassing any remaining rounds. All pending and active rounds are marked as approved. Use this when a ticket needs to proceed urgently regardless of the normal approval process. Restart the approval process. Existing rounds are archived and new rounds are created. Approvers are re-notified and must approve again. You can change the policy or approvers during a reset. You can reset individual rounds or the entire approval process. *** ## Workspace settings Configure approval behavior for your workspace in **Settings** > **Workspace**. Allow workspace admins to approve tickets on behalf of other users. Enabled by default. Control whether the ticket requester can be added as an approver on their own request. When off (the default), the requester is removed from every approval round, even when they would otherwise be pulled in through an approver group. The rule applies uniformly across the ticket sidebar, approval rounds UI, workflows, and forms. When on, the requester can be added as an approver like anyone else. Require approvers to verify their identity with a passkey (Touch ID, Face ID, or security key) before approving or declining. When enabled, Slack approval buttons redirect to the Admin for verification. Approvers register passkeys in **Settings** > **Account** > **Passkeys**. *** ## Approval reminders Automatically nudge approvers who have not yet responded by configuring an organization-wide reminder cadence. When enabled, Ravenna posts a public ticket message that @mentions every pending approver on each interval until the round resolves or the maximum reminder count is reached. Learn how to configure cadence, business-hours behavior, and escalation in [reminders](/documentation/tickets/reminders). *** ## Approvals in workflows Use workflow actions to automate approval processes: * **Add Approvers**: Adds approvers to a ticket and creates an approval round. Supports assignment strategies (All, Round Robin, Auto). * **Wait for Approval**: Pauses the workflow until the approval round completes or the configured timeout expires (default 3 days). Continues down the On Approved, On Declined, or On Timeout path. * **Ticket Approval trigger**: Fires when a ticket's approval status changes, letting you trigger follow-up actions after approval or handle declined requests. Learn more about [approval workflow actions](/documentation/automate/workflows/triggers-actions) ## Mental model Approvals are a structured gate on ticket progress. A ticket can have zero or more approval rounds, each with its own policy and set of approvers. Rounds are grouped into stages by their `stageIndex`. Stages execute in order, and rounds sharing the active stage's `stageIndex` execute together. The ticket tracks an overall approval status derived from the state of its rounds. Key entities: | Entity | Purpose | Cardinality | | -------------------------- | ----------------------------------------------------------------------------- | ------------------------- | | **Ticket approval status** | Overall ticket-level status (In Progress, Approved, Declined, Force Approved) | One per ticket (nullable) | | **Approval round** | A single stage with a policy and approvers | Zero or many per ticket | | **Round approver** | A user assigned to approve within a round | One or many per round | *** ## Approval policies | Policy | Approved when | Declined when | | ------------- | ---------------------------------- | ------------------------------- | | **ANY** | Any single approver approves | Any approver declines | | **ALL** | Every approver approves | Any approver declines | | **THRESHOLD** | N approvers approve (configurable) | Impossible to reach N approvals | *** ## Round status flow ```text theme={"system"} PENDING → ACTIVE → APPROVED → (next round activates or ticket approved) → DECLINED → (ticket declined) → RESET → (new replacement round created) ``` * **PENDING**: Waiting for a previous round to complete * **ACTIVE**: Awaiting approver decisions * **APPROVED**: Policy satisfied * **DECLINED**: Approver declined * **RESET**: Admin reset the round (archived, replaced by a new round) * **SKIPPED**: Round was bypassed *** ## Ticket approval status | Status | Meaning | | ------------------- | ------------------------------ | | **IN\_PROGRESS** | Active or pending rounds exist | | **APPROVED** | All rounds approved | | **DECLINED** | A round was declined | | **FORCE\_APPROVED** | Admin bypassed all rounds | *** ## Round sequencing Rounds are ordered by `stageIndex`. Rounds sharing a `stageIndex` run in parallel (the same stage); the system activates the lowest unfinished stage. When every round in the active stage is approved, the next stage activates automatically. When the final stage is approved, the ticket's `approvalStatus` is set to APPROVED. *** ## Adding approvers Approvers can be added through: * Ticket sidebar (creates/updates the focused round) * Approval rounds UI (explicit round management) * Workflow "Add Approvers" action (creates round at head of chain) * Approval templates (creates full round chain from template) * Forms (adds approvers to active round or creates new one) When user groups are selected, they are expanded to individual users server-side. Only concrete users are stored as round approvers. *** ## Admin operations * **Force approve**: Sets all non-approved rounds to APPROVED, sets ticket status to FORCE\_APPROVED. Requires workspace admin. * **Reset round**: Archives the round (status = RESET), creates a new replacement round with `resetFromRoundId` link. Can change policy and approvers. * **Reset approval**: Resets all rounds, restarts the process from the beginning. *** ## Notifications Approvers are notified through: * **Slack DM**: Always sent, bypasses notification preferences. Includes approval action buttons. * **Microsoft Teams Adaptive Card**: Always delivered to the approver's chat, bypasses notification preferences. Includes **Approve** and **Decline** actions. * **Slack thread**: Batched @mentions posted to the ticket thread (5-second batching window). * **Microsoft Teams channel thread**: Approval updates posted into the ticket's connected Teams channel. * **Email**: Configurable notification for pending approvals. Events dispatched: `APPROVAL_ROUND_APPROVER_ADDED`, `APPROVAL_ROUND_APPROVER_REMOVED`, `APPROVAL_ROUND_APPROVER_APPROVED`, `APPROVAL_ROUND_APPROVER_DECLINED`, `TICKET_APPROVAL_COMPLETED`, `TICKET_APPROVAL_RESET`, `APPROVAL_ROUND_STARTED`. *** ## Constraints and gotchas * A ticket can have multiple rounds, but only one stage is ACTIVE at a time. Rounds sharing that stage's `stageIndex` are active together. * Removing approvers from an active round triggers immediate policy re-evaluation. If remaining approvers already satisfy the policy, the round auto-completes. * User groups are expanded to individual users at save time, not at evaluation time. * Unless the workspace enables **Allow requester as approver**, the ticket requester is stripped from approvers on every persist path (sidebar, rounds UI, workflows, forms). Group expansion happens first, so a requester pulled in through a group is still removed. * Force approve requires workspace admin privileges. * Reset preserves history by archiving the old round (RESET status) rather than deleting it. * Biometric verification (when enabled) forces Slack approval buttons to redirect to the Admin. * Approval DMs in Slack always send regardless of user notification preferences. # Approval rounds Source: https://docs.ravenna.ai/documentation/tickets/approvals/rounds Create and manage approval rounds on tickets with configurable policies, threshold rules, sequential or parallel stages, approver management, and admin controls. Approval rounds are the building blocks of ticket approvals. Each round defines a set of approvers and a policy that determines when the round is complete. Add a single round for simple approvals, chain multiple rounds for multi-stage workflows, or group rounds into a stage so they run in parallel. *** ## Create approval rounds Navigate to the ticket that needs approval. Find the **Approvals** section in the ticket detail page. Click **Add round** to open the round editor. For each round, set: * **Name**: A descriptive label (for example, "Manager approval" or "Security review") * **Policy**: Choose **Any can approve**, **All must approve**, or **Threshold** * **Threshold** (if using threshold policy): The number of approvers required * **Approvers**: Select users or user groups who can approve this round Click **Add round** again to add additional stages. Rounds run in the order you create them by default. To have two or more rounds run at the same time, drag one round onto another to group them into a single stage. Save your rounds. The first stage activates immediately and every approver in it is notified. You can add multiple rounds at once before saving. The round editor lets you configure all rounds in a single view. *** ## Run rounds in parallel Group two or more rounds into a single stage so they run side by side. Every round in the stage activates together, and the next stage only starts once every round in the current one is decided. Use this when a request needs sign-off from independent approvers who do not need to wait on each other, for example a manager approval alongside a security review. Click **Edit** in the Approvals section to open the multi-round editor. Drag one round onto another. The two rounds merge into a single stage and a small inline indicator on each round name shows which rounds are running in parallel. Click the unlink icon on a grouped round to move it back into its own stage. Rounds that are already active or terminal are locked in place and cannot be regrouped. Each round in a parallel stage still enforces its own policy independently. A stage is only approved once every round in it is approved, and a decline in any round declines the ticket. *** ## Edit approval rounds Edit rounds to change policies, add or remove approvers, or reorder stages. Click the **Edit** button in the Approvals section to open the multi-round editor. Modify round names, policies, thresholds, or approver lists. You can also add new rounds or remove existing ones. Click **Save** to apply your changes. If you remove approvers from an active round, the policy is re-evaluated immediately. Removing approvers from an active round can trigger automatic completion. If the remaining approvers already satisfy the policy (for example, one approver already approved in an "any can approve" round), the round completes immediately. *** ## Approve or decline When you are added as an approver, you receive notifications with action buttons. Click **Approve** from the ticket detail page or Slack DM. Your approval is recorded and the round policy is evaluated. If the policy is satisfied, the round completes and the next round activates. Click **Decline** and optionally provide a reason. Declining immediately completes the round with a declined status. The ticket's overall approval status changes to **Declined**. *** ## Approval policies Choose the right policy for each round based on your requirements. | Policy | How it works | Best for | | -------------------- | ------------------------------------------------------------- | ------------------------------------------------------ | | **Any can approve** | First approver to approve completes the round | Quick approvals where any authorized person can decide | | **All must approve** | Every approver must approve before the round completes | Sensitive decisions requiring consensus | | **Threshold** | A specific number of approvals required (for example, 2 of 5) | Committee-style reviews with quorum requirements | *** ## Multi-stage approvals Chain rounds for workflows that require multiple levels of approval. Rounds run in the order you add them, and you can group rounds into a stage to run them in parallel. **Example: Software access request** | Stage | Round | Policy | Approvers | Runs | | ----- | ------------------ | ---------------- | ------------------- | -------------------------------- | | 1 | Manager approval | Any can approve | Requester's manager | Alone | | 2 | Security review | All must approve | Security team | In parallel with IT prep | | 2 | IT prep | Any can approve | IT administrators | In parallel with Security review | | 3 | Executive sign-off | Any can approve | Department head | Alone | Stage 2 only starts after Stage 1 is approved. Security review and IT prep run at the same time, and Stage 3 only starts once both are approved. If any round is declined, the process stops and the ticket is marked as declined. *** ## Reset rounds Workspace admins can reset rounds when approvals need to be reconsidered. Reset one round to restart it with the same or different configuration. The original round is archived and a new replacement round is created. You can change the policy and approvers during the reset. Existing approvers are re-notified and must approve again. Reset the entire approval process. All rounds are archived and recreated from scratch. The ticket's approval status returns to **In progress**. *** ## Sidebar approver management The ticket sidebar provides a simplified view for managing approvers on the focused round (the currently active or most relevant round). * **Add approvers**: Search for users or groups in the sidebar Approvers field * **Remove approvers**: Click the remove button next to an approver's name * **Auto-creation**: If no rounds exist when you add approvers through the sidebar, a round is created automatically with the "Any can approve" policy The sidebar always shows the most relevant round: the active round if one exists, the most recently declined round, or the first pending round. ## Mental model Approval rounds are grouped into stages on a ticket, ordered by `stageIndex`. Each round has a policy, a set of approvers, and a status. Rounds sharing a `stageIndex` run in parallel as one stage. Ravenna evaluates each round's policy after every approver action, and advances to the next stage once every round in the active stage is terminal. *** ## Round data model | Field | Type | Description | | ------------------ | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | String (nullable) | Display name for the round | | `policy` | ANY, ALL, MAJORITY, THRESHOLD | Determines completion criteria | | `status` | PENDING, ACTIVE, APPROVED, DECLINED, RESET, SKIPPED | Current round state | | `threshold` | Integer (nullable) | Required approval count for THRESHOLD policy | | `stageIndex` | Integer | Ordering position; rounds sharing a value run in parallel | | `filterGroups` | Ticket condition filter (nullable) | Snapshotted from the template round at apply time. If the conditions match against the ticket, the round is created with status `SKIPPED` and never activates. | | `resetFromRoundId` | String (nullable) | Links to the round this replaced (after reset) | | `openedAt` | DateTime (nullable) | When the round was activated | | `closedAt` | DateTime (nullable) | When the round completed | *** ## Approver data model | Field | Type | Description | | ------------- | --------------------------- | -------------------------- | | `userId` | String | The approver's user ID | | `status` | PENDING, APPROVED, DECLINED | Approver's decision status | | `reason` | String (nullable) | Decline reason | | `completedAt` | DateTime (nullable) | When the decision was made | | `deletedAt` | DateTime (nullable) | Soft delete timestamp | *** ## Policy evaluation logic Policy evaluation happens after each approver action (approve, decline, or remove): **ANY policy:** * At least one APPROVED approver → round APPROVED * Any DECLINED approver → round DECLINED **ALL policy:** * All approvers APPROVED → round APPROVED * Any DECLINED approver → round DECLINED **MAJORITY policy:** * More than half of approvers APPROVED → round APPROVED * Any DECLINED approver → round DECLINED **THRESHOLD policy:** * N or more APPROVED approvers → round APPROVED * Impossible to reach N (remaining pending + already approved \< threshold) → round DECLINED After round completion: * If other rounds in the same `stageIndex` are still ACTIVE → wait for them; the stage is not yet settled. * If every round in the active stage is terminal and all were APPROVED → activate every round in the next `stageIndex` together (set each to ACTIVE, set `openedAt`). * If every round is terminal and any were DECLINED → set ticket `approvalStatus` to DECLINED. * If no later stage exists → set ticket `approvalStatus` to APPROVED or DECLINED based on the stage outcome. Two rounds in the same parallel stage can settle at nearly the same time. Ravenna serializes the "is the whole ticket done" check with a per-ticket lock so only one settlement path finalizes the ticket. *** ## Sidebar focus logic The sidebar shows the "focused" round, determined by priority: 1. Active round (status = ACTIVE) 2. Most recently declined round 3. Last round if all are approved 4. First pending round When approvers are added via the sidebar with no existing rounds, the system auto-creates a round with ANY policy. *** ## Reset behavior **Single round reset:** 1. Original round status set to RESET 2. New round created with `resetFromRoundId` pointing to the original 3. New round is inserted at the same `stageIndex` as the original 4. New round is set to ACTIVE 5. Carried-over approvers are re-notified **Full approval reset:** 1. All non-reset rounds are archived (status = RESET) 2. New rounds created matching the original stage layout (including any parallel groupings) 3. Every round in the first stage is activated, ticket status set to IN\_PROGRESS *** ## Workflow integration The "Add Approvers" workflow action creates a round at the **head** of the linked list: * If rounds already exist: new round becomes the first round, ticket status resets to IN\_PROGRESS * If no rounds: creates round and kicks off approval * Supports assignment strategies: All (all users), Round Robin (one user), Auto (system bot auto-approves) The "Wait for Approval" action pauses until the ticket's approval status changes from IN\_PROGRESS or the configured timeout (default 3 days) expires. The action branches into three outcome paths — On Approved, On Declined, and On Timeout — so workflows can escalate or auto-close stalled approvals. *** ## Constraints and gotchas * Only one stage is ACTIVE at a time. Rounds sharing that stage's `stageIndex` are active together. * The next stage does not activate until every round in the current stage is terminal, even in the parallel case. * Rounds require at least one approver. * Removing the last approver from a round deletes the round (via sidebar). * Removing approvers triggers immediate policy re-evaluation, which can auto-complete the round. * The same approver appearing in more than one round in a parallel stage is notified once per stage kickoff, not once per round. * Reset preserves audit history. Reset rounds (status = RESET) are hidden from the UI but remain in the database. * Round ordering is stored via the `stageIndex` field. Rounds sharing a `stageIndex` run in parallel. * Reopening a declined ticket by syncing in a new round in a later stage advances correctly past the declined stage without re-approving it. * `sourceTemplateRoundId` tracks which template round generated each ticket round (for lineage). * Rounds created from a template can enter status `SKIPPED` at apply time when their snapshotted `filterGroups` match the ticket. Skipped rounds never activate, do not notify approvers, and are treated as terminal for stage advancement. See [Skip conditions](/documentation/tickets/approvals/templates#skip-conditions) on approval templates for how to configure this. # Approval templates Source: https://docs.ravenna.ai/documentation/tickets/approvals/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. *** ## Create a template Go to **Settings** > **Approval Templates** in your workspace. Click **New Template** to open the template form. 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. Configure one or more approval rounds. For each round, set: * **Policy**: Select **Any can approve** or **All must approve** * **Approvers**: Select users or user groups who should approve this round * **Skip conditions** (optional): Attach a ticket condition filter that determines whether the round runs. If the conditions do not match at the time the template is applied, the round is skipped instead of requesting approval. See [Skip conditions](#skip-conditions) below. To have rounds run in parallel, drag one round onto another to group them into a single stage. See [approval rounds](/documentation/tickets/approvals/rounds#run-rounds-in-parallel) for how stages work. Click **Save** to create the template. It becomes available for import on tickets in the selected workspaces. *** ## Apply a template to a ticket Navigate to the ticket that needs approval. In the **Approvals** section, click the import button and select a template from the list. The template's rounds and approvers are applied to the ticket. The first round activates immediately and approvers are notified. Importing a template replaces any existing approval rounds on the ticket. Make sure you want to overwrite the current approval configuration before importing. *** ## Skip conditions Each template round can carry a set of skip conditions built from ticket fields. When the template is applied to a ticket, Ravenna evaluates the round's conditions against that ticket. If the conditions match, the round is marked **Skipped** instead of activating, and the approval process continues with the next round. Use skip conditions when a single template needs to cover branching approval flows. For example, a purchase template can include a Finance sign-off round with the condition `amount > $5,000` — tickets under that threshold skip the Finance round automatically, while tickets over it still require the extra approval. In the template form, expand the round you want to make conditional. Click **Add skip condition set** and pick a ticket field, an operator, and a value. Add more conditions to require multiple matches, or add another set to skip when any set matches. Save the template. The next time it is applied to a ticket, each round's conditions are evaluated against that ticket and matching rounds are skipped. Skip conditions are evaluated once, when the template is applied. Changing the ticket after the round is created does not retroactively skip or unskip it. A round with no skip conditions always runs, matching the previous behavior. If every round in a template is skipped for a given ticket, the ticket's approval status is set to **Approved** automatically. *** ## 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. Resolves to the person who submitted the ticket. Useful for self-approval steps or acknowledgment rounds. 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. Resolves strictly two levels up the manager hierarchy: requester → manager → manager's manager. Ravenna first resolves the requester's direct manager using the same cascade as **Requester's manager** (app-scoped integration, then organization-wide HRIS, then the identity provider), and then applies the same cascade again to resolve that manager's manager. Skip-level resolution is deliberately strict about who counts as the approver: * If the requester has no direct manager in any source, the skip-level role has nobody to escalate from and is unresolved. * If the direct manager resolves but that manager has no manager of their own in any source, the skip-level role is again unresolved. Ravenna does **not** fall back to the direct manager. Use this role for second-level sign-off (for example, a VP or department head reviewing after a direct manager) where routing to the direct manager would defeat the purpose of the escalation. 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. **Requester's manager** and **Requester's skip-level manager** are the exceptions: when either role would resolve to nobody, Ravenna substitutes the ticket's workspace admins as the approvers for that slot so the round is never left without an approver. The skip-level fallback still respects the two-level rule during resolution itself — Ravenna never substitutes the direct manager for a missing skip-level manager. *** ## 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 A single-round template for basic manager sign-off. | Round | Policy | Approvers | | -------------- | --------------- | ------------------- | | Manager review | Any can approve | Requester's manager | 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 | 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 | ## 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, stageIndex, approvers, approverGroups, roleBasedApprovers, filterGroups | A round within the template. Rounds sharing a `stageIndex` run in parallel when the template is applied. `filterGroups` holds an optional ticket condition filter — when it matches at apply time, the resulting ticket round is created with status `SKIPPED` instead of activating. | 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` (code identifier `manager_id`) - 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. * `requester_skip_level_manager` (code identifier `skip_level_manager_id`) - Resolves strictly two levels up the manager hierarchy (requester → manager → manager's manager). Each level uses the same cascade as `requester_manager` (app-scoped integration → HRIS → identity provider). If either the direct manager or the skip-level manager cannot be resolved, the slot falls back to the ticket's workspace admins. Ravenna never substitutes the direct manager when a skip-level manager is missing. * `access_level_owners` - Resolves to owners from the access level (access request workflows) Resolution happens in `resolveTemplateRoundApprovers()`. If a role other than `requester_manager` or `requester_skip_level_manager` cannot be resolved, the approver slot is silently skipped. Those two manager roles are the only ones with a workspace-admin safety net. *** ## Apply template process 1. Delete all existing non-reset rounds on the ticket 2. For each template round (ordered by `stageIndex`): a. Resolve dynamic approvers (role-based + group expansion) b. Snapshot the template round's `filterGroups` onto the ticket round (or `null` if unset) c. Evaluate `filterGroups` against the ticket's hydrated field values. If they match, create the ticket round with status `SKIPPED`; otherwise create it as normal. d. Create `TicketApprovalRound` with `sourceTemplateRoundId` link e. Copy the template round's `stageIndex` onto the ticket round 3. Kickoff: activate every non-skipped round in the lowest `stageIndex` that still has a non-skipped round, set ticket approval status to IN\_PROGRESS. If every round produced by the template is `SKIPPED`, set the ticket's `approvalStatus` to APPROVED and record `approvalCompletedAt` instead of activating anything. 4. Dispatch notifications to all approvers in the first activated stage, deduping approvers who appear in more than one round of that stage *** ## 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** | `stageIndex` integer field (rounds sharing a value run in parallel) | `stageIndex` integer field (copied from the template) | | **Lifecycle** | Static blueprint | Active lifecycle with status transitions | | **Lineage** | Source | Links back via `sourceTemplateRoundId` | | **Skip conditions** | `filterGroups` (ticket condition filter) | Snapshotted `filterGroups`; evaluated once at apply time to decide `SKIPPED` vs `PENDING`/`ACTIVE` | *** ## 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` or `requester_skip_level_manager`. In those cases, the ticket's workspace admins are substituted as approvers so the round can proceed. The fallback is limited to those two manager roles: it does not apply to `ticket_requester` or `access_level_owners`, 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. * `requester_skip_level_manager` is strictly two levels up. If the requester's direct manager cannot be found, or the direct manager has no manager of their own, the role goes unresolved (before the workspace-admin fallback kicks in). Ravenna never substitutes the direct manager for a missing skip-level manager. * Templates with the THRESHOLD policy are supported in the template round configuration. * `filterGroups` on a template round is snapshotted onto the ticket round at apply time. It is evaluated once against the ticket's hydrated fields; matching conditions produce a `SKIPPED` ticket round rather than blocking approval. Later changes to the ticket do not re-evaluate an already-created round. * If every round in the template resolves to `SKIPPED` for a given ticket, the ticket's `approvalStatus` is set to `APPROVED` and `approvalCompletedAt` is stamped — the ticket is not left in `IN_PROGRESS` with no active round. * In a parallel stage, only the non-skipped rounds are activated. If every round sharing that `stageIndex` is skipped, the stage is treated as settled and Ravenna advances to the next stage. # Attachments Source: https://docs.ravenna.ai/documentation/tickets/attachments Add files to tickets, preview images, video, PDFs, audio, and text inline, and download all attachments on a message as a zip. Attachments let you share files on a ticket. Files appear as tiles that are visible to everyone with access to the ticket across Admin, Slack, email, and the Portal. You can add files to a message, to the ticket description, or through a form. *** ## Add files to a message Add files from the message compose box in three ways: * **Paperclip button** - Select the paperclip icon in the compose toolbar to open your file picker. You can select multiple files at once, and any file type is accepted. * **Drag and drop** - Drag files from your desktop onto the compose area. A drop overlay appears while you drag. * **Paste** - Paste a file or screenshot straight from your clipboard into the message editor. Each file uploads as soon as you add it. A spinner on the tile shows the upload in progress, and the send button stays disabled until every upload finishes. Files added here become attachments on that message. Each file can be up to 100 MB. There is no limit on the number of files per message. *** ## Add files to the ticket description Attach files directly to a ticket from the description area on the ticket detail view. There is no separate widget, the whole description area is a drop target: * **Drag and drop** - Drag files onto the description. A drop overlay appears while you drag. * **Paste** - Paste a file or screenshot into the description editor. Files uploaded this way are ticket-level attachments. They appear as tiles directly below the description text, separate from any message attachments. *** ## Collect files with a form Forms can gather files from requesters at submission time. There are two field options in the [form builder](/documentation/tickets/forms/overview): * **Attachments** - A built-in system field. Add it from the **System** tab in the form builder's field picker. Files submitted through it become ticket-level attachments, shown in the description area. * **File Picker** - A custom field. Add it from the **File** category in the **Create** tab. You can set a **Label**, optional **Description**, whether the field is **Required**, and which **Accepted file types** are allowed (documents, spreadsheets, images, audio, video, archives, and more). Leave file types unset to accept any type. Files submitted through it are stored on the custom field and shown in the ticket's custom fields panel. Requesters upload to either field by dragging files onto it or selecting it to open a file picker. Learn more about [form custom fields](/documentation/tickets/forms/custom-fields) *** ## Preview attachments Select an attachment to open it in a preview with a header, the filename, and a one-click download button. Preview behavior depends on the file type: | Type | Behavior | | --------------------------------------- | -------------------------------------------------- | | Images (jpg, jpeg, png, gif, svg, webp) | Render full size inline; select to open fullscreen | | Video (mp4, mov, webm, avi, wmv, mkv) | Play inline with player controls | | PDF | Opens in the preview modal | | Audio (mp3, wav, ogg, flac) | Plays in a compact audio player in the preview | | Text (txt, csv, log, md, json) | Renders the file contents in the preview | File types that aren't supported for preview (including HEIC and HEIF photos from iPhones) show a "can't be previewed here" message. You can still download them with the download button. *** ## Download all attachments When a message has more than one attachment, open the message **...** menu and select **Download all attachments**. Ravenna packages every file on the message into a single zip (`message--attachments.zip`). A progress toast shows the download and lets you cancel it. If two files share the same name, Ravenna disambiguates them automatically (for example, `report.pdf` and `report (1).pdf`). *** ## Attachments across channels Attachments stay in sync wherever a ticket is visible: * **Slack** - Files mirror to the request thread, the triage thread, and relevant direct message threads. * **Email** - Attachments on inbound emails appear on the ticket alongside other files. * **Portal** - Requesters see message attachments when they view their tickets in the [Portal](/documentation/platform/portal). An attachment sent by a user in Slack stays owned by Slack. Editing or deleting it in Ravenna is not reflected back in Slack. # Channels Source: https://docs.ravenna.ai/documentation/tickets/channels Channels organize tickets by team, topic, or workflow with their own ticket prefix, settings, integrations, and routing rules in each workspace. Channels organize tickets by team, topic, or workflow. Every ticket belongs to a channel, and each channel functions as a dedicated container with its own: * **Prefix** - Appears in ticket numbers (e.g., `HELP-123`) * **Settings** - Controls ticket creation, automation, and notifications * **Integrations** - Connects to Slack, email, forms, and external systems * **Routing rules** - Determines which tickets land in the channel Use channels to separate work by team (Engineering, Support), topic (Bugs, Features), or workflow stage. *** ## Create a channel In your left sidebar, click the **+** button next to Channels. Add an emoji, name, and prefix. The prefix appears in ticket numbers (e.g., `HELP-123`). Click **Create** to save the channel. Every workspace includes a **Slack** system channel that is always visible and receives tickets created from Slack when no specific channel applies. New workspaces also include **Web**, the default channel that you can customize. *** ## Channel settings Access channel settings by selecting a channel and clicking **Settings**. Connect an agent to handle interactions in connected Slack channels. Agents can answer questions, create tickets, and apply rules you configure. Create agents in **Settings > Agents** before connecting them to channels. Connect Slack channels as sources for tickets. Multiple Slack channels can connect to a single Ravenna channel. Configure how tickets are created and managed in Slack. **Auto create tickets** Automatically create tickets for all messages in connected Slack channels. Thread replies update the parent ticket. **Ignore workspace members** Skip ticket creation for messages from workspace members. Requires auto create tickets to be enabled. **Send all tickets to triage channel** Automatically send tickets created in this channel to your triage channel. **Silent mode** Prevent ticket mirrors from appearing in request Slack channels. **AI tags** Automatically extract and apply tags to tickets based on message content. **System emojis** Send system emoji updates to Slack when ticket actions occur. **CSATs** Send CSATs when tickets are resolved. **Ticket events** Send Slack messages for ticket updates including priority, tags, due date, form, snooze, channel, and starred changes. Requires silent mode to be disabled. **Public ticket actions** Send action buttons in request Slack channels for all users, including non-workspace members. **Public emoji actions** Allow all users to trigger actions with emoji reactions. Enable your channel to receive emails and convert them into tickets. Each channel gets a unique email address in the format `PREFIX+CHANNEL_ID@mail.ravenna.ai`. The **Email** tab is split into two sections: * **Inbound** - Controls which emails become tickets. Configure guest users, forwarded requester extraction, bounce handling, blocked senders, and sender allow lists. * **Outbound** - Controls the replies and notifications the channel sends. Configure blocked recipients, agent email masking, sender name, and the email footer. Learn more about [Email integration](/integrations/email/overview) for complete setup instructions and features Associate forms with your channel. Connected forms appear as options when creating tickets in the channel. Connect knowledge bases to provide AI agents with context for answering questions. Configure bidirectional synchronization between Ravenna and external ticketing systems. Ticket replication keeps tickets in sync across platforms with automatic updates to comments, status changes, and ticket details. **Supported integrations:** * [Jira](/integrations/jira/ticket-replication) - Jira Software, Work Management, and Service Management * [Linear](/integrations/linear/ticket-replication) - Issue tracking and project management Install and configure the integration in Settings > Integrations. Open **Ticket Replication** in channel settings. Enable replication for your connected integration. Click **Configure** to set channel-specific mapping and preferences. Select replication directions (Ravenna → External, External → Ravenna). Learn more about each integration's ticket replication capabilities in their documentation *** ## Hide channels from your sidebar You can hide any channel from your own sidebar without affecting other workspace members. Hiding is a personal preference: other members still see the channel, ticket routing continues to work, and every ticket in the channel remains accessible from URLs, search, and views. To hide a channel, right-click it in the sidebar (or open its menu) and select **Hide**. The channel moves into a collapsible **Hidden** group at the bottom of the Channels section. Expand **Hidden**, then right-click a channel there and select **Unhide** to restore it to its previous position. Use this to declutter your sidebar when your workspace has channels you don't work in day-to-day. *** ## Move tickets between channels Select one or more tickets from the ticket list. Click **Move** from the bulk actions menu or individual ticket menu. Select the target channel and optionally update other properties. Click **Move** to transfer the tickets. *** ## Share tickets across channels Share tickets across multiple channels for cross-team collaboration: * The ticket appears in all shared channels * All team members in shared channels can view and update the ticket * Changes made in any channel are reflected everywhere * The original channel maintains ownership Use ticket sharing for cross-team collaboration and ticket links for related but separate tickets. *** ## Ticket routing Ravenna routes tickets using this priority order: If a form specifies a default channel, the ticket routes there. If the source Slack channel is connected to a specific channel, the ticket routes there. Tickets created from Slack without a specific channel, such as direct messages, shortcuts, and modals, route to the workspace's **Slack** channel. The workspace's default channel is used as a fallback for everything else. Set a default channel in **Settings > Workspace > General**. *** ## Delete a channel Navigate to the channel you want to delete and click **Settings**. Scroll to the bottom and click **Delete Channel**. Select a destination channel to move all existing tickets from the channel you're deleting. Confirm the deletion. All tickets will be moved to the selected channel and the original channel will be deleted. This action cannot be undone. All tickets will be permanently moved to the destination channel. ## Mental model A channel is the primary organizational unit for tickets within a workspace. Every ticket belongs to exactly one channel at any given time (though tickets can be shared to additional channels for visibility). A workspace contains one or more channels. Channels map to how teams divide their work. The relationship hierarchy is: Organization > Workspace > Channel > Ticket. Key relationships: * One workspace has many channels. * One channel has many tickets. * One channel can connect to many Slack channels (for ticket creation). * One channel can connect to one AI agent. * One channel can associate with many forms and knowledge bases. * A ticket's prefix comes from its channel (e.g., channel prefix "HELP" produces ticket numbers like HELP-123). *** ## Channel design patterns There are three common approaches to structuring channels within a workspace: | Strategy | Example channels | Best for | | --------------- | ----------------------------------------- | -------------------------------------------------------- | | **By team** | Engineering Support, Design Requests | Workspaces serving multiple internal teams | | **By topic** | Hardware, Software Access, Account Issues | High-volume workspaces where categorization helps triage | | **By workflow** | Approvals, Incidents, General Requests | Workspaces with distinct ticket lifecycles per type | Most workspaces start with a single general channel and add more as volume grows and patterns emerge. Over-segmenting into too many channels creates confusion and routing complexity. When a workspace handles requests that follow fundamentally different processes (e.g., quick questions vs. multi-step approvals), separate channels make sense. When the difference is just categorization, use categories or tags within a single channel instead. *** ## Routing priority When a ticket is created, Ravenna determines which channel it belongs to using this priority order: 1. **Form default channel** - If the form used to create the ticket specifies a default channel, the ticket routes there. 2. **Slack channel connection** - If the Slack channel where the message was posted is connected to a specific Ravenna channel, the ticket routes there. 3. **Slack system channel** - Tickets created from Slack without a specific channel route to the workspace's **Slack** channel. 4. **Workspace default channel** - The workspace's configured default channel catches everything else. This means form configuration takes precedence over Slack channel mapping, which takes precedence over the Slack system channel and the workspace default. When designing channel routing, set up form defaults for structured intake paths and Slack connections for organic message-based ticket creation. *** ## Configuration patterns Different channel use cases call for different setting combinations: **Agent-handled support channel (e.g., IT Help Desk):** * Auto create tickets: disabled (the agent handles messages first and creates tickets when needed) * AI agent: connected * Send to triage: enabled * CSATs: enabled **Auto-create channel (every message becomes a ticket):** * Auto create tickets: enabled * Ignore workspace members: enabled (so internal replies do not create tickets) * AI agent: not connected (auto-create bypasses agent processing) * Send to triage: enabled **Backend processing channel (e.g., Approvals, Provisioning):** * Silent mode: enabled (no mirrors in Slack) * Auto create tickets: disabled (tickets arrive via forms or workflows) * Ticket replication: enabled if syncing to Jira or Linear **Transparent team channel (e.g., Engineering Requests):** * Auto create tickets: enabled * Silent mode: disabled (mirrors visible in Slack) * Public ticket actions: enabled (requesters can update tickets directly) * Ticket events: enabled (status updates posted to Slack) *** ## Moving vs. sharing tickets Channels support two mechanisms for cross-channel collaboration: | | Move | Share | | -------------- | ------------------------------------------- | ------------------------------------------------ | | **Ownership** | Transfers to the destination channel | Stays with the original channel | | **Visibility** | Ticket appears only in the new channel | Ticket appears in all shared channels | | **Use case** | Ticket was routed to the wrong team | Multiple teams need to collaborate on one ticket | | **Prefix** | Changes to the destination channel's prefix | Keeps the original prefix | Move tickets when the original channel should no longer own the request. Share tickets when multiple teams need visibility and the ability to update the same ticket. For related but separate work items, use ticket links instead of sharing. *** ## Constraints and gotchas * Every ticket must belong to exactly one channel. There is no "unassigned" state. * Deleting a channel requires selecting a destination channel for all existing tickets. Tickets are never orphaned. * Channel prefixes appear in ticket numbers and cannot be changed after creation without recreating the channel. * Multiple Slack channels can feed into one Ravenna channel, but each Slack channel can only connect to one Ravenna channel at a time. * "Ignore workspace members" only works when "Auto create tickets" is enabled. Without auto-create, the setting has no effect. * Silent mode and ticket event notifications are mutually exclusive. Enabling silent mode prevents ticket event messages from being sent to Slack. * A channel can connect to one AI agent. To change agents, disconnect the current one first. * Each workspace member can hide channels from their own sidebar. Hidden channels move into a collapsible **Hidden** group; the preference is stored per user on the workspace member record. Hiding is purely a sidebar-rendering preference — it does not affect routing, does not affect other members' sidebars, and does not restrict access to the channel's tickets. # Due dates Source: https://docs.ravenna.ai/documentation/tickets/due-dates Set ticket due dates manually or through workflows, then track progress with filters and visual indicators to keep time-sensitive work on schedule. Due dates help manage time-sensitive tickets and ensure tasks are completed on schedule. Set deadlines manually or through workflows, then track progress with filters and visual indicators. *** ## Set due dates Set due dates directly on tickets: Navigate to the ticket you want to set a due date for. Click the due date field in ticket details. Choose the date when the ticket should be completed. The due date saves automatically. Automate due date assignment through workflows: * Set due dates based on ticket properties or conditions * Update due dates when ticket status changes * Calculate deadlines relative to ticket creation Due dates include the entire day. Tickets aren't considered overdue until the next day begins. *** ## Track due dates All due date changes are logged in ticket activity history. Visual indicators throughout the interface show approaching and overdue deadlines. ### Filter and sort Use due dates to organize your ticket list in views: * Filter by specific due date ranges * Show only overdue tickets * Find tickets due within a timeframe * Filter for tickets with no due date set using the "is empty" condition * Create saved filters for upcoming deadlines * Sort by due date to see most urgent first * Group tickets by due date ranges (overdue, due today, due this week) * Combine due date sorting with other criteria ### Visual indicators Due dates appear throughout Ravenna with: * Due date badges showing the deadline * Color coding for overdue, due soon, and future due dates * Dashboard widgets highlighting approaching deadlines *** ## Use in workflows Due dates integrate with workflow automation: * Automatically set due dates based on ticket properties * Update due dates based on ticket progress * Calculate deadlines relative to other dates * Use due dates as conditions in workflow rules * Create different processes for urgent vs routine deadlines * Route tickets based on due date proximity There is no workflow trigger that fires when a ticket's due date is approaching or has passed. To act on upcoming or overdue due dates, use a [Cron trigger](/documentation/automate/workflows/triggers-actions#scheduled-triggers) with a [Search Tickets](/documentation/automate/workflows/triggers-actions) step filtered by `dueAt`, then loop over the results to send reminders, reassign, or escalate. Learn more about [building workflows](/documentation/automate/workflows/publish) with due date automation *** ## Monitor with analytics Use due dates in analytics and reporting: * Track completion rates against due dates * Monitor overdue tickets and resolution times * Analyze team performance on deadline adherence * Identify bottlenecks causing missed deadlines * Review due date changes in ticket event history ## Mental model A due date is a deadline timestamp on a ticket. It represents when the ticket should be resolved. Due dates are a single date field (day granularity). A ticket is not considered overdue until the day after the due date. Due dates are independent of SLA timers. SLAs measure response and resolution time from ticket creation or status changes. Due dates are explicit deadlines set by users or automation. Both can exist on the same ticket and are tracked separately. *** ## Setting due dates Due dates can be set through three methods: | Method | When to use | | ------------------- | ------------------------------------------------------------------------------------------------ | | **Manual** | Agent or workspace member sets a deadline based on judgment or requester needs | | **Workflow action** | Automatically set based on ticket properties (e.g., all "Urgent" tickets get a 24-hour due date) | | **Form default** | Set during ticket creation through form configuration | Workflow-based due dates can be calculated relative to ticket creation time (e.g., "3 business days from now") or set to absolute dates based on conditions. *** ## Due dates in automation **As triggers:** Not supported. There is no workflow trigger that fires when a due date is set, changes, is approaching, or is passed. To act on upcoming or overdue due dates, use a Cron trigger with a Search Tickets step filtered by `dueAt`, then loop over the results. Setting a due date fires an internal `SET_DUE_DATE` event, but it is not exposed as a workflow trigger in the UI. **As conditions:** Use due date presence, proximity, or overdue status as branching conditions in workflows. **As actions:** Set or update due dates as part of workflow execution. Calculate deadlines relative to other dates or ticket properties. **In views:** Due dates are available as filter, sort, and grouping criteria. Common patterns include creating views for "Overdue tickets," "Due today," and "Due this week." **In analytics:** Due date adherence is trackable in analytics for measuring team performance against deadlines. *** ## Constraints and gotchas * Due dates are day-level precision. A ticket due on March 15 is not overdue until March 16. * Due dates do not automatically change ticket status. A ticket can be overdue and still show as "Open." * Due dates are independent of SLA timers. Having an SLA does not set a due date, and setting a due date does not affect SLA calculations. * All due date changes are logged in ticket activity history. * Snoozing a ticket does not pause or extend its due date. A snoozed ticket can become overdue while hidden from default views. * Due dates apply to the ticket itself, not to individual tasks within a ticket. Tasks do not have their own due dates. # Attributes Source: https://docs.ravenna.ai/documentation/tickets/forms/attributes Promote a custom field to an attribute so it appears on every ticket in the workspace, regardless of which form created the ticket. Attributes are custom fields promoted to workspace-wide status. Once a field is an attribute, it appears on every ticket in the workspace, not just tickets created through the form that owns the field. *** ## How attributes work Regular custom fields are tied to the forms they're added to, so a ticket only carries a field's value if it was created through a form that includes it. Promoting a field to an **attribute** removes that scope. The field renders on every ticket in the workspace and agents can set or update its value from the ticket detail sidebar, whether the ticket came from a form, a Slack message, an email, or anywhere else. **Example:** Turn a **Root cause** select field into an attribute so agents can categorize any ticket after the fact, including tickets created by email that never touched a form. Custom fields are workspace-specific, so an attribute exists in exactly one workspace. *** ## Eligible field types Only field types that render meaningfully outside of a form context can be attributes: * Text Input * Text Area * Date * Date & Time * Boolean * Select * Multi-Select * User Select * User Multi-Select Other field types can still be used on forms but cannot be promoted to attributes: Number, Duration, Time, File Picker, and the remaining resource pickers such as Application Select and Tag Select. **Time** is not eligible even though **Date** and **Date & Time** are. In the field list, the **Add as attribute** menu item is disabled for ineligible types and labeled **Add as attribute (unsupported field type)**. ### User attributes **User Select** and **User Multi-Select** attributes render a real people picker everywhere an attribute is editable: the ticket sidebar, the compact attribute bar, table cells, the create-ticket dialog, and workflow ticket actions. If the field defines a user allowlist, the picker only shows that subset of workspace users. Otherwise it shows every workspace user. *** ## Create an attribute You can promote an existing custom field, promote a field straight from a ticket, or create a new attribute from scratch. Go to **Settings > Workspace > Fields** and stay on the **Fields** tab. Find the field you want to promote, open its menu, and choose **Add as attribute**. If the option is disabled, the field's type is not eligible. Ravenna adds the field to the **Attributes** tab and starts showing it on every ticket in the workspace. Open any ticket and click the plus button on the **Attributes** section. The **Add a field as an attribute** menu lists every eligible field that isn't an attribute yet. Pick one and it becomes a workspace attribute immediately, without a trip to settings. If the menu shows **No eligible fields**, every eligible field is already an attribute. Create a new one from settings instead. Go to **Settings > Workspace > Fields > Attributes**. Click **New**. The create dialog is the same as the custom field dialog, but the **Type** picker only offers eligible types. Set the label, description, type, and options, then save. The new field is created and marked as an attribute in one step. *** ## Manage attributes Open **Settings > Workspace > Fields > Attributes** to see every attribute in the workspace. * **Reorder** attributes by dragging. The order controls how they appear on tickets in the workspace. * **Edit** an attribute to change its label, description, or options. Because attributes are custom fields, edits propagate to every form that also uses the field. * **Remove** an attribute to stop showing it on tickets. Removing an attribute does not delete the underlying custom field. The field stays available in the **Fields** tab and on any form that still references it. ### Removing a Select or Multi-Select option Removing an option from a **Select** or **Multi-Select** attribute (or custom field) does not blank the value on tickets that already hold it. The option is archived instead of deleted: * Tickets that already held the removed option keep displaying it, greyed out and labeled **(removed)**. Agents can clear the value, but they cannot re-select the removed option once cleared. * Removed options do not appear in pickers on new tickets or tickets that never held the value. * Ticket list filters and analytics group-by continue to offer removed options, labeled **(removed)**, so you can still find every ticket that carries the value. * The Ravenna Agent can read a removed option by name on a ticket that holds it, but cannot set a removed option on a ticket that doesn't already hold it. Attempting to do so returns `ATTRIBUTE_FIELD_VALUE_INVALID`. * Once no ticket references a removed option, Ravenna hard-deletes it during a daily cleanup sweep. Restoring a value after that requires creating a new option. To fully retire a value, remove the option and let the sweep clear it out, or edit the tickets that still hold it before removing the option. *** ## Attributes on tickets By default, attributes appear in the ticket detail sidebar alongside standard fields like status, priority, and assignee, and you can move the **Attributes** section to a tab if you prefer. Agents can set or update attribute values directly on any ticket in the workspace, and the same editor is available from the ticket create and edit modals and the ticket drawer. Attribute values are stored on the ticket and available anywhere custom field values are: * Filter and sort tickets by attribute value in views, and show attributes as table columns. Attribute columns are hidden by default, so enable the ones you want from the column picker. Sorting is available for single-value types, not multi-select. * Group and break down tickets by attribute in analytics dashboards. Group-by on a **User Multi-Select** attribute buckets by user name, so each bucket is a person rather than a raw stored id. * Reference attributes in workflow conditions and actions. * Read and set attributes in agent conversations. * Show attribute values on Slack work objects, following the same workspace setting as custom fields. * Include attributes in ticket CSV exports. For user attributes and user form fields, the export writes the user's display name, not the internal user id. *** ## Attributes on forms An attribute can also be added to a form. The submitter fills it in like any other field, but the answer is saved as the ticket's attribute value, not as a form response, so it appears in the **Attributes** section on the ticket rather than under the form's captured fields. * In the form builder, attributes appear on the **Ticket** tab alongside built-in ticket fields. They no longer show under **Shared** or **Custom**. * Hidden attributes cannot be added to forms. The form builder does not offer them and the backend rejects the attach. * On the **Create ticket** dialog, an attribute added to the selected form renders in the form's field list instead of being duplicated in the top attribute bar. Learn more about [custom fields](/documentation/tickets/forms/custom-fields), which attributes are built on top of. ## Mental model An attribute is a custom field that has been registered on a workspace. The registration lifts the field out of its form-only scope, so the field renders on every ticket in the workspace regardless of how the ticket was created. Key points: * Attributes are a per-workspace overlay on the custom field library. The custom field itself is unchanged. Adding it as an attribute is a separate join record on the workspace. * Because attributes reuse the underlying custom field, editing an attribute edits the field for every form it also appears on. * Removing an attribute detaches the field from the workspace overlay only. The field survives on any forms that still reference it. * On tickets, attribute values live in `Ticket.attributeFields`, a keyed blob separate from `Ticket.customFields`. When a form submission includes an attribute, the form submission service splits the state with `splitStateForAttributeFields` and writes the value into `attributeFields`, not into the form response. *** ## Eligible types Only these `CustomFieldType` values can be promoted to attributes: `TEXT`, `TEXT_AREA`, `DATE`, `DATETIME`, `BOOLEAN`, `SELECT`, `MULTI_SELECT`, `USER_SELECT`, `USER_MULTI_SELECT`. Other types (`NUMBER`, `DURATION`, `TIME`, `FILE_PICKER`, `APPLICATION_SELECT`, and the other resource pickers) render empty off a form context and are rejected by the API with `CUSTOM_FIELD_TYPE_NOT_ATTRIBUTE_ELIGIBLE`. `TIME` is ineligible even though `DATE` and `DATETIME` are eligible. `USER_SELECT` and `USER_MULTI_SELECT` attributes render the same people picker used for assignees. The attribute's `config.allowList` (a list of user ids) restricts the picker to that subset; without it, the picker offers every workspace user. The UI enforces this in three places: * The **Add as attribute** menu item is disabled for ineligible fields. * The **Create Attribute** dialog's type picker is filtered to eligible types only. * The plus button on a ticket's **Attributes** section only lists eligible, non-system fields that aren't attributes yet. *** ## Attributes on forms * The form builder tab formerly labeled **System** is now **Ticket**, and non-hidden attributes are listed there alongside built-in ticket fields. Attributes no longer appear under the **Shared** or **Custom** tabs. * Hidden attributes are not form-eligible. The builder hides them from every tab, and `RequestTypeCustomFieldService` rejects the attach with `HIDDEN_ATTRIBUTE_NOT_FORM_ELIGIBLE`. * When a submitter fills in an attribute on a form, the answer is stored on the ticket's `attributeFields`, not on the form response. The ticket's form response section does not list it, and the attribute card shows the value. * On the **Create ticket** dialog, an attribute that is also a field on the selected form renders once, in the form's field list. The compact attribute bar receives an `excludeAttributeCustomFieldIds` set for exactly this. * A form field that later becomes an attribute keeps its historical form-response values in place. Tickets created before the change still show blank on the attribute card until backfilled. *** ## Agent tools Copilot and MCP tools for attributes: * `search_workspace_attributes`: the discovery tool. Returns each attribute's `custom_field_id`, `label`, `type`, and (for `SELECT` / `MULTI_SELECT`) the option `id` + `value` pairs. Removed (archived) options are omitted, since they can no longer be set. Filter by `search` (case-insensitive label substring) or fetch specific ones with `attribute_ids`. IDs that don't resolve come back in `missing_ids` rather than as an error. * `list_workspace_custom_fields`: lists every custom field in the workspace and marks which ones are attributes. * `create_workspace_custom_field`: creates a field in the workspace field library, attached to no form. Pass `is_attribute: true` to mark it as an attribute in the same call, the equivalent of the Attributes tab's **New** dialog. Rejected for an ineligible type. * `create_ticket` and `update_ticket`: accept an `attributeFields` object keyed by `custom_field_id`. Value shapes match `customFields`. `SELECT` and `MULTI_SELECT` values are validated against the attribute's real options, so a hallucinated option id fails loudly instead of being stored. A removed option is only accepted when the ticket already holds it; setting it on a ticket that doesn't returns `ATTRIBUTE_FIELD_VALUE_INVALID` with a note that the option was removed. `USER_SELECT` takes a user id and `USER_MULTI_SELECT` an array of user ids; each id is checked against the organization's users and rejected with `ATTRIBUTE_FIELD_VALUE_INVALID` if it doesn't resolve. Resolve user ids with `list_users` first. * `get_ticket`: hydrates both `customFields` and `attributeFields` against the field definitions before returning, so the agent sees the current attribute values without a follow-up lookup. If a hydrated `SELECT` / `MULTI_SELECT` value points at a removed option, that option is included in `options` with `removed: true` so the agent can still read its label; other removed options are omitted. The intended flow is: call `search_workspace_attributes` to resolve label → id (and option label → option id for selects), then pass that id into `create_ticket` / `update_ticket` under `attributeFields`. *** ## API The public REST endpoints are under `/workspace-custom-fields`: | Endpoint | Method | Purpose | | ------------------------------- | ------ | --------------------------------------------- | | `/workspace-custom-fields` | GET | List attributes in the current workspace | | `/workspace-custom-fields` | POST | Promote an existing custom field to attribute | | `/workspace-custom-fields/{id}` | PUT | Reorder an attribute | | `/workspace-custom-fields/{id}` | DELETE | Remove an attribute from the workspace | POST accepts `customFieldId` and an optional `order`. The custom field must already exist in the workspace and be an eligible type. `order` defaults to one past the current highest order in the workspace. PUT accepts only `id` and `order`, so it is a reorder, not an edit. Change an attribute's label, description, or options through the custom field endpoints instead. *** ## Constraints and gotchas * Custom fields are workspace-specific, so an attribute belongs to exactly one workspace. * Removing an attribute never deletes the underlying custom field. Delete the field from **Settings > Workspace > Fields > Fields** if you want it gone entirely. * Deleting the underlying custom field cascades: the attribute registration goes with it. * Editing an attribute's label, description, or options edits the underlying custom field, so the change propagates to every form referencing it. Edits from the **Attributes** tab apply immediately with no confirmation step. * Attributes render in the order set on the **Attributes** tab. A single PUT with a new `order` is enough, since the sibling attributes are reshuffled around it server-side. * `system` custom fields are excluded from attribute filters, table columns, and exports even when registered as attributes. * Attribute values populate on any ticket the field is set on, regardless of source. Tickets created before an attribute was added simply start empty and can be filled in afterwards. * Attribute values are merged into the ticket's `attributeFields` blob by key, not replaced wholesale. Clearing a value requires sending an explicit `null` for that key. * Removing an option from a `SELECT` or `MULTI_SELECT` attribute archives it (sets `archivedAt`) rather than deleting the `CustomFieldOption` row. Tickets holding the option keep resolving its label. Pickers, `search_workspace_attributes`, and the update-attribute form all filter archived options out, but filters, analytics group-by, and `get_ticket` hydration include them (labeled `(removed)` or flagged `removed: true`) so held values remain findable. A daily Temporal sweep hard-deletes archived options once no ticket references them. * CSV exports resolve `USER_SELECT` and `USER_MULTI_SELECT` values (and user form fields) to the user's display name via `formatUserName`. The raw user id is not written to the export. * Analytics group-by on `USER_MULTI_SELECT` joins the ticket's stored `{ id }` entries against the `User` table and buckets by `firstName lastName`, so groups are labeled with the person's name rather than the raw stored value. # Custom fields Source: https://docs.ravenna.ai/documentation/tickets/forms/custom-fields Add custom fields to Ravenna forms to capture exactly the information your team needs when tickets are created, with multiple input types. Custom fields add additional information fields to ticket creation forms. Use them to create dynamic, customized templates that capture exactly the information your team needs for different types of requests. *** ## How custom fields work Custom fields are tied to specific forms. When someone creates a ticket using a form, they see both standard system fields (like title and description) plus any custom fields configured for that form. **Example:** A "Bug Report" form might include custom fields for bug severity, browser type, and steps to reproduce. A "Feature Request" form might include custom fields for business justification, priority level, and target users. Custom fields are only available when creating tickets through forms. *** ## Field types Single-line text input for short responses like names, titles, or brief descriptions. Multi-line text input for longer descriptions, explanations, or detailed information. Numeric input with validation for quantities, counts, or measurements. Date picker for scheduling, deadlines, or date-related information. When used in a [title template](/documentation/tickets/forms/overview#title-templates), date fields support format suffixes to control how the date displays in the generated title. Combined date and time picker for when the hour matters, like a maintenance window or a scheduled cutover. Pick it instead of **Date** when you need both halves in one field, rather than pairing a Date field with a separate Time field. The value is stored as wall-clock time, so 9:00 AM stays 9:00 AM for everyone who reads the ticket regardless of their timezone. In Slack, the field renders as Slack's combined date and time picker and is interpreted in the submitter's Slack timezone, so what they choose is what gets saved. Time input for selecting specific times of day. Time duration input for tracking time spans or estimated completion times. Select from predefined timezone options for scheduling and time-related information. Yes/No checkbox for binary choices or confirmations. Single-choice dropdown menu from predefined options. Multiple-choice dropdown menu allowing selection of multiple options. Choose a single organization member for assignments or mentions. Choose multiple organization members for assignments or mentions. Select from user groups in your organization. * Configure an **allowlist** with no item limit to restrict which groups appear as options * Filter by **source** to show only groups from a specific provider (Okta, Google Workspace, or groups created in Ravenna) * Manually created groups only appear in their assigned workspace. Synced groups are visible across all workspaces. Select from available tags to categorize tickets. Select from applications connected to your organization. Select multiple applications connected to your organization. * Configure an **allowlist** with no item limit to restrict which applications appear as options Select from application groups in your organization. Select from predefined ticket type options (e.g., Service, Incident, Question). Select from defined access levels for permission management. Upload files and attachments to tickets. Configure allowed file types and size limits. *** ## Create custom fields Create custom fields centrally in workspace settings: Go to **Settings > Fields** in your workspace. Click **Create Custom Field**. Fill in the required information: * **Label**: The name that appears on the form * **Description**: Help text explaining what this field is for * **Type**: Choose from available field types * **Required**: Toggle whether this field must be filled out. Turning this on at the workspace level makes the field required everywhere it appears and locks the per-form **Required** toggle so individual forms cannot opt out. This floor does not apply to private fields, which are locked to a single form and can be toggled required independently. Click **Create** to save your custom field. Create and manage custom fields directly within forms: Go to **Settings > Forms**. Select an existing form or create a new one. Drag and drop fields from the right panel into your form. The right panel has three tabs: * **Custom**: Create new custom fields * **Existing**: Use existing custom fields from other forms * **System**: Add system fields Use the dropdown menu in each custom field item to edit field properties. Toggle the private option to make a custom field visible only for the current form. *** ## Use existing fields Existing custom fields are non-private fields created from other forms or settings. Find them in the **Existing Custom Fields** tab in the form builder. These fields are shared across forms, meaning you can reuse them without recreating them. When you update an existing custom field that's shared across multiple forms, the changes apply to all forms using that field. *** ## Per-form label and description overrides Override the **label** and **description** of a shared custom field on a single form without affecting how the field appears on other forms. Use overrides when the same underlying data point needs different wording per audience. **Example:** A shared **Department** field can show as "Your department" on an employee-facing onboarding form and "Requesting department" on an internal procurement form, while still writing to the same field on every ticket. **Configure an override:** Go to **Settings > Forms** and select the form. In the form builder, click the field's title to rename it inline, or open the field's menu and choose **Edit** to update the description. Changes save automatically. The override applies only to this form. Clear an override to fall back to the field's shared label or description. Overrides do not change the field's key, type, options, or validation — only the displayed text on this form. Custom fields cannot be deleted when they are being used in a form. ### Preview impacted forms When you edit a shared custom field, Ravenna asks you to confirm the change and lists every form the field is attached to. When you try to delete a shared field that's still in use, the error dialog shows the same list so you can see exactly where it's referenced. Each entry in the list links directly to the affected form. The form you're currently editing is labeled **Current** and is not clickable. Use this list to: * Review which forms will be affected before saving a label, description, or option change. * Jump to other forms that need follow-up edits. * Locate every form that still references a field you want to delete. *** ## Hidden fields Toggle **Hidden** on a custom field to exclude it from all requester-facing form surfaces. Hidden fields do not appear in Slack modals, the customer portal, or the web form for requesters. Hidden fields remain on the ticket and are: * Visible and editable by agents in the ticket detail sidebar * Fillable by workflows, agent prefills, and the API * Available as filter and group-by options in views and analytics Use hidden fields for internal-only metadata that agents or automations populate without exposing the field to requesters. *** ## Rich text for text areas Text Area fields support an optional **Rich text** toggle. When enabled: * Web forms display a rich text editor with bold, italic, lists, links, and headings * Slack modals use native rich text input * Values are stored as structured content and rendered with formatting in ticket details Enable rich text when the field captures structured content like instructions, notes, or descriptions that benefit from formatting. *** ## Use custom fields Once you've created custom fields and assigned them to forms: **Ticket creation** * Users see custom fields when creating tickets with that form **Ticket display** * Custom field values appear in ticket details * In table views, custom field columns are hidden by default. Show them from the column visibility menu. * URLs in text and textarea fields are automatically converted to clickable links, including `https://`, `http://`, `www.`, and bare domain formats **Ticket updates** * Custom field values can be updated after ticket creation from the ticket details page Learn more about [setting up forms](/documentation/tickets/forms/overview) and assigning custom fields to create complete ticket templates ## Mental model Custom fields are additional data fields attached to forms. When a ticket is created using a form, the custom fields on that form become part of the ticket's data. Custom fields extend the ticket data model beyond the built-in system fields (title, description, status, priority, assignee, requester, approvers, followers). Key concepts: * Custom fields are workspace-scoped. * A custom field can be **shared** (available to add to multiple forms) or **private** (locked to a single form). * Custom field values are stored on the ticket and can be read, updated, and used in workflows and agent rules. * Custom fields are only collected when a ticket is created through a form. Tickets created without a form do not have custom field data. *** ## Field type selection guide | Field type | Use when | | ---------------------------- | ------------------------------------------------------------------------------------- | | **Text** | Short freeform input (names, identifiers, URLs) | | **Text area** | Longer freeform input (steps to reproduce, justifications) | | **Number** | Quantities, counts, version numbers | | **Date** | Deadlines, target dates, incident dates. Supports format suffixes in title templates. | | **Time** | Specific times of day | | **Duration** | Time spans, estimated effort | | **Timezone select** | User timezone for scheduling | | **Boolean** | Yes/no confirmations, toggles | | **Select** | Single choice from a fixed set (severity, environment, device type) | | **Multi-select** | Multiple choices from a fixed set (affected systems, required permissions) | | **User select** | Pick one organization member (manager, approver) | | **User multi-select** | Pick multiple members (stakeholders, reviewers) | | **User group select** | Pick a team or group (supports allowlist and source filtering) | | **Tag select** | Pick from workspace tags | | **Application select** | Pick from connected applications (for access requests) | | **Application multi-select** | Pick multiple connected applications (supports allowlist filtering) | | **Application group select** | Pick from application groups | | **Type select** | Pick from predefined ticket types (Service, Incident, Question, etc.) | | **Access level select** | Pick from defined access levels (for permission management) | | **File picker** | Attachments (screenshots, documents, logs) | For structured data that needs filtering and reporting, prefer select/multi-select over freeform text. Select fields produce consistent values that work better in views, workflows, and analytics. *** ## Shared vs. private fields **Shared fields** (non-private) can be added to multiple forms. Updating a shared field's configuration (type, options, key) propagates the change to all forms using it. This is useful for standardized fields like "Department" or "Location" that appear on many forms. Each form can override the **label** and **description** of a shared field locally. The override is stored on the form's field assignment, not the underlying field, so the same field can read as "Your department" on one form and "Requesting department" on another. Clearing the override restores the shared values. **Private fields** are locked to a single form. They cannot be added to other forms and do not appear in the "Existing Custom Fields" tab. Use private fields for form-specific data that is not relevant elsewhere (e.g., "Steps to Reproduce" on a bug report form). When deciding between shared and private: if the same data point is relevant across multiple forms, make it shared. If it only makes sense in the context of one form, make it private. *** ## Custom fields in automation **Workflows:** Custom field values are available as dynamic values in workflow actions for tickets created with the corresponding form. Use them to: * Route tickets based on field values (e.g., if "Severity" is "Critical", assign to senior team). * Include field data in notifications or messages. * Set other ticket properties based on field values. **Agent rules:** The agent can read custom field values from a ticket and use them in conversation context. The agent can also set custom field values when creating or updating tickets through forms. **Views and filtering:** Custom field values are available as filter and grouping criteria in ticket views. Select and multi-select fields are most effective for filtering. *** ## Constraints and gotchas * Custom fields are only available on tickets created through forms. Tickets created via direct message or without a form selection will not have custom field data. * A custom field cannot be deleted while it is attached to any form. Remove it from all forms first. * Updating a shared field's configuration affects all forms using it. If you need form-specific behavior, create a private field instead. The update confirmation dialog lists every impacted form so you can review the scope of the change before saving. * Deleting a shared field that is still attached to one or more forms is blocked. The error dialog lists each form referencing the field so you can detach it before retrying. * Field type cannot be changed after creation. If you need a different type, create a new field and migrate the data manually. * Required fields must be filled out during ticket creation. If a field is marked required, the ticket cannot be submitted without a value. * Required is enforced as a floor across levels for shared fields. If a shared custom field is set to Required in workspace settings, the per-form Required toggle is locked on and individual forms cannot make the field optional. To allow forms to opt out, uncheck Required on the field in **Settings > Fields**. Private fields are exempt from this floor and can be toggled required directly on the form. * Custom field values can be updated after ticket creation from the ticket detail page, regardless of whether the field was originally required. * Select and multi-select option changes do not retroactively update existing tickets. Removing an option archives it rather than deleting it: tickets that already held the option keep displaying it, greyed out and labeled **(removed)**, and it stays available in ticket-list filters and analytics group-by so those tickets remain findable. Removed options do not appear in pickers on new tickets, and Ravenna hard-deletes them during a daily cleanup sweep once no ticket references them. * For user group select fields, changing the source filter clears the allowlist. When duplicating forms across workspaces, allowlist and source configurations are stripped because group IDs may differ. * Allowlists have no item cap. When a fillable field has more than 100 options, Slack form modals automatically switch to a searchable dropdown that loads options on demand, so requesters can find any option by typing. # Forms Source: https://docs.ravenna.ai/documentation/tickets/forms/overview Create structured ticket forms with custom fields, lifecycle states, audience controls, and folder organization to route requests intelligently. **Request Types are now Forms.** This rename is rolling out to all organizations soon. Forms transform generic support requests into structured, categorized tickets with the right information, routing, and workflow. Use folders to organize related forms by department, process, or team structure. AI-powered classification automatically identifies the right form based on request content. *** ## Getting started Organize your forms using folders that match your team's workflow. Consider department-based, process-based, or complexity-based organization. Navigate to **Forms** and create folders with clear names, descriptions, and visual elements to help users quickly identify categories. Create forms within folders, configure them with system and custom fields, and set up AI classification with sample messages. Set up defaults, status management, channel integration, and AI responses to streamline ticket handling. *** ## Organize with folders Folders group related forms and provide the same organizational approach you use for workflows and knowledge pages. Forms and folders are workspace-specific, allowing each team to create a support system matching their unique requirements. ### Create folders Give folders clear names and descriptions that explain their purpose. Folders support nested structures that mirror your organization. **Example:** An "IT Support" folder might contain subfolders for "Hardware", "Software", and "Network" issues. ### Organization patterns Organize by team ownership - IT Support, DevSecOps, IT Admins. This structure matches organizational hierarchy and ownership. Group by business function - Onboarding, Procurement, Maintenance. This structure aligns with business processes and workflows. Separate simple requests from complex processes and specialized workflows. This helps users find the right level of detail quickly. ### Moving forms and folders Move forms and folders between locations as your organization evolves. Use drag-and-drop or bulk operations to reorganize your form structure. Drag forms or folders to move them between locations. **Single item:** 1. Click and hold on a form or folder 2. Drag to the target folder or breadcrumb 3. Release to move **Multiple items:** 1. Select multiple forms or folders using checkboxes 2. Drag any selected item 3. All selected items move together **Create new folder during move:** Drag items to the "Move to new folder" button to create and move in one action. Move multiple forms at once using bulk actions. 1. Select forms or folders using checkboxes 2. Click the **Move** action in the toolbar 3. Select the target folder 4. Confirm the move Bulk move is ideal for reorganizing large numbers of forms or restructuring your folder hierarchy. Some moves are prevented to maintain system integrity: * Forms keep their history and configuration when moved * Folders cannot be moved into their own subfolders (prevents circular references) * Moving a folder also moves all forms and subfolders within it *** ## Create forms Create forms within folders or at the root level based on your organizational needs. Each workspace maintains its own collection tailored to specific support requirements. ### Basic configuration Choose a clear, recognizable name and helpful description that eliminates guesswork for requesters. #### Icon and color customization Visual elements like icons and colors help users quickly identify the right form in the portal, Slack, and ticket views. Forms support three types of icons, displayed with the following priority: 1. **Custom image**: Upload a branded or project-specific image (PNG, JPEG, GIF, WebP, or SVG, max 1MB). The image is cropped to a square during upload. 2. **Lucide icon**: Select any icon from the full [Lucide](https://lucide.dev/icons) library. Use the search bar in the icon picker to find an icon by name or keyword. 3. **Default icon**: If no icon is configured, a default icon is used automatically. Custom icons appear on Portal request cards, the forms list page, ticket rows, and task rows. Select a color for your form icon to create visual distinction between forms. Colors apply to both Lucide icons and the icon background in the Portal. Upload branded icons to help users visually distinguish forms in the Portal, especially when you have many forms in a single folder. ### Form builder Use the form builder to create custom data collection forms with system fields and custom fields. Drag and drop fields to arrange your form layout, nest dependent fields under parent fields, and collapse groups to manage complex forms. Every form must have at least one field configured to collect information from requesters. System fields are core built-in ticket components: title, description, status, priority, requester, assignee, approvers, and followers. You can control whether they're required or optional. The title field must always be required. Custom fields provide flexibility to collect specific information for different forms. Available types include text, text area, number, date, boolean, select, multi-select, user select, and application select. All field types can be configured to show or hide based on the value of another field, including layout fields (headings, dividers, text blocks) and system fields. For example, a "Department" select field can control which follow-up fields and section headings appear. Conditional fields display as nested under their parent in the form builder and are grouped in collapsible sections for easier management. Visibility rules are enforced both during form filling and in the ticket detail view. Learn more about [custom fields](/documentation/tickets/forms/custom-fields) and how to configure them for your forms *** ## Configure forms Configure form behavior through settings tabs. Control basic behavior and appearance. Set it as the default when the system can't determine the most appropriate type. Updates in the **General** section auto-save as you edit. Toggling a setting or selecting an audience card applies the change immediately — there is no manual save step. ### Privacy settings The **Private** toggle controls default ticket privacy for this form. When enabled, tickets created with this form are automatically marked as private. **When to use private forms:** * HR requests * Security incidents * Personal information * Confidential business matters **Configure privacy:** 1. Go to **Settings > Forms** 2. Select the form you want to configure 3. Click the **Details** tab and open the **General** section 4. Enable or disable the **Private** toggle — the change saves automatically Your organization may have different needs for private forms based on your security policies and compliance requirements. The **Private** toggle controls default ticket privacy only. It does not hide the form itself. Published forms with the Private toggle enabled still appear in the Portal and the Slack form selection list (subject to their audience settings); the resulting tickets are marked private when submitted. To hide a form from end-user surfaces entirely, move it to **Draft** or **Archived**, or restrict its audience. ### Feature in Portal Enable **Feature in Portal** to surface a form on the **Start new request** tab of the Portal home. Featured forms keep your most common requests front and center. Forms that are not featured still appear in the Portal's full forms catalog when the requester has access. Streamline ticket creation with automatic values. ### Title templates Title templates generate consistent, informative titles using field values, especially valuable when requesters don't provide clear titles. Insert tokens using the dropdown in the title template editor. Available tokens include system values like requester name, assignee, and form name, plus any custom fields on the form. Date fields support an optional format suffix to control how the date appears in the generated title. When you insert a date field token, a submenu lets you pick from common date formats. If no format is specified, date fields default to MM/DD/YYYY. Set default priority, type, channel, and tags to ensure tickets start with appropriate settings, reducing manual work and ensuring consistent handling. ### Shortcut public acknowledgement The **Shortcut Public Acknowledgement** toggle controls the default acknowledgement for tickets created from this form through the Slack [message shortcut](/integrations/slack/creating-tickets#methods). It applies in DMs and in channels that are not connected request channels. This setting is Slack-only. Microsoft Teams does not have a 1:1 DM entry point or shortcut equivalent in the current beta; Teams tickets are always created from channel messages. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview). * **Enabled (default):** Ravenna posts a public threaded message confirming the ticket was created so everyone in the conversation sees the acknowledgement. * **Disabled:** Only the user who created the ticket sees an ephemeral confirmation. The original thread stays untouched. Submitters can still change the choice per ticket using the **Publicly acknowledge that a ticket was created?** checkbox on the Slack modal. This setting only changes the default state of that checkbox. The setting has no effect inside connected request channels, where Ravenna always posts a public confirmation in the thread. *** ## Form lifecycle Forms follow a Draft, Published, and Archived lifecycle that controls their visibility to end users. Draft forms are works in progress. They are visible to workspace admins in the forms table but do not appear in ticket creation flows, the Portal, or Slack. Newly created forms start in Draft so you can build and review them before exposing them to end users. Publish the form when you're ready to make it available. You can also move a published form back to Draft if you need to make changes before re-publishing. The one exception is the default form a new workspace comes with (`Ask `). It is created Published so the workspace can take tickets right away. Published forms are active and available to users based on their audience settings. They appear in ticket creation flows, the [Portal](/documentation/platform/portal), and Slack form selection. Publishing is also what makes a form selectable elsewhere in Ravenna. When you pick which forms a queue, agent, or Slack channel uses, only published forms can be selected. A draft or archived form that was already attached stays listed so you can see it and remove it, marked with the reason it is no longer selectable. Archived forms are removed from all user-facing surfaces. Existing tickets created with an archived form retain their data and history. Archive a form when it is no longer needed but you want to preserve its configuration. ### Manage form status The form detail page includes a toggle switch in the header that controls whether a form is **Published** or **Draft**. Toggle it on to publish, or off to move back to draft. A confirmation dialog appears before the change is applied so you can review the impact before publishing or unpublishing. Publishing makes the form available in end-user surfaces; unpublishing hides it from the Portal, Slack, and ticket creation flows. Click **Confirm** to apply the change, or **Cancel** to keep the current status. The toggle is disabled when a form is archived. You must unarchive a form before you can change its publish state. Archive and unarchive controls are in the **Details** tab at the bottom of the form detail page. * Click **Archive** to remove a form from all user-facing surfaces. A confirmation dialog appears before the form is archived. * Click **Unarchive** to restore an archived form back to Published status. **Archiving folders:** When you archive a folder, a confirmation dialog asks whether to include the folder's contents: * **Include contents:** The folder and every form and subfolder inside it are archived together. * **Folder only:** Only the folder is archived. Forms and subfolders inside it are moved up to the nearest non-archived parent so they remain available to end users. Forms created inside an archived folder — including duplicates — inherit the archived status automatically. Unarchive the parent folder first if you want new forms to start as Draft. The delete option is also in the **Details** tab. Delete is only available for forms that have **no associated tickets**. If a form has been used to create tickets, it cannot be deleted. Archive it instead. The workspace's default form follows the same rules as any other form. You can edit, archive, and delete it, so you are free to replace the starter form with one of your own. You can also manage status from the forms table: * **Three-dot menu**: **Publish** appears for draft forms, **Unpublish** appears for published forms. Both actions show a confirmation dialog before the status change is applied. * **Bulk actions**: Select multiple forms or folders and use the **Archive** bulk action. When the selection includes folders, you're prompted to choose whether to archive their contents along with them. * **Status column**: Color-coded badges show each form's current status (Draft = gray, Published = green, Archived = amber). * **Filtering**: Use the status filter to show or hide forms by status. Archived forms are hidden by default unless you add an explicit status filter. *** ## Audience settings Control who can see and submit a form by setting its audience. Audience settings work alongside the form lifecycle to determine which users can access a form. All users in your organization can see and submit the form. This is the default audience for new forms. Only workspace members and admins can access the form. End users who are not workspace members will not see it in ticket creation flows or the Portal. Only members of selected user groups can access the form. Select one or more groups to define the audience. ### Configure audience Navigate to the form and click the **Details** tab, then select the **General** section. In the **Who Can Access** card, select one of the three audience cards: **Everyone**, **Members only**, or **User Groups**. The selected card is highlighted to confirm your choice. If you chose **User Groups**, a group picker appears below the audience cards. Search for and add the groups you want to grant access to. Changes in the **General** section save automatically as you make them. There is no separate **Save changes** button — selecting a card or updating a field commits the change immediately. Audience settings only apply to published forms. Draft and archived forms are not visible to end users regardless of their audience setting. Learn more about [user groups](/documentation/platform/groups) and how to create and manage them *** ## Advanced features ### Status management Forms can define custom statuses beyond the standard system statuses. All forms include default statuses (Open, In Progress, Waiting, Done, Closed), but you can add custom statuses within these groups. **Example:** The "In Progress" group might include "Needs Review" for requests requiring approval. The "Done" group could have "Completed" and "Delivered" to track different completion states. Learn more about [status management](/documentation/tickets/organize/statuses) and custom statuses ### Channel integration Forms integrate with your channel structure to ensure proper routing and assignment. Each form can specify a default channel for streamlined ticket creation. Learn more about [setting up and managing channels](/documentation/tickets/channels) for your workspace ### Share forms in Slack Paste a Ravenna form URL into any Slack channel, DM, or thread to share it as an unfurled card with an **Open Form** button. Teammates can click the button to launch the form as a Slack modal and submit a request without leaving Slack. Learn more about [sharing forms in Slack](/integrations/slack/creating-tickets) including URL formats and routing behavior. ### Share forms publicly Turn on **Public access** to host a form at an unguessable URL that anyone can submit without signing in. Use it for requests from people outside your organization, like vendor onboarding, event sign-ups, or external bug reports. Open the **Share** popover on a published form and toggle **Public access**. Ravenna generates a public link you can copy and share. Submitters enter their email, and Ravenna creates or reuses a guest user as the requester so the ticket routes like any other. Public access is only available on published forms. The public link becomes active once the form is published. Public forms support simple input fields (text, paragraph, number, date, time, yes/no, select, multi-select, and timezone) plus layout blocks. Fields that reference workspace data, such as user, tag, or status pickers, are not allowed. If a form has an incompatible field, Ravenna lists the fields to remove before you can enable public access. Copy the public link from the **Share** popover and distribute it however you like. To invalidate the current link, use **Rotate link** to generate a new token. Rotating breaks the existing link for everyone. Public forms never expose workspace data. Responses are limited to the allowed field types, submissions are rate limited, and a CAPTCHA challenge protects against abuse. Turn off **Public access** at any time to deactivate the link. ### Workflow automation Forms integrate with workflows through the Form Submitted trigger, enabling automated responses when specific forms are submitted or updated. **Automation capabilities:** * Trigger workflows on form submission * Filter workflows by specific form types * Access form field data in workflow actions * Automate routing, assignment, and approvals based on form type Learn more about [workflow triggers and actions](/documentation/automate/workflows/triggers-actions) including the Form Submitted trigger ## Mental model A form defines the structure and defaults for a type of support request. When a ticket is created using a form, the form determines which fields are collected, what default values are applied (priority, channel, tags), and which custom sub-statuses are available. Key relationships: * One workspace has many forms, organized into folders. * One form produces many tickets. * One form can specify a default channel (affects ticket routing priority). * One form can have specific custom sub-statuses assigned to it. * One form can be referenced in agent rules with `@` and in workflow triggers. * Each form has a lifecycle status (Draft, Published, Archived) that controls end-user visibility. * Each form has an audience type (Everyone, Members Only, User Groups) that controls which users can see and submit it. * Only Published forms with matching audience appear in end-user surfaces (portal, Slack, ticket creation). Forms are workspace-scoped. Each workspace maintains its own form library. AI classification matches incoming requests to the most appropriate form based on the request content and each form's description and sample messages. This is separate from category classification. Forms determine ticket structure, categories determine ticket topic. *** ## Form design patterns **When to create a separate form:** * The form needs different fields (e.g., "Software Access" needs an application select field, "Hardware Request" needs a device type field). * The form needs different defaults (e.g., incidents default to high priority, feature requests default to low). * The form needs a different status workflow (e.g., access requests use "Pending Approval" sub-status, bug reports use "Needs Review"). * The form should route to a different channel by default. **When to use the same form:** * The requests collect the same information and follow the same process. Differentiate with categories or tags instead. **Folder organization:** Group forms into folders that match how requesters think about their needs, not how the support team is organized. "I need help with..." is a better mental model than "This goes to team X." **Naming:** Use action-oriented names that describe what the requester needs: "Request Software Access", "Report a Bug", "Submit Expense Report." Avoid internal jargon. *** ## Form lifecycle Forms have three statuses: | Status | End-user visible | Admin visible | Valid transitions | | ------------- | -------------------------- | ------------------------------------ | ----------------------------------------- | | **Draft** | No | Yes (forms table) | Draft -> Published | | **Published** | Yes (filtered by audience) | Yes | Published -> Draft, Published -> Archived | | **Archived** | No | Yes (forms table, hidden by default) | Archived -> Published | New forms default to Draft so admins can finish configuring them before they become available to end users. The workspace's own default form (`Ask `) is the exception and is created Published. The lifecycle is enforced server-side via the `updateStatus` endpoint, which validates transitions. **UI controls:** The form detail page header has a toggle switch that controls Published/Draft. The toggle is disabled when the form is archived. Archive/unarchive buttons are in the Details tab. The forms table shows Publish/Unpublish in row actions and Archive as a bulk action. **Deletion rules:** A form can only be deleted if it has zero associated tickets. Forms with tickets must be archived instead. The default form carries no extra restriction and can be edited, archived, or deleted like any other form. **Table visibility:** Archived forms are hidden from the forms table by default. They only appear when the user adds an explicit status filter. Draft and Archived forms do not appear in the Portal, Slack form selection, or ticket creation form picker. They are also not selectable when attaching forms to a queue, agent, or Slack channel: already-attached forms remain visible but disabled, labeled with their current status. Existing tickets created with a now-archived form retain their data. *** ## Audience access control Audience determines which users can see and submit a published form: | Audience type | Who can access | | -------------------------- | ---------------------------------------- | | **Everyone** | All users in the organization | | **WorkspaceMembers** | Only workspace members and admins | | **Specific** (User Groups) | Only members of the selected user groups | Audience filtering is server-side via `getPublishedAccessibleForms`. The Portal, Slack form selection, and semantic loader all use this endpoint. This replaces previous client-side filtering. When audience is set to "Specific", the form stores `allowedGroups` (array of user group IDs). A user gains access if they are a member of any of the allowed groups. *** ## Form-ticket-channel integration Forms influence ticket creation in several ways: 1. **Field collection:** The form determines which fields the requester fills out (system fields + custom fields). 2. **Default values:** Priority, channel, and tags can be pre-set per form. 3. **Title template:** Forms can auto-generate ticket titles from field values for consistent naming. Date fields support format suffixes (e.g., `{{fieldKey:MM/DD/YYYY}}`) to control date display. 4. **Channel routing:** A form's default channel takes highest priority in the routing order (form default > Slack channel connection > workspace default). 5. **Status options:** Custom sub-statuses assigned to the form determine which statuses are available beyond the five system statuses. 6. **Privacy:** Forms can default tickets to private, useful for HR, security, or confidential forms. 7. **Icon display:** Forms support custom image icons (uploaded images), Lucide icons, or a default fallback. The Portal renders them in priority order: custom image URL, then configured Lucide icon, then default icon. When designing forms, consider the full ticket lifecycle: what information is needed at creation, what defaults reduce manual work, and what channel/status configuration matches the handling process. *** ## Forms in automation **Workflow triggers:** The "Form Submitted" trigger fires when a ticket is created using a specific form. Filter by form to build form-specific automations. Form field data is available as dynamic values in downstream workflow actions. **Agent rules:** Reference forms in agent rules using `@Form Name`. Common patterns: * "When a user asks about software access, present the @Software Access Request form." * "For hardware issues, use the @Hardware Request form and set priority based on urgency." The agent can present forms to users during conversation, pre-fill fields from conversation context, and let the user review before submission. **AI classification:** The system matches incoming requests to forms based on form descriptions and sample messages. Well-written descriptions and diverse sample messages improve classification accuracy. This classification is separate from category classification and runs independently. *** ## Constraints and gotchas * Every form must have at least one field. The title field is always required and cannot be made optional. * Forms are workspace-scoped. There is no cross-workspace form sharing or import. * A form's default channel takes highest routing priority. If a form specifies a default channel, tickets created with that form always go to that channel regardless of which Slack channel the request originated from. * AI form classification and AI category classification are separate systems. A request can be matched to a form and independently classified into a category. * Custom sub-statuses must be explicitly assigned to each form. Creating a sub-status does not make it available on all forms. * Moving a form between folders does not affect existing tickets or form configuration. * Private forms create private tickets by default. Users can still change ticket visibility after creation if they have permission. * Form field data is accessible in workflows via dynamic values, but only for tickets created with that specific form. Tickets created without a form (or with a different form) will not have those field values available. * Only published forms appear in end-user surfaces (Portal, Slack, ticket creation). Draft and archived forms are admin-only. * AI agents also honor form lifecycle. The agent only presents Published forms, even if a Draft or Archived form is referenced in an agent rule. Publish the form before relying on it in agent rules. * Audience filtering is server-side. The `listAccessible` endpoint returns only forms the current user can access based on publish status and audience. * Changing a form's audience does not affect existing tickets created with that form. * A form's audience setting has no effect when the form is in Draft or Archived status, since those forms are not visible to end users regardless. * A form cannot be deleted if it has any associated tickets. The only option is to archive it. * The default form for the workspace cannot be deleted or archived. * Archived forms are hidden from the forms table by default. They appear only when the user adds an explicit status filter. * The publish/draft toggle in the form header is disabled when the form is archived. You must unarchive first. * Archiving a folder offers two modes: archive the folder with its contents, or archive only the folder and reparent its contents to the nearest non-archived ancestor. Bulk archive applies the chosen mode to every selected folder in one transaction. * Forms created inside an archived folder inherit the archived status at creation time. The same applies to duplicates whose target parent is archived. Unarchive the parent first if you want new forms to start as Draft. # Links Source: https://docs.ravenna.ai/documentation/tickets/links Connect Ravenna tickets to external resources like GitHub or Jira for context and bi-directional sync with integrated ticketing systems. Connect tickets to external resources like GitHub issues, design documents, or integrated ticketing systems. Add manual links for context or let integrations create them automatically for bi-directional sync. *** ## What are ticket links? Ticket links connect your Ravenna tickets to external resources and systems. Add manual links for context or let integrations create links automatically for bi-directional sync with tools like Slack, Jira, and Linear. *** ## Add ticket links ### Manual links Add links to external resources directly from any ticket: Navigate to the ticket you want to add a link to. Find the links section in the ticket details. Click **Add Link** or the plus button. Enter the external URL you want to link to. Ravenna automatically fetches the page title to use as the link name. The name field auto-populates with the page title. You can edit it to customize the link name if desired. Click **Save** to create the link. When you paste a URL, Ravenna automatically fetches the page title to populate the link name. For Ravenna ticket URLs, it uses the ticket title. For external URLs, it extracts the page title from the site's metadata. You can always edit the auto-generated name before saving. ### Integration links Some links are created automatically through system integrations: * Automatically creates links when tickets are created from Slack messages * Provides direct access to the original Slack conversation }> * Creates links when tickets are synchronized with Jira issues * Enables bi-directional updates between Ravenna and Jira * Maintains real-time sync through webhooks }> * Automatically links when Linear issues are created * Provides direct access to Linear workspace issues * Supports workflow automation between systems * Automatically links a pull request to a ticket when the PR branch contains the ticket id (for example, `ENG-42-fix-login`) * Moves the ticket to **In Progress** when the PR is opened, **Done** when it merges, and **Open** when it is reopened * Requires the Ravenna GitHub App. Learn more in [Pull request sync](/integrations/github/pull-request-sync). *** ## Manage ticket links ### Edit links Find the link you want to edit in the ticket's links section. Click the edit button or dropdown menu for the link. Modify the name or URL as needed. Click **Save** to update the link. ### Delete links Find the link you want to remove in the ticket's links section. Click the delete button or select **Delete** from the dropdown menu. Confirm the deletion when prompted. This action cannot be undone. *** ## Use ticket links Click any link to open the external resource in a new tab. Links display with favicons and domain information for easy identification. Use links to provide additional context for tickets, reference related documentation, pull requests, or external issues, and share resources with team members. Integration links maintain bi-directional sync with external systems, keeping ticket information consistent across platforms. ## Mental model Ticket links are URL references attached to a ticket. They come in two forms: * **Manual links**: User-added URLs to any external resource (documentation, pull requests, design files, etc.). These are display-only references with no sync behavior. * **Integration links**: System-created links from integrations (Slack, Jira, Linear). These can support bi-directional sync, meaning changes in one system propagate to the other. Links are distinct from ticket relations. Links point to external resources (URLs). Ticket relations connect Ravenna tickets to each other (parent/child, related). *** ## Links vs. relations vs. sharing | Mechanism | Connects | Sync behavior | | ------------- | --------------------------------- | ----------------------------------------------------------- | | **Links** | Ticket to external URL | Manual links: none. Integration links: bi-directional sync. | | **Relations** | Ticket to ticket (within Ravenna) | Parent/child hierarchy, related tickets | | **Sharing** | Ticket visibility across channels | Same ticket appears in multiple channels | Use links when referencing external systems. Use relations when connecting Ravenna tickets. Use sharing when multiple teams need to see the same ticket. *** ## Integration link behavior **Slack:** When a ticket is created from a Slack message, a link to the original Slack thread is automatically attached. This is read-only context, not sync. **Jira / Linear (ticket replication):** When ticket replication is enabled, integration links are created automatically and maintain bi-directional sync. Status changes, comments, and updates propagate between systems. These links are managed by the integration, not by users. *** ## Constraints and gotchas * Manual links are simple URL references. They do not sync, update, or validate that the target resource still exists. * Integration links are system-managed. Deleting an integration link can break replication sync. Avoid manually deleting integration-created links. * Links have a name and URL. When adding a link, the system auto-fetches the page title, but this can be overridden. # Move tickets Source: https://docs.ravenna.ai/documentation/tickets/move-tickets Move tickets between Ravenna workspaces to reassign ownership when a request belongs to a different team or your org structure changes. Move tickets from one workspace to another when a request needs to be handled by a different team or when organizational structure changes require ticket reassignment. *** ## How moving works The ticket is removed from the original workspace and added to the destination workspace with all its history intact. The ticket mirror in the original workspace's triage channel is updated with a "moved" indicator showing where the ticket was relocated. A new mirror is automatically created in the destination workspace's triage channel. All stakeholders (assignee, followers, requester) are notified of the workspace change with context about the new location. Request thread mirrors, DM mirrors, and triage channel mirrors are all updated to reflect the workspace change. The following information is preserved: * **Ticket history**: All messages, comments, and activity * **Priority**: Carried over as-is * **Attachments**: Files and images attached to the ticket * **Time tracking**: SLA timers and due dates Each workspace owns its own configuration, so these fields re-point to the destination workspace's equivalents: * **Status**: Ravenna picks the destination status with the same label. If there is no match, the ticket moves to the destination's **Open** status. * **Tags**: Each tag is matched to a destination tag with the same name. Missing tags are created in the destination workspace. * **Category**: Matched by name in the destination workspace. If it doesn't exist, Ravenna creates it there. * **Ticket attributes**: Attributes are matched to destination attributes with the same key. Missing ones are created. For dropdown fields, option values are matched by label; options with no equivalent in the destination are dropped. The following elements change: * **Ticket ID**: The ticket receives a new ID based on the destination workspace's channel prefix. * **Channel**: The ticket moves to the destination channel you selected. * **Assignee**: May need to be reassigned if the original assignee is not a member of the destination workspace. * **Followers**: Followers who are not members of the destination workspace are removed. Fields that cannot span workspaces are cleared on move: * **Form**: Forms are workspace-scoped, so the ticket loses its form association. Answers captured through the form remain in the ticket's history. * **Parent ticket link**: A parent-child relationship cannot span workspaces. Moving a child ticket detaches it from its parent. Moving a parent ticket detaches all of its children. From the source workspace's point of view, the ticket is gone. It disappears from ticket lists and counts, and from any parent's sub-ticket list. If you were viewing it when it moved, Ravenna sends you back to the ticket list. A ticket that is also **shared** into the workspace you're viewing still shows up there through the share, even though it now lives elsewhere. *** ## Move a ticket Navigate to the ticket you want to move in Ravenna. Click the **More actions** menu (three dots) in the ticket header. Select **Move to workspace** from the dropdown menu. Select the destination workspace from the list of available workspaces. Review the change and click **Move** to complete the transfer. Moving tickets cannot be undone. Make sure you're moving to the correct workspace before confirming. *** ## Use cases Move complex issues to specialized teams or leadership workspaces for higher-level attention. Fix tickets that were created in the wrong workspace due to initial misrouting. Transfer requests that span multiple departments, such as moving from IT to HR or between cross-functional teams. ## Mental model Moving a ticket transfers it from one workspace to another. This is a full ownership transfer, not a copy or share. The ticket leaves the source workspace entirely and becomes part of the destination workspace. Key distinction: moving vs sharing. | Operation | What happens | Use when | | --------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | | **Move** | Ticket transfers to a new workspace. Gets a new ticket ID. Removed from source workspace. | The ticket belongs to a different team entirely | | **Share** | Ticket remains in its original workspace but becomes visible in additional channels. | Multiple teams need visibility but the owning team stays the same | Moving is irreversible. Sharing is reversible (unshare). *** ## What transfers and what changes **Preserved on move:** * Full message history, comments, and activity log * Priority * File attachments * SLA timers and due dates **Carried by name (matched or created in the destination workspace):** * **Status**: The destination status with the same label. Falls back to the destination's **Open** status if there is no match. * **Tags**: Matched by name; missing tags are created in the destination. * **Category**: Matched by name; created in the destination if it doesn't exist. * **Ticket attributes**: Matched by field key. Missing attribute fields are created in the destination. For `SELECT`/`MULTI_SELECT` fields, option values are matched by label; options with no equivalent in the destination are dropped. **Changed on move:** * **Ticket ID**: The ticket receives a new ID with the destination workspace's channel prefix. * **Channel**: The ticket moves to the destination channel you selected. * **Assignee**: May need reassignment if the original assignee is not a member of the destination workspace. * **Followers**: Followers who are not members of the destination workspace are removed. * **Slack mirrors**: The original triage channel mirror is updated with a "moved" indicator. A new mirror is created in the destination workspace's triage channel. Request thread and DM mirrors are updated. **Cleared on move:** * **Form**: Forms are workspace-scoped, so the association is dropped. Answers captured through the form stay in the ticket's history. * **Parent link**: Parent-child relationships cannot span workspaces, so moving a child detaches it from its parent, and moving a parent detaches all of its children. **After a cross-workspace move**, the ticket no longer appears in the source workspace's lists, counts, or sub-ticket views. If someone was on the ticket's detail page when it moved, they are redirected back to the ticket list. The exception is a ticket that is also shared into the workspace being viewed: it stays visible there through the share. *** ## When to move tickets Common patterns: * **Misrouted tickets**: A ticket was created in the wrong workspace. Move it to the correct one. * **Escalation to specialized teams**: A general IT ticket needs to go to the security team's workspace. * **Departmental handoff**: An HR onboarding ticket needs IT provisioning handled in the IT workspace. Do not move tickets when: * Multiple teams need to collaborate on the same ticket. Use sharing instead. * The ticket just needs a different assignee within the same workspace. Change the assignee instead. * The ticket needs to be in a different channel within the same workspace. Change the channel instead. *** ## Constraints and gotchas * Moving is irreversible. There is no "undo move" or "move back" operation. * The ticket gets a new ID in the destination workspace. Any external references to the old ID will need updating. * Followers who are not members of the destination workspace lose access immediately. * The ticket is assigned to the destination workspace's default channel. If specific channel routing is needed, it must be updated manually after the move. * All stakeholders (assignee, followers, requester) receive notifications about the move. * Moving a ticket does not move its child tickets, and the parent-child link does not survive a cross-workspace move. Moving a child detaches it from its parent; moving a parent detaches all of its children. If you need the family to stay together, move each ticket individually into the destination workspace and re-link them there. # Categories Source: https://docs.ravenna.ai/documentation/tickets/organize/categories Use AI-powered categories to automatically classify tickets by topic with name, description, and example phrases that train the classifier. Categories use AI-powered classification to automatically organize tickets when they're created, analyzing ticket content to determine the best classification match. *** ## Understanding categories Categories automatically classify tickets based on the criteria you define. Each category includes: * **Name**: The category label shown on tickets * **Description**: Explains what types of tickets belong in this category * **Examples**: Sample phrases that help AI classify tickets accurately ### Categories vs tags While both help organize tickets, they serve different purposes: | Feature | Categories | Tags | | -------------- | ---------------------------------- | -------------------------------------- | | **Assignment** | Automatic via AI | Manual, AI-assisted, or workflow-based | | **Purpose** | Primary classification | Flexible labeling | | **Limit** | One per ticket | Multiple per ticket | | **Examples** | "Password Reset", "Hardware Issue" | "Urgent", "VIP", "Needs Review" | Many teams use categories for primary classification and tags for additional context like priority, status, or team assignments. *** ## Set up categories ### Create categories Go to **Settings > Workspaces > Categories**. Click **New Category** to open the creation form. Enter a clear, descriptive label like "Password Reset" or "Software Request". Explain what belongs in this category - "Requests to reset user passwords or unlock accounts". Include sample phrases that represent this category: * "I forgot my password" * "Can't log into my account" * "Need to reset my credentials" Click **Create** to save the category. ### Use templates Import pre-built category sets for common use cases. Templates provide ready-to-use categories with names, descriptions, examples, icons, and colors already configured. Go to **Settings > Workspaces > Categories**. Click **New from template**. Browse categories organized by department (IT Support, HR, Facilities, etc.) and select multiple categories to import. Click **Create** to add them to your workspace. You can select up to 100 categories at once when importing from templates. After import, customize any category to match your team's specific needs. ### Edit categories You can modify category details at any time: * Name and description * Example phrases * Default category status Changes to examples and descriptions will affect future AI classifications but won't reclassify existing tickets. ### Default category Every workspace requires exactly one default category. You can manually assign the default category to tickets that don't fit into other categories. The first category you create automatically becomes the default category. You can change this later by editing another category and marking it as default. To change the default category: Edit the category you want to make default. Toggle **Set as default** to enabled. Save changes. The previous default category is automatically unset. ### Delete categories Go to **Settings > Workspaces > Categories**. Select the category to delete. Click **Delete**. * You cannot delete the default category * Tickets assigned to deleted categories will show "No category" until manually updated *** ## How classification works When a ticket is created, Ravenna automatically analyzes its content and assigns the most appropriate category by examining the ticket's title, description, and initial messages against your category descriptions and example phrases. ```mermaid theme={"system"} graph TD A["Ticket Created"] --> B["Analyze Content"] B --> C{"Match Found?"} C -->|Yes| D["Assign Best
Matching Category"] C -->|No| E["Leave Unclassified"] D --> F["Classification Complete"] E --> F ``` If AI can't find a good match, the ticket remains unclassified (no category assigned). You can manually assign a category anytime, including your default category for tickets that don't fit elsewhere. Auto-classification only runs when tickets are first created and don't already have a category assigned. This means: * Categories you manually set during ticket creation won't be overwritten * Categories assigned by workflows stay as you configured them * You can always manually change a category without AI changing it back *** ## Use categories ### View and assign categories Categories appear on tickets in multiple places: * **Ticket detail**: Category badge displayed in ticket attributes * **Ticket table**: Category shown as a customizable column in table view * **Ticket list**: Category shown in list view * **Analytics**: Category-based reporting and grouping While categories are typically assigned automatically, you can manually set or change a ticket's category: Open the ticket you want to categorize. Click the category field in ticket attributes. Select a different category from the dropdown. Manual assignments take precedence over auto-classification. The AI will not overwrite categories you've manually set. ### Filter and analyze Use categories to filter your ticket list and focus on specific topics. Category filters work in: * Ticket list views * Saved filters and views * Analytics dashboards Categories enable reporting capabilities: * Ticket volume by category * Resolution time by topic * Category trends over time * Team workload by category type ### With agent rules Categories can be referenced in agent rules to create conditional logic and automation based on ticket topics. Use `@` mentions to reference categories in agent rule instructions. For example: When a ticket with category @Password Reset is created, set the priority to URGENT When you mention a category in a rule, the agent gains access to that category's details (name, description, examples) as reference context. This helps the agent understand ticket topics and apply appropriate logic. Common patterns: * Auto-escalate specific categories: "When @Security Issue tickets are created, assign to Security Team" * Set priorities by topic: "For @Hardware Failure tickets, set priority to HIGH" * Conditional workflows: "If category is @Software Request, run approval workflow" ### With workflows Categories can trigger workflows when assigned or changed on tickets. Learn more about [Category Assigned workflow trigger](/documentation/automate/workflows/triggers-actions) Common workflow patterns: * Auto-assign tickets to specialized teams based on category * Set priority automatically for specific category types * Send notifications when critical categories are assigned * Route tickets through approval workflows by category *** ## Best practices Good category descriptions help AI classify tickets accurately: * **Be specific**: "Password reset requests for user accounts" * **Include context**: "Hardware issues including laptops, monitors, and peripherals" * **Use clear language**: "Software installation and license requests" * **Avoid overlap**: Keep categories distinct from each other Example phrases train the AI. Include 5-10 diverse examples using natural language that matches how your users actually describe issues: * ✅ "I can't access my email" * ✅ "Locked out of my account" * ✅ "Need to reset my password" * ❌ "password" (too generic) * ❌ "authentication failure" (too technical) * **Start small**: Begin with 5-10 core categories. You can always add more later. * **Avoid overlap**: Keep categories distinct. "Password Issues" and "Login Problems" overlap - combine them instead. * **Review regularly**: Check tickets in your default category to spot patterns that need their own category. * **Test and adjust**: Monitor classification accuracy in the first week and refine examples as needed. Many teams use both: categories for the primary topic (Password Reset, Hardware Issue) and tags for additional context like team ownership or urgency (IT Team, High Priority). *** ## Common questions No, each ticket can only have one category assigned. This ensures clear primary classification. Use tags if you need additional labels. The ticket remains unclassified (no category assigned). You can manually assign a category anytime, including your default category for tickets that don't fit elsewhere. No, classification only runs when tickets are created. To update existing tickets, manually change their categories or use bulk actions. Add more diverse example phrases that match how your users actually describe issues. Check tickets in your default category to spot misclassifications and adjust examples accordingly. Not directly, but you can use category templates which provide pre-configured categories. If you've customized categories in one workspace, you'll need to recreate them manually in others. Yes, tickets created from integrations (Linear, Jira, Notion) are classified the same way as tickets from other sources. The category exists only in Ravenna - it doesn't sync back to the integration.
## Mental model A category is a single-label classification assigned to a ticket. Every ticket can have zero or one category. Categories are workspace-scoped and AI-assigned at ticket creation time. Categories vs. tags: | | Categories | Tags | | -------------- | ---------------------------------------------------------------- | --------------------------------------- | | **Per ticket** | Zero or one | Zero or many | | **Assignment** | Automatic (AI at creation) | Manual, AI-assisted, or workflow-based | | **Purpose** | Primary topic classification | Flexible supplementary labeling | | **Mutability** | Can be changed manually or by workflow, but AI will not reassign | Can be added/removed freely at any time | Use categories for the primary "what is this request about" classification. Use tags for supplementary metadata like urgency, team ownership, or process state. *** ## Classification behavior Auto-classification runs once: when a ticket is created and has no category already set. The system analyzes the ticket's title, description, and initial messages against all category descriptions and example phrases in the workspace. **What prevents auto-classification:** * A category was manually set during ticket creation. * A workflow assigned a category before the classifier ran. * The classifier found no confident match (ticket remains unclassified, not assigned to default). **What does not trigger reclassification:** * Editing a ticket's title or description after creation. * Updating category descriptions or examples (affects future tickets only). * Adding messages to an existing ticket. Manual category changes always take precedence. The AI will never overwrite a manually assigned category. *** ## Writing effective categories Classification accuracy depends on the quality of descriptions and example phrases. **Descriptions** should define the scope clearly and specifically. "Requests to reset user passwords or unlock accounts" is better than "Password stuff." **Example phrases** should mirror how users actually describe their issues, not how support agents would categorize them: * Good: "I can't log into my email", "My account is locked out", "Need to reset my credentials" * Bad: "password", "authentication failure", "credential management" Include 5-10 diverse examples per category. Cover different phrasings of the same intent. **Avoiding overlap:** If two categories could reasonably match the same ticket, they overlap. "Password Issues" and "Login Problems" overlap significantly. Combine them into one category or make the descriptions mutually exclusive (e.g., "Password resets for self-service accounts" vs. "SSO and authentication errors with corporate login"). Start with 5-10 core categories. Review tickets landing in the default category to identify patterns that need their own category. Refine examples based on misclassifications. *** ## Integration with agent rules and workflows **Agent rules:** Reference categories in rules using `@Category Name`. When a category is mentioned in a rule, the agent gains access to that category's details as context. Common rule patterns: * Priority escalation: "When a ticket is categorized as @Security Issue, set priority to urgent and assign to the security team." * Workflow triggers: "If category is @Software Request, trigger @Software Approval Workflow." * Conditional responses: "For @Password Reset tickets, guide the user through self-service reset before escalating." **Workflows:** The "Category Assigned" trigger fires when a category is assigned to a ticket (either by AI or manually). Use this to build automation based on ticket topic, such as routing to specialized teams, setting priority, or notifying specific channels. *** ## Constraints and gotchas * One category per ticket. For multiple labels, use tags. * Every workspace requires exactly one default category. The default category cannot be deleted. * Auto-classification only runs at ticket creation. There is no bulk reclassification. Updating category descriptions or examples does not affect existing tickets. * If the classifier has no confident match, the ticket remains unclassified (no category), not assigned to the default category. The default is only assigned manually. * Deleting a category removes it from all tickets that had it. Those tickets show "No category" until manually updated. * Categories are workspace-scoped. There is no way to import categories from one workspace to another directly. Use templates for common starting sets. * Categories do not sync to external integrations. A category assigned in Ravenna does not appear in Jira, Linear, or other connected systems. * Template import supports up to 100 categories at once. # Priorities Source: https://docs.ravenna.ai/documentation/tickets/organize/priorities Use Ravenna's four ticket priority levels to organize work by urgency, prioritize the queue, and surface the right requests for your team first. Priorities help your team organize and manage tickets based on their urgency and importance. Use four priority levels to ensure the right tickets get attention at the right time. *** ## Priority levels Ravenna provides five priority levels to categorize tickets: }> Tickets that have not been assigned a priority level. These tickets should be reviewed and assigned an appropriate priority. }> Nice-to-have features, minor improvements, or issues that don't significantly impact users. These can be addressed when time permits. }> Standard priority for most tickets. These are routine requests, non-critical bugs, or general support issues that can be handled in the normal workflow. }> Important issues that should be addressed soon but aren't blocking critical operations. These might include time-sensitive requests or issues affecting key processes. }> Critical issues that require immediate attention. These are typically system outages, security incidents, or blocking issues that affect multiple users. *** ## Set priorities Priorities can be assigned in several ways: When creating a ticket, select the priority from the form field. The default priority is Medium unless configured differently on the form. Team members with appropriate permissions can update ticket priority at any time by clicking the priority field in ticket attributes and selecting a new level. Select multiple tickets from the ticket list and use bulk actions to update their priorities simultaneously. Configure workflows to automatically set or escalate priorities based on ticket content, conditions, or events. Set up agent rules to automatically assign priorities based on ticket content analysis. Priority is a required field. All tickets must have a priority assigned. The default priority is Medium unless customized in form settings. *** ## Configure default priorities Each form can have its own default priority to ensure consistent prioritization across similar ticket types. Go to **Settings > Forms** to configure default priorities. Choose the specific form you want to configure. Click **Settings** for the selected form. Navigate to the **Defaults** section within the form settings. Choose the appropriate default priority level for tickets created with this form. Click **Save** to apply the new default priority setting. **Example:** Set "Bug Report" forms to default to High priority, while "Feature Request" forms default to Low priority. *** ## Use priorities ### Filter and sort Use priorities to organize your ticket list: **Filtering** * Filter views to show only specific priority levels * Create saved filters for quick access to high-priority tickets * Use priority filters in dashboards and reports **Sorting and grouping** * Sort tickets by priority (Urgent → Low or Low → Urgent) * Group tickets by priority in list views and Kanban boards * Organize Kanban boards with priority-based columns Priority is displayed as both text labels and colored badges for easy identification. ### Workflows Use priorities in workflow conditions and actions: **Triggers** * Trigger workflows when tickets are assigned specific priorities * Create escalation workflows for urgent tickets * Set up notifications for high-priority ticket creation **Actions** * Automatically set priorities based on ticket content * Escalate priorities when tickets remain unresolved * Send priority-based notifications to different team members **Conditional logic** * Use priority as a condition in workflow rules * Create different approval processes for different priority levels * Route tickets based on priority and other criteria Learn more about [building workflows](/documentation/automate/workflows/publish) with priority conditions ### Analytics Use priorities in your analytics and reporting: * Track ticket volume by priority level * Monitor resolution times across different priorities * Analyze team performance on high-priority tickets * Identify priority trends over time * Review priority changes in ticket event history and activity logs ## Mental model Priority is a built-in ticket property with a fixed set of five levels: none, low, medium, high, urgent. Every ticket has exactly one priority. The default is medium unless a form specifies a different default. Priority is distinct from categories and tags: * **Priority** is a single fixed-enum property on every ticket. It represents urgency/importance. * **Categories** are AI-assigned topic labels (one per ticket). * **Tags** are freeform multi-labels for supplementary metadata. Priority is also distinct from SLAs. SLAs define response and resolution time targets, which can be configured per priority level, but they are separate features. *** ## Priority assignment patterns | Method | When to use | | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Form defaults** | Set per-form defaults so tickets from specific forms start at the right priority (e.g., "Incident Report" defaults to high, "Feature Request" defaults to low) | | **Agent rules** | Have the agent assess urgency from conversation context and set priority accordingly | | **Workflows** | Auto-set priority based on ticket properties (e.g., set to urgent when a specific category is assigned, escalate priority after SLA breach) | | **Manual** | User or agent sets priority during or after ticket creation | For most workspaces, form defaults handle the majority of cases. Agent rules and workflows handle the exceptions and escalations. *** ## Using priority in automation **Agent rules:** The agent can set priority based on conversation analysis. Common patterns: * "If the user reports a system outage affecting multiple people, set priority to urgent." * "For password reset requests, set priority to medium." * "If the user mentions they are blocked from working, set priority to high." **Workflow triggers:** Priority changes can trigger workflows. The "Ticket Updated" trigger with a priority filter lets you build escalation automations. **Workflow conditions:** Use priority as a branching condition in workflows. For example: if priority is urgent, notify the on-call channel and assign to the team lead. If priority is low, add to the backlog queue. **Escalation pattern:** Combine priority with time-based triggers. If a high-priority ticket is not resolved within a set time, a workflow can escalate it to urgent, reassign it, or notify management. *** ## Constraints and gotchas * Priority levels are fixed (none, low, medium, high, urgent). You cannot add, remove, or rename priority levels. * Priority is a required field. Every ticket has a priority, even if it is "none" (which represents unset). * The system-wide default priority is medium. This can be overridden per form but not globally. * Priority does not automatically affect SLA targets. SLAs can be configured to vary by priority, but changing a ticket's priority does not retroactively adjust SLA deadlines already set. * Priority does not sync bidirectionally with external integrations. If a ticket is replicated to Jira, the priority in Ravenna and the priority in Jira are independent unless a workflow explicitly maps them. # Statuses Source: https://docs.ravenna.ai/documentation/tickets/organize/statuses Track ticket progress with flexible status system including system statuses and custom sub-statuses that can be assigned to specific forms Statuses track ticket progress through your workflow. Use five system statuses as categories, then create custom sub-statuses underneath them for granular process management. Assign custom statuses to specific forms to match different workflows. *** ## System statuses Every ticket uses one of five system statuses. These categories organize your workflow and serve as groups for custom sub-statuses. }> New tickets that haven't been started. This is the default status for all newly created tickets. }> Tickets actively being worked on by team members. }> Tickets on hold or waiting for external input, customer response, or other dependencies. }> Tickets that have been completed and resolved but may need final verification. }> Tickets fully completed and archived. System statuses cannot be deleted or modified. They serve as permanent categories for organizing your workflow. *** ## Status hierarchy Ravenna uses a two-level status system: **System statuses** * Five main categories (Open, In Progress, Waiting, Done, Closed) * Available to all tickets regardless of form * Cannot be deleted or modified * Serve as groups for custom sub-statuses **Custom sub-statuses** * Created under system status categories * Must be assigned to specific forms to be usable * Provide granular tracking for specific processes * Each form can have different available sub-statuses This hierarchy lets you create detailed status flows for different ticket types while maintaining consistent top-level categories across your organization. *** ## Create custom statuses Custom sub-statuses provide specific status options beyond the five system statuses. After creating a custom status, assign it to forms to make it available for tickets. Go to **Settings > Statuses** to access status management. Click **Add** to open the create status modal. Enter a label for your custom status and select which system status it belongs under. Click **Save** to create the status. Custom statuses won't be usable until assigned to forms. Continue to the next section to assign them. Status labels must be unique across your workspace. You can't create or rename a sub-status to a label that's already used by another status, even if that status sits under a different system status group. ### Assign statuses to forms Custom statuses must be assigned to specific forms before they appear as options on tickets. Go to **Settings > Forms** to configure form statuses. Select the form you want to configure. Navigate to the **Statuses** section for that form. Select which custom sub-statuses should be available for tickets created with this form. Click **Save** to apply the status configuration. **Example:** Create "Needs Review" and "Testing" sub-statuses under "In Progress", then assign them to your Bug Report form. Feature Request forms can have different sub-statuses like "Planning" and "Awaiting Approval". *** ## Use statuses ### Set status during creation When creating a ticket: * Default status is **Open** * Available statuses include all system statuses plus custom sub-statuses assigned to the selected form * Status can be changed immediately after creation ### Change status Update status from the ticket detail page: Navigate to the ticket you want to update. Click the status field and select the new status from the dropdown. The status change saves automatically and records in ticket history. Update multiple tickets at once: From the ticket list, select multiple tickets using checkboxes. Click the bulk actions menu. Select "Update Status" and select the new status. Confirm to apply the status change to all selected tickets. Send a reply and resolve the ticket in a single action using the **Send and resolve** option in the message composer. Click the dropdown arrow next to the **Send** button in the message composer. Select **Send and resolve** from the menu. This becomes the default action for subsequent messages. Click the button or press **Mod+Enter** to send the message publicly and set the ticket status to **Done**. Configure workflows to automatically update statuses based on ticket events, conditions, or actions. Common patterns: * Auto-progress to "In Progress" when ticket is assigned * Move to "Waiting" when requesting customer information * Change to "Done" when resolution is posted *** ## Organize with statuses Use statuses to organize and filter your ticket list. ### Filter by status Use status filters in views to focus on relevant tickets: * Filter by specific status or status group * Show only tickets with certain statuses * Exclude tickets with specific statuses * Create saved filters for quick access ### Group and sort **List and table views** * Group tickets by status for better organization * Collapse or expand status groups * See ticket counts per status * Sort by status in alphabetical or custom order **Kanban view** * Organize tickets in columns by status * Drag and drop tickets between status columns * Visual process management with status-based workflow *** ## Form-specific configurations Different forms can have different available statuses to match their workflows. **Bug reports** might use: * Open → In Progress → Needs Review → Done → Closed **Feature requests** might use: * Open → Planning → In Progress → Testing → Done → Closed **Support tickets** might use: * Open → In Progress → Waiting → Done → Closed System statuses are always available to all forms. Custom sub-statuses must be explicitly assigned to each form where they should appear. Learn more about [building workflows](/documentation/automate/workflows/publish) with status conditions and actions ## Mental model Status is a two-level system: five fixed system statuses and optional custom sub-statuses underneath them. **System statuses (fixed, always available):** | Status | Meaning | Active/Resolved | | --------------- | --------------------------------------- | --------------- | | **Open** | New, unstarted ticket | Active | | **In Progress** | Actively being worked on | Active | | **Waiting** | Blocked on external input or dependency | Active | | **Done** | Resolved, may need verification | Resolved | | **Closed** | Fully completed and archived | Resolved | Every ticket has exactly one status at any time. The default status for new tickets is Open. **Custom sub-statuses** nest under a system status and provide granular tracking. A sub-status like "Needs Review" under "In Progress" inherits the system status semantics (still active, still in progress) while adding process detail. Sub-statuses are workspace-scoped but form-gated: they must be explicitly assigned to specific forms before tickets using those forms can use them. Different forms can have different sub-statuses available, enabling form-specific workflows within the same workspace. *** ## Custom sub-status design patterns Design sub-statuses around the distinct workflows in your workspace: **Approval-heavy workflows (e.g., access requests):** * Open → Pending Approval (under Waiting) → Approved (under In Progress) → Provisioned (under Done) → Closed **Development workflows (e.g., bug reports):** * Open → Investigating (under In Progress) → Fix in Progress (under In Progress) → Needs Review (under In Progress) → Done → Closed **External dependency workflows (e.g., vendor requests):** * Open → In Progress → Waiting on Vendor (under Waiting) → Vendor Responded (under In Progress) → Done → Closed When designing sub-statuses, keep them scoped to the forms that need them. A "Needs Review" sub-status is relevant for bug reports but not for password reset requests. This prevents status dropdowns from becoming cluttered with irrelevant options. *** ## Status in automation **Workflow triggers:** The "Status Changed" trigger fires when a ticket's status changes. You can filter on specific status transitions (e.g., only fire when status changes to Done). **Workflow actions:** The "Set Status" action changes a ticket's status as part of a workflow. Use it for auto-progression (e.g., set to "In Progress" when assigned, set to "Done" when an approval is completed). **Agent rules:** The agent can set ticket status based on conversation context. Common patterns: * "When you resolve a user's issue, set the ticket status to Done." * "If the user says they need to check with their manager, set status to Waiting." **Status-driven patterns:** * Trigger a CSAT survey when status changes to Done. * Notify the requester when status changes from Waiting to In Progress. * Auto-close tickets that have been in Done status for a configured period. *** ## Constraints and gotchas * The five system statuses (Open, In Progress, Waiting, Done, Closed) cannot be renamed, deleted, or reordered. They are permanent. * Custom sub-status labels must be unique within a workspace. Two sub-statuses cannot share the same label, even if they sit under different system status groups. Ravenna rejects any attempt to create or rename a sub-status to a label that's already in use. * Custom sub-statuses must be assigned to forms before they can be used. Creating a sub-status alone does not make it available on any ticket. * A sub-status inherits the semantics of its parent system status. A sub-status under "Done" is considered resolved regardless of its name. * Tickets can transition between any statuses freely. There are no enforced status transition rules (e.g., you can go from Open directly to Closed). Enforce transitions through workflow logic if needed. * Kanban board columns map to statuses. Each status (system or custom) becomes a column. * Bulk status updates apply the same status to all selected tickets. If tickets span different forms with different available sub-statuses, only commonly available statuses will be selectable. * Status changes are recorded in ticket history with timestamps. This data is available in analytics for tracking resolution times and workflow efficiency. # Tags Source: https://docs.ravenna.ai/documentation/tickets/organize/tags Tag tickets with flexible workspace-specific labels to track ticket types, departments, projects, or any classification system your team needs. Tags are flexible labels for organizing tickets. Each workspace can create its own set of tags, and tickets can have multiple tags assigned. Use tags to track ticket types, departments, priority levels, or any classification system that works for your team. *** ## Create tags Go to **Settings > Tags** in your workspace. Click **New Tag** to open the creation form. Set the tag properties: * **Name**: The tag label that appears on tickets * **Description**: Optional context about when to use this tag * **Color**: Visual identifier to distinguish tags Click **Create** to add the tag to your workspace library. You can modify tag names and colors at any time. Changes automatically update across all tickets using that tag. *** ## Add tags to tickets When creating a new ticket, assign existing tags from your workspace's tag library in the tags field. Once a ticket is created, you have several options: **Direct assignment**: Click the tags section to add existing tags or create new ones **Keyboard shortcut**: Use **Option+T** (Mac) or **Alt+T** (Windows) to quickly assign tags without leaving the ticket page Assign tags directly from the ticket list view without opening individual tickets. Select multiple tickets for bulk tagging. Use workflows to automatically apply tags based on ticket properties or events. Configure AI agents to suggest or apply tags based on ticket content. *** ## Filter with tags Filter the ticket list by specific tags to focus on relevant tickets. Tag filters work in: * Ticket list views * Saved filters * Analytics dashboards Use tag filters to find tickets by department, type, or any classification system you've established. *** ## Tags vs categories While both help organize tickets, they serve different purposes: | Feature | Tags | Categories | | -------------- | -------------------------------------- | ---------------------------------- | | **Assignment** | Manual, AI-assisted, or workflow-based | Automatic via AI | | **Purpose** | Flexible labeling | Primary classification | | **Limit** | Multiple per ticket | One per ticket | | **Examples** | "Urgent", "VIP", "Needs Review" | "Password Reset", "Hardware Issue" | Learn more about [Categories](/documentation/tickets/organize/categories) for AI-powered automatic classification *** ## Best practices Begin with a few essential tags and expand as needed. Too many tags can make organization more difficult. Common starting tags: * Priority levels (High, Medium, Low) * Departments (IT, HR, Finance) * Status indicators (Needs Review, Approved, Escalated) Assign colors based on purpose or urgency: * Blue for IT requests * Green for HR inquiries * Red for security issues * Yellow for pending items Consistent color usage helps teams quickly identify ticket types. Create clear tag naming standards for your team: * Use consistent capitalization * Avoid abbreviations unless widely understood * Keep names concise but descriptive * Document tag purposes in descriptions Consistency ensures everyone uses tags the same way. Periodically review your tag usage: * Identify rarely used tags for removal * Consolidate overlapping tags * Add new tags based on emerging patterns * Update descriptions as usage evolves Tags are workspace-specific. Each workspace can have its own tagging system tailored to that team's needs. ## Mental model Tags are multi-label, workspace-scoped labels that can be applied to tickets. A ticket can have zero or many tags. Tags are never automatically assigned by the classification system (that is what categories do), but they can be applied by agents, workflows, bulk actions, or the AI Tags channel setting. | | Tags | Categories | | ----------------------------- | ----------------------------------------------- | ---------------------------- | | **Per ticket** | Zero or many | Zero or one | | **Auto-assigned at creation** | No (unless AI Tags channel setting or workflow) | Yes (AI classifier) | | **Purpose** | Supplementary metadata | Primary topic classification | | **Scope** | Workspace | Workspace | Use tags when you need multiple overlapping labels on the same ticket, or for metadata that does not represent the ticket's primary topic (e.g., process state, team ownership, urgency indicators). *** ## Assignment methods Tags can be applied through several mechanisms: | Method | When it applies | | --------------------------- | -------------------------------------------------------------------------------------------------------- | | **Manual** | User adds tags during ticket creation or on an existing ticket | | **Bulk action** | User selects multiple tickets and applies tags at once | | **AI Tags channel setting** | Channel setting that automatically extracts and applies tags based on message content at ticket creation | | **Agent rules** | Agent applies tags based on conversation context or rule logic | | **Workflows** | "Add Tag" or "Set Tags" workflow actions apply tags based on trigger conditions | | **Keyboard shortcut** | Option+T (Mac) or Alt+T (Windows) on the ticket page | The AI Tags channel setting and workflow-based tagging are the two automated methods. AI Tags analyzes the initial message content and applies relevant tags from the workspace library. Workflow-based tagging uses the Tags Changed trigger or applies tags as an action step. *** ## Common tagging patterns **By process state:** "Needs Review", "Approved", "Escalated", "Waiting on Vendor". Useful when statuses alone do not capture the full lifecycle. **By team ownership:** "IT Team", "Security", "HR". Useful when tickets in a single channel may be handled by different sub-teams. **By request source or type:** "VIP", "Executive", "Compliance", "Audit". Useful for flagging tickets that need special handling regardless of category. **By automation state:** "Auto-resolved", "Agent-handled", "Escalated-to-human". Useful for tracking AI agent effectiveness and intervention rates. Tags and categories work well together. Categories handle the "what is this about" question (Password Reset, Hardware Issue). Tags handle the "what else is true about this" question (VIP, Escalated, IT Team). *** ## Integration with workflows and rules **Workflow triggers:** The "Tags Changed" trigger fires when tags are added to or removed from a ticket. Use this to build automation like notifying a channel when a ticket is tagged "Escalated" or assigning tickets when tagged with a team name. **Workflow actions:** The "Add Tag" and "Set Tags" actions apply tags as part of a workflow. "Add Tag" appends to existing tags. "Set Tags" replaces all existing tags. **Agent rules:** Reference tags in agent rules to instruct the agent to apply tags based on conversation context. For example: "When a user mentions a security concern, add the Security tag." The agent can also read existing tags on a ticket to inform its responses. *** ## Constraints and gotchas * Tags are workspace-scoped. Tags created in one workspace are not available in another. * Renaming a tag updates the name across all tickets that have it. No tickets lose the tag. * Deleting a tag removes it from all tickets. There is no "reassign to another tag" step like there is for channels. * There is no limit on the number of tags per ticket, but excessive tagging reduces usefulness. Aim for 1-5 tags per ticket as a practical guideline. * Tag filters in views use AND logic. If you filter by two tags, only tickets with both tags appear. * The AI Tags channel setting applies tags at ticket creation only. It does not re-tag existing tickets when messages are added. * Tags do not sync to external integrations. Tags applied in Ravenna do not appear in Jira, Linear, or other connected systems. # Types Source: https://docs.ravenna.ai/documentation/tickets/organize/types Categorize tickets with five ITSM-aligned types including service request, incident, problem, change, and major incident for consistent handling. Types help categorize tickets based on the kind of request or issue they represent. Use five type options to align with ITSM workflows and ensure consistent handling across different request categories. *** ## Type options Ravenna provides five type options to categorize tickets: Standard service requests for routine support needs. This is the default type for all tickets unless configured differently. **Examples:** * Software access requests * Hardware provisioning * General support inquiries * Feature requests Unplanned interruptions or reductions in service quality that require immediate attention to restore normal operations. **Examples:** * System outages * Application errors * Service degradation * Access issues blocking work Root cause investigations for recurring incidents or systemic issues requiring analysis and long-term resolution. **Examples:** * Recurring system failures * Performance bottlenecks * Architecture deficiencies * Known error documentation Planned modifications to systems, infrastructure, or processes that require approval and coordination. **Examples:** * Configuration updates * System upgrades * Infrastructure changes * Policy modifications Requests for granting, modifying, or revoking access to systems, applications, or resources. **Examples:** * Application access provisioning * Permission changes * Account deactivation * Security group modifications *** ## Set types Types can be assigned in several ways: When creating a ticket, select the type from the form field. The default type is Service unless configured differently on the form. Team members with appropriate permissions can update ticket type at any time by clicking the type field in ticket attributes and selecting a new value. Select multiple tickets from the ticket list and use bulk actions to update their types simultaneously. Configure workflows to automatically set or change types based on ticket content, conditions, or events. Set up agent rules to automatically assign types based on ticket content analysis. Type is a required field. All tickets must have a type assigned. The default type is Service unless customized in form settings. *** ## Configure default types Each form can have its own default type to ensure consistent categorization across similar ticket types. Go to **Settings > Forms** to configure default types. Choose the specific form you want to configure. Click **Settings** for the selected form. Navigate to the **Defaults** section within the form settings. Choose the appropriate default type for tickets created with this form. Click **Save** to apply the new default type setting. **Example:** Set "Incident Report" forms to default to Incident type, while "Software Access" forms default to Access type. *** ## Use types ### Filter and sort Use types to organize your ticket list: **Filtering** * Filter views to show only specific types * Create saved filters for quick access to incident or access request tickets * Use type filters in dashboards and reports **Sorting and grouping** * Sort tickets by type * Group tickets by type in list views and Kanban boards * Organize Kanban boards with type-based columns Type is displayed with icons and text labels for easy identification. ### Workflows Use types in workflow conditions and actions: **Triggers** * Trigger workflows when tickets are assigned specific types * Create specialized workflows for incident or change tickets * Set up notifications for access request creation **Actions** * Automatically set types based on ticket content * Change types when conditions are met (such as escalating a service request to an incident) * Route tickets to different teams based on type **Conditional logic** * Use type as a condition in workflow rules * Create different approval processes for change requests * Route tickets based on type and other criteria Learn more about [building workflows](/documentation/automate/workflows/publish) with type conditions ### Analytics Use types in your analytics and reporting: * Track ticket volume by type * Monitor resolution times across different types * Analyze team performance on incidents versus service requests * Identify type trends over time * Review type changes in ticket event history and activity logs ## Mental model Type is a built-in ticket property with a fixed set of five values: service, incident, problem, change, access. Every ticket has exactly one type. The default is service unless a form specifies a different default. Type is distinct from categories and tags: * **Type** is a single fixed-enum property representing the kind of request (service, incident, problem, change, access). * **Categories** are AI-assigned topic labels (one per ticket). * **Tags** are freeform multi-labels for supplementary metadata. Type helps align Ravenna tickets with ITSM workflows and enables reporting, automation, and routing based on the nature of the request. *** ## Type assignment patterns | Method | When to use | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Form defaults** | Set per-form defaults so tickets from specific forms start with the right type (for example, "Incident Report" defaults to incident, "Software Access" defaults to access) | | **Agent rules** | Have the agent assess the request from conversation context and set type accordingly | | **Workflows** | Auto-set type based on ticket properties (for example, set to incident when specific keywords are detected, change type from service to problem when recurring pattern is identified) | | **Manual** | User or agent sets type during or after ticket creation | For most workspaces, form defaults handle the majority of cases. Agent rules and workflows handle the exceptions and reclassification. *** ## Using type in automation **Agent rules:** The agent can set type based on conversation analysis. Common patterns: * "If the user reports a system outage affecting multiple people, set type to incident." * "For access requests to applications, set type to access." * "If the user mentions a recurring issue, set type to problem." **Workflow triggers:** Type changes can trigger workflows. The "Ticket Updated" trigger with a type filter lets you build specialized automations for different kinds of request. **Workflow conditions:** Use type as a branching condition in workflows. For example, if type is incident, notify the on-call team and set priority to high. If type is access, route to the IAM team and require approval. **Type-based routing:** Combine type with channel or assignment rules to automatically route tickets to specialized teams (incidents to operations, access requests to security, changes to change management). *** ## Constraints and gotchas * Type values are fixed (service, incident, problem, change, access). You cannot add, remove, or rename type options. * Type is a required field. Every ticket has a type, defaulting to service if not specified. * The system-wide default type is service. This can be overridden per form but not globally. * Type does not sync bidirectionally with external integrations. If a ticket is replicated to Jira, the type in Ravenna and the type in Jira are independent unless a workflow explicitly maps them. * Changing a ticket's type does not retroactively affect workflows or automations that already executed. It only affects future workflow evaluations. # Views Source: https://docs.ravenna.ai/documentation/tickets/organize/views Save personalized ticket views with display preferences, filters, and sort settings to streamline triage and recurring workflows in Ravenna. Views organize tickets by saving your display preferences, filters, and sorting settings. Each view provides quick access to different workflows and ticket organizations. *** ## Display modes Views support three display modes: Detailed analysis with customizable columns. Choose which fields to display and adjust column widths for your preferred layout. Custom fields are hidden by default and are grouped separately in the column visibility menu, where you can show or hide them individually. **Edit fields inline** Update a ticket without leaving the table view. Click any editable cell to change the value in place — Ravenna saves the change immediately and re-renders the row with the new value. You can edit the following columns inline: * **Due date** and **Start date** * **Custom fields** of type Text, Number, Date, Boolean (toggle), Select, and Multi-select Other custom field types (User, Application, Access level, File, and similar resource pickers) stay read-only in the table. Open the ticket to edit them from the detail view. Cells become read-only when you don't have permission to edit that ticket, so members with view-only access still see the values without an editable affordance. Streamlined readability with essential ticket information. Compact format for scanning through tickets quickly. Visual workflow management with columns organized by status or other criteria. Drag tickets between columns to update their status. Collapse columns to focus on specific workflow stages. **Collapse and expand columns** Collapse columns you're not actively working with by clicking in the column header. Collapsed columns display vertically with the column name and ticket count. Expand collapsed columns by clicking anywhere on them or the expand button. Empty columns collapse by default. Your preferences save per view and don't affect other team members. Dropping a ticket on a collapsed column expands it automatically. *** ## Create views Create views to save specific configurations for different workflows or responsibilities. Click the **+** button in the Views section of your sidebar. Set the view name and add an optional emoji. Choose whether the view should be private (visible only to you) or shared with your workspace. On a shared view, toggle **Allow edits** to control whether other workspace members can promote their changes back to the shared configuration. **Allow edits** is off by default, so only the view's owner and workspace admins can save changes for everyone. See [Lock shared views](#lock-shared-views) for details. Click **Create** to save the view. It appears in your sidebar navigation. ### Create a view inside a collection You can also create a view directly inside an existing collection instead of at the top of the Views section. Right-click the collection (folder) in the sidebar, or open its menu. Select **New view**. The create dialog opens with the new view already assigned to that collection. Set the name, emoji, and any other options, then click **Create**. The view appears inside the collection in your sidebar. The new view inherits the collection's privacy. Creating a view inside a private collection produces a private view; creating one inside a shared collection produces a shared view. You can't override this on creation because private views can only live in private collections, and shared views can only live in shared collections. Views appear in your sidebar navigation and can show unread ticket counts for new activity. *** ## Customize views Configure how tickets are filtered, grouped, and sorted in each view. Apply filters to focus on relevant tickets: * **ID** and **Short ID**: Filter by a ticket's full ID or its short ID using **equals**, **does not equal**, **is any of**, or **is not any of**. Use this to jump to specific tickets, exclude known ones, or pull a list referenced from another tool (for example, paste a set of short IDs from a spreadsheet). * **Status**: Filter by open, resolved, or closed tickets * **Assignee**: Show tickets assigned to specific team members. Use the **is member of** or **is not member of** operator with this filter, or with **Requestor** or **Author**, to match tickets whose user belongs to one or more selected user groups. This is useful for following a team rather than a single person. * **Priority**: Focus on high, medium, or low priority tickets * **Due date**: View tickets due within specific time ranges, or filter for tickets with no due date set * **Channel**: Filter tickets from specific channels * **Category**: Filter by ticket category * **Tags**: Filter by ticket tags * **CSAT score**: Filter tickets by their CSAT score (1-5 stars), or filter for tickets without a score * **SLA**: Filter tickets by the SLA applied to them. * **SLA Outcome**: Filter by whether the SLA was **Met** or **Breached**. Use this to surface tickets that missed their target or confirm compliance. * **SLA target**: Filter tickets by which SLA target types they have — Time to first response, Time to resolution, or Time to close. You can also filter for tickets that have any SLA target applied, or tickets with no SLA targets at all. Use this to focus on a specific commitment type (for example, only tickets tracked for first response). * **SLA Target Outcome**: Filter by one SLA target and its outcome together, such as **Time to First Response met** or **Time to Resolution breached**. Each value binds a single target type to a single outcome. Add two of these conditions to match tickets that met one target but breached another (for example, first response met and resolution breached), which the separate **SLA target** and **SLA Outcome** filters cannot express. Supports the **is**, **is not**, **is one of**, and **is not one of** operators. * **Breaching Within**: Filter for tickets with an active SLA target that will breach within a duration you set in minutes, hours, or days. Only pending targets that breach between now and the threshold match. Tickets that have already breached are excluded, so use **SLA Outcome** for those. Use this to build an at-risk queue, for example, tickets breaching within the next hour. * **AI Outcome**: Filter by how much of the ticket an AI agent handled: **Resolved** (the agent handled it end-to-end), **Assisted** (the agent did substantive work but a human finished it), **Escalated** (the agent handed off without contributing), or **Not Applicable** (nobody asked for help, such as spam or a monitoring alert). Tickets the classifier has not reached yet are excluded. * **Custom fields**: Filter by any custom field values Group tickets into logical categories: * **Status**: Group by ticket status * **Assignee**: Group by assigned team member * **Assignee group**: Group by the user group that the assignee belongs to * **Priority**: Group by priority level * **Parent ticket**: Group by parent ticket relationships * **Channel**: Group by channel * **Category**: Group by ticket category * **AI Outcome**: Group by AI outcome (Resolved, Assisted, Escalated, Not Applicable, or Not Computed) * **Custom fields**: Group by custom field values Sort tickets to prioritize your work: * **Creation date**: Newest or oldest first * **Priority**: Highest or lowest priority first * **Due date**: Soonest or latest due date first * **Title**: Alphabetical order * **Updated date**: Most recently updated first * **CSAT score**: Highest or lowest customer satisfaction rating first * **AI Outcome**: Group tickets with the same AI outcome together * **Custom fields**: Sort by any sortable custom field on the workspace's forms. Text, Text area, Number, Date, Time, Duration, Boolean, Select, and Timezone select fields appear under the **Custom Fields** group in the sort menu. Select and Duration fields sort by the display order of their options, so ascending puts the first-defined option first. Timezone select fields sort as text. Multi-select, Tag, and User fields aren't sortable. When you modify filters, display modes, grouping, or sorting for a view, your changes persist automatically. Your configuration is preserved every time you return to that view. In table views, clicking **Reset Columns** restores default column visibility and hides any custom field columns. You can re-show custom fields from the column visibility menu. Use the search box at the top of the menu to quickly find a column by name when you have many fields. ### Personal overrides on shared views On any custom view (any view other than the workspace default), your filter and display-option changes are saved as a **personal override** that only affects you. The shared view's saved configuration stays the same for everyone else until you explicitly promote your changes. Personal overrides cover: * **Filters** added, removed, or edited from the filter bar * **Display mode** (Table, List, or Kanban) * **Column visibility, column order, and column widths** in table views * **Grouping** and **sorting** This lets you adjust a shared view to your workflow without disrupting teammates. For example, you can narrow **My team's open tickets** to just your channel for the afternoon, and no one else sees the change. **Save or reset your overrides** When you have unsaved filter changes on a custom view, **Save** and **Reset** buttons appear next to the filter bar: * **Save** promotes your current filters to the shared view's configuration. Everyone using the view sees the new filters the next time they load it. * **Reset** discards your personal filter overrides and reverts to the shared view's saved filters. The view options menu shows an indicator when your column, grouping, sorting, or display-mode choices differ from the shared view. From that menu you can: * **Save view options to view** to push your current display settings to the shared view. * **Reset view options** to discard your personal display overrides and return to the shared configuration. The **workspace default view** does not use personal overrides. Filter and display-option changes there save directly to the view and apply to anyone who hasn't customized it. Personal overrides are stored per user, per view. They follow you across browsers and sessions, and they don't affect other workspace members. ### Lock shared views Shared views have an **Allow edits** toggle that controls whether other workspace members can promote their personal overrides back to the shared configuration. * When **Allow edits** is **off** (the default), the **Save**, **Save for all**, and **Save view options to view** actions are hidden from non-owner, non-admin members. Everyone can still tweak filters, columns, sorting, and display mode for themselves — those tweaks continue to save as [personal overrides](#personal-overrides-on-shared-views) — but only the owner and workspace admins can push those changes into the shared view. * When **Allow edits** is **on**, any workspace member who uses the view can save their changes back to the shared configuration, matching the previous default behavior. The view's owner and workspace admins always bypass the lock. They see **Save** and **Save view options to view** regardless of the **Allow edits** setting. Toggle **Allow edits** from the view's edit dialog. You can change it at any time, and it takes effect immediately for everyone using the view. Locking a shared view only affects who can promote changes for the whole team. Personal overrides — filters, columns, sorting, grouping, and display mode scoped to you — keep working exactly the same way for every member. ### Duplicate views Any workspace member can duplicate a view from the sidebar to create their own copy without touching the original. To duplicate a view, hover over it in the sidebar, open its menu, and select **Duplicate**. The copy appears in the sidebar named ` (copy)`. **What the copy inherits** * The duplicate is created **private** and owned by you, so it only shows up in your sidebar. * **Allow edits** is off, matching the default for new shared views. If you later make the copy shared, other members won't be able to promote changes to it unless you turn **Allow edits** on. * The duplicate captures **your effective view** — the shared view's saved configuration overlaid with your personal filter and display overrides. This means the copy reflects what you were actually looking at, including any filters you narrowed, columns you toggled, or sort orders you changed for yourself. It does not just clone the owner's shared definition. * The emoji, table (Tickets, Users, and so on), and containing collection are copied from the original. Duplicating is useful when you want to fork a shared view to experiment with different filters, keep a personal variant of a locked team view, or hand a starting point to another teammate by making your copy shared later. ### Hide views from your sidebar You can hide any view from your own sidebar without affecting anyone else. Hiding is a personal preference stored per user, so other members still see the view in their sidebars, routing is unchanged, and every ticket the view matches is still accessible from the view's URL, search, and other surfaces. To hide a view, right-click it in the sidebar (or open its menu) and select **Hide**. The view moves into a collapsible **Hidden** group at the bottom of the Views section. Expand **Hidden** to see everything you've hidden, then right-click a view there and select **Unhide** to bring it back to its previous position. Use this to declutter your sidebar when you have shared views that don't apply to your work, without deleting them for teammates who rely on them. ### Edit and delete views Workspace members can edit shared views. Private views can only be edited by their owner. To delete a view, click the view options menu and select **Delete**. Private views can only be deleted by their owner. Shared views can be deleted by any workspace member. *** ## Create tickets from a view When you create a ticket while a view is active, Ravenna pre-fills the new ticket form with values from the view's filters. This saves you from re-entering fields that are already implied by the view you're working in. **How defaults are applied** Ravenna looks at each filter on the active view and pre-fills the matching field on the new ticket when: * The filter uses an **equals** or **is any of** operator. * The filter targets a single value (for example, *Assignee equals Alex*, not *Assignee is any of Alex, Sam*). Ravenna can pre-fill the following fields: * Assignee * Status * Priority * Category * Tags (all tag values from matching filters are added) If a filter matches multiple values or uses a different operator (such as *is not* or *contains*), Ravenna skips that field. **Where this applies** * **Ticket list and table views**: clicking **New ticket** opens the create dialog with defaults from the view's filters. * **Kanban views**: clicking **+** on a column adds the column's grouping value (status, priority, or assignee) on top of the view's filter defaults. Column values take precedence when both are set. You can still change any pre-filled field before submitting the ticket. Defaults only seed the form — they don't constrain what you can create. Ravenna only applies filter defaults to new tickets. They have no effect when you duplicate an existing ticket. *** ## Organize with collections View collections provide a folder-like structure for organizing multiple related views. Collections reduce clutter in your sidebar navigation by grouping related views together. ### Create collections Click the **+** button in the Views section of your sidebar and select **New Collection**. Give it a descriptive name based on the views you'll group (e.g., "Project Alpha", "Support Team", "Weekly Reviews"). Choose private or shared. Private views can only be placed in private collections. Public views can only be placed in public collections. Drag and drop views into the collection from your sidebar. Collections can be edited and deleted by their owner or any workspace member (for shared collections). Private collections can only be managed by their owner. ### Add views to a collection Once a collection exists, you can populate it two ways: * **Drag and drop** an existing view from your sidebar into the collection. * **Right-click the collection** (or open its menu) and select **New view** to create a view directly inside the collection. See [Create a view inside a collection](#create-a-view-inside-a-collection). The new view inherits the collection's privacy. *** ## Work with views ### Switch views Click any view in the sidebar to instantly apply its configuration. This updates your filters, grouping, sorting, and display mode to match the selected view's settings. ### Export tickets Export tickets from any view to a CSV file for reporting or analysis. Navigate to the view containing the tickets you want to export. Click the **Export** button in the toolbar. The CSV file downloads with all tickets matching the current view's filters. The file is named using the view name and current date (e.g., `My_Tickets_2026-01-13.csv`). **What's included in the export** Each row in the CSV represents one ticket. Exported columns mirror the columns currently visible in the view's table configuration. Hiding a column from the table excludes it from the export, and showing a column adds it back. This gives you control over which fields land in the CSV without filtering the resulting file afterward. Available columns cover the core ticket properties used across views, including: * Ticket ID, title, and description * Status, priority, category, and tags * Channel and workspace * Requester and assignee * Created, updated, due, and resolution timestamps * SLA name and current SLA outcome (On Track, Alert, Breached, or Met) * CSAT score (when available) * Custom field values configured on the ticket's form **Custom field columns** Each custom field you've added to the view appears as its own column in the CSV, using the field's label as the header. Values are formatted to match how they display in Ravenna: * **Select** and **Duration**: the selected option's label (e.g., `Critical`). * **Multi-select**, **Tag**, **User multi-select**, and **Application multi-select**: a comma-separated list of labels (e.g., `Frontend, Backend`). * **Boolean**: `Yes` or `No`. * **Date**: `YYYY-MM-DD`. * **Text**, **Number**, and other single-value types: the raw value. Empty custom fields export as a blank cell. Hide a custom field column from the table before exporting if you don't want it in the CSV. To customize what gets exported, adjust column visibility from the view's table settings before clicking **Export**. Shared views use the shared column configuration, so changes affect every member who uses that view. The export honors the view's active filters, so applying filters such as status, assignee, or SLA outcome before exporting limits the file to a focused dataset. ### Share view URLs Views are accessible through direct URLs. Bookmark specific views or share them with team members by copying the URL from your browser. Switching views updates the browser URL automatically. ### Unread notifications Views display notification badges showing the count of unread tickets that match the view's criteria. These badges indicate which views contain new activity. ## Mental model A view is a saved lens over a workspace's tickets. Views do not contain tickets. They define a combination of filters, sorting, grouping, and display mode that determines which tickets are shown and how. The underlying ticket data is the same regardless of which view is active. Key distinction: channels are containers (every ticket belongs to exactly one channel), while views are filters (a ticket can appear in many views simultaneously if it matches their criteria). Views belong to a workspace. They can be private (visible only to the creator) or shared (visible to all workspace members). Collections group related views into folders in the sidebar. Custom views (any view except the workspace default) layer two configurations: the **shared view configuration** that everyone sees, and an optional **personal override** for the current user. When a user tweaks filters, display mode, columns, grouping, or sorting, the change is stored as their personal override and does not affect anyone else. The user must explicitly **Save** filter changes or **Save view options to view** to promote their override into the shared configuration; **Reset** clears the override and falls back to the shared configuration. The workspace default view does not support personal overrides — changes there save directly to the shared configuration. Shared views additionally carry an **Allow edits** flag. When it is off (the default for new views), the **Save** / **Save view options to view** actions are hidden from non-owner, non-admin members, so only the owner and workspace admins can promote personal overrides into the shared configuration. Personal overrides themselves are unaffected — every member can still adjust the view for themselves. Duplicating a view is available to any member and creates a private, `allowEdit: false` copy owned by the caller, seeded with the caller's *effective* configuration (shared config overlaid with their personal overrides) rather than the raw shared definition. *** ## View design recommendations **Common shared views for a workspace:** | View name | Filters | Grouping | Purpose | | -------------------- | ------------------------------------ | -------- | --------------------------------- | | Unassigned | Assignee: none, Status: open | Channel | Triage queue for incoming tickets | | My tickets | Assignee: current user, Status: open | Priority | Personal work queue | | High priority | Priority: high/urgent, Status: open | Assignee | Escalation visibility | | Waiting on requester | Status: waiting | Due date | Follow-up tracking | | Recently resolved | Status: done, Updated: last 7 days | Channel | Review and quality check | **When to create a new view vs. use an existing one:** * Create a new view when a team member or team needs a repeatable way to see a specific slice of tickets. * Do not create views for one-off queries. Ad-hoc filtering without saving serves that purpose. * Shared views are better for team workflows (triage, escalation). Private views are better for individual preferences (my assignments, my channels). **Display mode selection:** * Table for data-heavy analysis, reporting, and when custom field columns matter. * List for quick scanning and high-volume ticket processing. * Kanban for status-driven workflows where dragging tickets between stages is the primary interaction. *** ## Filter and grouping patterns Effective views combine filters and grouping to answer specific questions: **Triage pattern:** Filter by status (open) and assignee (none). Group by channel or category. This surfaces all unhandled tickets organized by where they came from or what they are about. **Workload balancing:** Filter by status (open, in progress). Group by assignee. This shows how tickets are distributed across the team and highlights imbalances. **SLA monitoring:** Filter by SLA outcome (Alert or Breached) to focus on tickets that need immediate attention, or filter by a specific SLA to track compliance for a single agreement. Filter by SLA target to narrow to a specific commitment type, such as Time to first response or Time to resolution. You can also isolate tickets with no SLA targets at all. Use **SLA Target Outcome** to bind one target to one outcome, such as Time to Resolution breached; stacking two of these conditions finds tickets that met one target but breached another, which the independent SLA target and SLA outcome filters cannot express. Use **Breaching Within** to catch tickets before they breach: it matches tickets whose pending SLA target breaches within the duration you set (for example, 30 minutes), and excludes tickets that have already breached. Combine with sorting by due date (soonest first) to prioritize work. **Cross-channel oversight:** No channel filter, group by channel. This gives a workspace-wide view of ticket distribution across channels. Filters use AND logic. All active filters must match for a ticket to appear. There is no OR logic within a single view. To see tickets matching either condition A or condition B, create two separate views. *** ## Collections Collections are folders for views. Use them when a workspace has enough views that the sidebar becomes cluttered. Recommended collection patterns: * **By role:** "Managers", "On-call", "New hires" with views tailored to each role's needs. * **By process:** "Triage", "Escalation", "Review" grouping views by workflow stage. * **By project or initiative:** Temporary collections for time-bound efforts. Privacy rules: private views can only go in private collections. Shared views can only go in shared collections. You cannot mix privacy levels within a collection. Views can be added to a collection two ways: by dragging an existing view into the collection, or by using the collection's context menu action **New view**, which creates a view directly inside that collection. A view created via **New view** inherits the collection's privacy — private in a private collection, shared in a shared collection — and this is enforced server-side. *** ## Personal sidebar visibility Each workspace member can hide individual channels and views from their own sidebar. The preference is stored per user on the workspace member record and has no effect on other members, on ticket routing, or on access. A hidden view is still reachable by URL, search, and any other surface that references it; hiding only affects sidebar rendering for the user who set it. The hide action is available from the sidebar row's context menu (right-click or menu): * On a channel, **Hide** / **Unhide** toggles the channel's ID in the user's hidden-channel list. * On a view, **Hide** / **Unhide** toggles the view's ID in the user's hidden-view list. Hidden items are grouped into a collapsible **Hidden** section at the bottom of the corresponding sidebar section (Channels or Views). Unhiding returns the item to its previous position. This is a personal UI preference only. Do not use it as an access control mechanism — hiding a shared view does not prevent the user, or anyone else, from reading its tickets. *** ## Ticket creation defaults from filters When a user creates a ticket from inside a view, Ravenna seeds the new ticket form with defaults derived from the view's active filters. This reduces redundant data entry when a view already implies the field's value. Rules: * Only filters using **equals** or **is any of** operators are considered. * A default is only applied when the filter targets a single value. Multi-value filters (e.g., *Assignee is any of Alex, Sam*) do not produce a default. * Eligible fields are: assignee, status, priority, category, and tags. Tags accept all matching values from the filters. * On Kanban boards, the column's grouping value (status, priority, or assignee) takes precedence over the filter default for that field. * Defaults are never applied when duplicating an existing ticket. This behavior is automatic and requires no configuration. Users can override any pre-filled value before submitting the ticket. *** ## Constraints and gotchas * Views are workspace-scoped. A view cannot span multiple workspaces. * On custom views, filter and display-option changes auto-save as personal overrides scoped to the current user. Other workspace members are unaffected until the user promotes the override via **Save** (for filters) or **Save view options to view** (for display options). **Reset** discards the personal override and falls back to the shared configuration. * The workspace default view does not use personal overrides. Edits there save directly to the view and affect anyone who hasn't customized it. * Personal overrides include filters, display mode, column visibility/order/width, grouping, and sorting. They are stored per user, per view. * Private views are only visible to and editable by their creator. Shared views can be edited or deleted by any workspace member. * Shared views have an **Allow edits** flag that gates the **Save** / **Save view options to view** actions for non-owner, non-admin members. The default is off, so newly created shared views are locked until the owner or an admin opts in. Owners and workspace admins always bypass the lock. Personal overrides are unaffected by the flag. * Any workspace member can duplicate a view from the sidebar's view menu. Duplicates are always created private, `allowEdit: false`, and owned by the caller. The duplicate captures the caller's effective view (shared configuration overlaid with their personal filter and display overrides), not the raw shared configuration. * Filters use AND logic only. For OR conditions, create separate views. * Kanban column collapse preferences are per-user, per-view. They do not affect other team members. * Unread notification badges on views reflect tickets matching the view's filters that have new activity. They update in real time. * CSV exports include all tickets matching the current view's filters at the time of export. The export reflects the live data, not a cached snapshot. * CSV exports follow the view's column visibility settings. Hidden columns are excluded from the file, so confirm your column configuration before exporting. # Private notes Source: https://docs.ravenna.ai/documentation/tickets/private-notes Use private notes to share internal-only messages on tickets that stay hidden from requesters, perfect for sensitive discussions and team strategy. Private notes let you send messages within tickets that only workspace members can see. Use them for internal discussions, strategy planning, or sharing sensitive information that shouldn't be visible to ticket requesters or external users. *** ## Send private notes Send private notes from the ticket message composer: Navigate to the ticket where you want to add a private note. Type your message in the message composer at the bottom of the ticket. Click the dropdown arrow next to **Send** and select **Send private**. The message will be marked with a lock icon. Only workspace members can send private notes. Guest users cannot access the "Send private" option. The ticket message composer is a rich text editor. Use the formatting toolbar to add **bold**, *italic*, lists, links, and inline code in both public replies and private notes. Type formatted text directly in the composer instead of writing raw Markdown or HTML. Learn how to send private notes from Slack in the [triage channel documentation](/integrations/slack/triage-channel#private-notes) *** ## Identify private notes Private notes are visually distinguished from regular messages: * **Lock icon**: Private notes display a lock icon * **Yellow background**: Private notes have a yellow-tinted background in the ticket view * **Hidden from external channels**: Private notes never appear in public Slack threads or external communication *** ## Mention workspace members @mention a workspace member in a private note to send them a direct Slack DM about the note. Because private notes never appear in request threads or DM ticket threads, this is the only way a mentioned teammate is alerted to a callout. The DM includes: * Who mentioned them and the ticket title * An excerpt of the private note * A **View Ticket** button that opens the ticket in Ravenna * A **View in Slack** button that jumps to the matching triage or request thread when available Mentions only notify the recipient when they are a workspace member with Slack connected. Authors are never notified of their own mentions, and requesters are never notified of mentions in private notes. *** ## Access control * Workspace members * Workspace admins * Guest users (role-restricted) * Ticket requesters * External users * Anyone without workspace member access *** ## Use cases Discuss sensitive information or strategy without exposing details to requesters. Coordinate with team members before sending a public response to the requester. Share internal context, credentials, or restricted details that shouldn't be visible externally. Assign tasks, discuss workload, or coordinate handoffs without cluttering the public ticket thread. ## Mental model Private notes are messages within a ticket that are hidden from the ticket requester and external users. Only workspace members and admins can see and send private notes. They exist in the same ticket thread as public messages but are filtered by visibility. Private notes are different from private tickets. A private note is a single hidden message within any ticket (public or private). A private ticket restricts visibility of the entire ticket to specific roles. *** ## When to use private notes * Internal coordination before responding to a requester. * Sharing context that the requester should not see (e.g., internal policy details, escalation reasoning). * Documenting internal decisions or handoff notes. * Agent-to-agent communication within a ticket. The agent can send private notes when communicating information that is meant for workspace members only, not for the requester. For example, when escalating to a human, the agent can leave a private note summarizing the context for the assignee. *** ## Constraints and gotchas * Only workspace members and admins can send and view private notes. Guest users cannot. * Private notes never appear in Slack request channel threads. They are only visible in the Admin and the triage channel. * Private notes from the triage channel in Slack are delivered as private notes in the ticket. * @mentions in private notes do not notify the requester, even if the requester is mentioned. * @mentioning a workspace member in a private note sends them a Slack DM with the ticket link and a short excerpt of the note. The author of the note is never notified of their own mentions. * Private notes cannot be converted to public messages after sending, and vice versa. # Private tickets Source: https://docs.ravenna.ai/documentation/tickets/private-tickets Restrict ticket visibility to specific roles for HR, security, and confidential requests so only the requester and assigned team members can view. Private tickets restrict visibility to specific users, ensuring sensitive information stays confidential. Use private tickets for HR requests, security incidents, personal information, and other confidential matters. *** ## Visibility and access Private tickets are only visible to users with specific roles: * **Requester**: The person who created or is the subject of the ticket * **Workspace admins**: All administrators of the workspace the ticket belongs to * **Workspace members**: Team members with access to the workspace * **Assignee**: The person responsible for resolving the ticket * **Followers**: Users explicitly added to follow the ticket * **Approvers**: Users assigned to approve the ticket Followers and approvers lose access to a private ticket when removed from their role, unless they are also a workspace admin or member. Ticket roles sit on top of your organization and workspace access. For the full model, see [Roles and access](/documentation/platform/roles-access). *** ## Create private tickets Tickets become private through two methods: Tickets created from Slack direct messages with Ravenna are always private, regardless of any other settings. Microsoft Teams does not have a 1:1 DM entry point in the current beta. All Teams tickets originate from channel messages. Use [private forms](/documentation/tickets/forms/overview) to keep Teams-created tickets private. See the [Microsoft Teams integration overview](/integrations/microsoft-teams/overview). When you message Ravenna directly in Slack: * The ticket is automatically marked as private * Only authorized users can view the ticket * The conversation stays in your DM with Ravenna When a form has the private setting enabled, all tickets created with that form are private by default. This applies even when users interact with the form in a public channel. **Public channel behavior**: If a user triggers a private form in a public Slack channel (via slash commands or agents), Ravenna: 1. Posts a message in the public thread confirming the ticket was created. The notice includes a deep link to the requester's DM with Ravenna so they can jump directly into the private conversation. 2. Automatically moves the conversation to the user's DM with Ravenna 3. Continues all ticket interactions privately in the DM This ensures sensitive information is never exposed in public channels, even if the request started there. Learn more about [configuring private forms](/documentation/tickets/forms/overview) to automatically create private tickets *** ## Use cases Consider using private tickets for scenarios where confidentiality is important: PTO requests, benefits inquiries, complaints, and personnel matters that require confidentiality. Vulnerability reports, security issues, and incident response that must remain protected. Requests involving private data, personal details, or sensitive employee information. Sensitive operational matters, executive communications, or strategic discussions. Your organization may have different needs for private tickets based on your security policies and compliance requirements. *** ## Manage access ### Role-based access Access to private tickets is dynamic and based on roles: **Adding roles** * Adding someone as a follower, approver, or assignee grants immediate access to the ticket **Removing roles** * Removing a follower, approver, or assignee removes their access unless they have another qualifying role (workspace admin/member, requester, or assignee) **Workspace membership** * Workspace admins and members always have access to private tickets within their workspace, regardless of ticket-specific roles ### Mentions @mentions in private tickets do not automatically add users as followers. You must manually add them as a follower, approver, or assignee to grant access. *** ## Public thread protection When a ticket is moved to private, the original public request thread displays a notice indicating the conversation has been moved. If the ticket originated from a private form triggered in a public channel, the notice also includes a deep link that opens your DM with Ravenna in one click. If you reply in the public thread of a private ticket, Ravenna sends you a one-time ephemeral warning reminding you to continue the conversation in DMs instead. The ephemeral warning is only shown once per user per thread. After seeing the warning, your future replies in that thread will not trigger additional warnings. ## Mental model A private ticket restricts the entire ticket's visibility to users with specific roles. Unlike a regular ticket (visible to anyone in the workspace), a private ticket is only accessible to the requester, assignee, followers, approvers, and workspace members/admins. Private tickets are different from private notes. A private ticket hides the entire ticket from unauthorized users. A private note hides a single message within an otherwise visible ticket. *** ## How tickets become private Two mechanisms create private tickets: 1. **DM-created tickets**: Any ticket created from a Slack DM with Ravenna is automatically private. This cannot be overridden. 2. **Private forms**: When a form has the private setting enabled, all tickets created with that form are private by default. When a private form is triggered in a public Slack channel, the system automatically redirects the conversation to the user's DM with Ravenna. A confirmation message is posted in the public channel with an embedded deep link that opens the requester's DM with Ravenna, so they can reach the private conversation in one click. All subsequent interactions happen privately. *** ## Access rules | Role | Access to private tickets | | ----------------- | ------------------------------- | | Requester | Always | | Assignee | While assigned | | Followers | While following | | Approvers | While assigned as approver | | Workspace members | Always (within their workspace) | | Workspace admins | Always (within their workspace) | Access is dynamic. Adding someone as a follower grants access immediately. Removing them revokes access unless they qualify through another role. Important: @mentions do not grant access. Mentioning a user in a private ticket does not add them as a follower or grant visibility. You must explicitly add them to a role. *** ## Public thread protection When a ticket is privatized, the public request thread receives a prominent notice that the conversation has been moved to a private ticket. If a user replies in this public thread, Ravenna sends an ephemeral warning to that user, directing them to continue in DMs. This warning is sent once per user per thread — tracked via metadata on the Slack thread so repeat replies do not trigger additional warnings. The flow: 1. A ticket is converted to private (via DM creation, private form, or 🤫 emoji). 2. The public request thread gets a `:lock:` notice indicating the conversation moved to private. When the ticket originated from a private form in a public channel, the notice also embeds a deep link to the requester's DM with Ravenna so the requester can open the private conversation directly from the public thread. 3. If any user posts a reply in the public request thread, Ravenna sends them an ephemeral message warning them to use DMs instead. 4. The user's ID is stored in the thread metadata (`warnedUserIds`) so they are only warned once. 5. The reply is silently dropped — it is not processed as a ticket message. This prevents accidental information leakage in public channels when users do not realize the ticket has been made private. *** ## Constraints and gotchas * DM-created tickets are always private. There is no way to make a DM-created ticket public. * Private forms create private tickets even when triggered from public Slack channels. The system handles the redirect to DM automatically. * Workspace members and admins always have access to private tickets in their workspace. If you need to restrict visibility from workspace members, private tickets alone are not sufficient. Consider using a separate workspace with restricted membership. * Access changes are immediate. Adding or removing a follower/approver/assignee updates visibility instantly. * @mentions in private tickets do not grant access or send notifications to users who lack access. * Replies in the public request thread of a private ticket are not processed. The user receives a one-time ephemeral warning to continue in DMs. # Parent & child tickets Source: https://docs.ravenna.ai/documentation/tickets/relations Create parent and child ticket relationships across channels and workspaces to break down complex projects and coordinate cross-team work. Create parent-child relationships between tickets to organize complex work into manageable components. Parent and child tickets can exist across different channels and workspaces, enabling cross-team collaboration and process tracking. *** ## Understanding parent-child relationships Parent tickets contain one or more child tickets (also called subtickets). Use this hierarchy to break down large projects into smaller work items while maintaining clear connections between related tickets. Parent and child tickets can exist in different channels and workspaces. This allows teams like IT and HR to collaborate and track shared processes while maintaining separate work environments. *** ## Add parent tickets Establish a parent-child relationship by adding a parent to an existing ticket: Navigate to the ticket details page. Click the actions dropdown and select **Relations > Add Parent Ticket**. Browse and select an existing ticket to serve as the parent. Click **Save** to establish the relationship. Find the ticket in any ticket list or table view. Click the actions dropdown in the rightmost column and select **Relations > Add Parent Ticket**. Browse and select an existing ticket to serve as the parent. Click **Save** to establish the relationship. *** ## Add child tickets Add child tickets (subtickets) to a parent ticket: Click the **Add Subticket** button in the ticket details page to create a new child ticket. Click the actions dropdown, select **Relations > Add Subticket**, then create the new child ticket. When creating a new ticket, specify a parent ticket to establish the relationship immediately. *** ## View relationships Child tickets display their parent ticket number and channel prefix. In ticket lists, child tickets show a parent badge you can click to navigate to the parent. Parent tickets show a list of their child tickets with titles, descriptions, status, and priority. In ticket lists, parent tickets display a count of their child tickets. Parent and child tickets can exist in different channels and workspaces, maintaining relationships across teams, departments, and project areas. This enables collaboration between teams like IT and HR while each team maintains their own workspace. Group or sort tickets by parent in ticket lists and tables to see all related work items together. *** ## Manage relationships Archiving a parent ticket automatically archives all child tickets throughout the entire hierarchy. This ensures completed or paused projects are properly organized. Unarchiving a parent ticket automatically unarchives all child tickets, restoring the complete project structure with relationships intact. This applies to both individual and bulk unarchive actions from the ticket list. Deleting a parent ticket permanently deletes all child tickets throughout the entire hierarchy. This ensures clean data organization when removing projects. Deleting a parent ticket permanently deletes all child tickets. This action cannot be undone. ## Mental model Parent-child relationships create a hierarchy between tickets. A parent ticket represents a larger piece of work, and its child tickets (subtickets) represent the component parts. Each ticket in the hierarchy is a full ticket with its own status, assignee, channel, and lifecycle. Key distinction: parent-child tickets vs tasks. | Feature | Parent-child tickets | Tasks | | ------------------- | ------------------------------------------------ | -------------------------------------- | | **Nature** | Each is a full ticket with independent lifecycle | Checklist items within a single ticket | | **Status** | Each has its own status workflow | Complete/incomplete only | | **Cross-workspace** | Parent and child can be in different workspaces | Tasks exist within one ticket | | **Assignee** | Each ticket has its own assignee | Tasks can have multiple assignees | | **Depth** | Unlimited nesting | 3 levels maximum | | **Notifications** | Each ticket has independent notifications | Task assignees become ticket followers | Use parent-child tickets when component work needs independent tracking, different assignees with full ticket lifecycle, or cross-team visibility. Use tasks for simple checklists within a single ticket. *** ## Relations vs links vs sharing | Mechanism | Connects | Purpose | | ---------------------------- | ------------------------------- | ---------------------------------------------------- | | **Relations (parent-child)** | Ticket to ticket within Ravenna | Hierarchical work breakdown with cascade behaviors | | **Links** | Ticket to external URL | Reference to external resources (Jira, GitHub, docs) | | **Sharing** | Ticket to additional channels | Cross-team visibility without moving the ticket | | **Moving** | Ticket to different workspace | Full ownership transfer | *** ## Cascade behaviors Parent-child relationships have important cascade behaviors: * **Archive**: Archiving a parent archives all children recursively through the entire hierarchy. * **Unarchive**: Unarchiving a parent unarchives all children recursively. You can also bulk unarchive by selecting multiple archived tickets from the ticket list. * **Delete**: Deleting a parent permanently deletes all children recursively. This is irreversible. These cascades apply to the entire descendant tree, not just direct children. *** ## Cross-workspace relationships Parent and child tickets can exist in different channels and workspaces. This enables patterns like: * An IT parent ticket with HR child tickets for onboarding processes. * A project management parent ticket with engineering, design, and QA child tickets in their respective workspaces. Cross-workspace relationships are visible from both sides. Child tickets display their parent's ticket number and channel prefix. Parent tickets list their children with status and priority. *** ## Relations in views * Tickets can be grouped or sorted by parent in list and table views. * Parent tickets display a count of child tickets. * Child tickets show a parent badge that links to the parent. *** ## Constraints and gotchas * A ticket can have at most one parent. A ticket can have many children. * Deleting a parent permanently deletes all descendants. This is the most destructive cascade behavior in the system. * Archiving and unarchiving cascade through the entire hierarchy. * Parent-child relationships are maintained across workspace moves. If a child ticket is moved to a different workspace, the relationship persists. * There is no "related tickets" relationship type. Only parent-child hierarchy exists. For non-hierarchical connections, use links. * Child ticket status does not automatically update the parent. Completing all children does not close the parent. * Creating a child ticket from the parent's detail page automatically establishes the relationship. # Reminders Source: https://docs.ravenna.ai/documentation/tickets/reminders Automatically nudge pending approvers and ticket assignees on a configurable schedule until they act, the work completes, or the reminder cap is reached. Reminders automatically nudge people who have not acted on work assigned to them. Ravenna handles the follow-ups and delivers each reminder privately to the recipient. There are two types: * **Approval reminders** nudge approvers who have not yet responded to a pending [approval round](/documentation/tickets/approvals/rounds). * **Assignment reminders** nudge the current assignee of a ticket that has been sitting in an open state. Both are configured per workspace in **Settings** → **Workspace** → **Automation**. Each workspace owns its own policies, so IT and HR can run on different cadences. Admins can also read and update reminder policies through Copilot or an MCP client using the `list_reminder_policies` and `configure_reminder_policy` [tools](/documentation/automate/mcp/tools#reminders). Nudge approvers who have not yet responded to a pending approval round. Nudge the current assignee of a ticket that has been sitting in an open state. *** ## Shared behavior Approval and assignment reminders work the same way under the hood: * Each is a workspace-level policy with an **Enable** toggle, a **reminder interval** (hours, days, or weeks, default `24 hours`), a **maximum reminders** count (`1`, `2`, `3`, `5`, `10`, or **Unlimited**, default `3`), an optional **business schedule**, and optional **conditions** that scope which tickets the policy applies to. * Each reminder is delivered privately to its recipient (pending approvers for approval reminders, the current assignee for assignment reminders). Ravenna sends the reminder through three independent channels: an in-app notification in the [notification center](/documentation/platform/notifications#notification-center), a Slack DM, and an email. No public ticket message is posted, and other people with access to the ticket are not notified. * Delivery is gated per channel by the recipient's [notification preferences](/documentation/platform/notifications). Approval reminders follow the **Approvals** group; assignment reminders follow the **Assignments** group. If a recipient has Slack disabled for that group, the DM is skipped; the same rule applies to email. * Reminders are only delivered on **published** tickets. Draft or unpublished tickets do not receive reminder deliveries even if a reminder fires. Each fire is logged on the ticket timeline as a **Reminder sent** (`REMINDER_SENT`) event regardless of whether delivery succeeded on any channel. * The interval clock restarts after every reminder. It is measured from when the work started (or from the last reminder), not from ticket creation. * When the maximum is reached, the work itself is unaffected. Ravenna fires a [Reminder Expired](/documentation/automate/workflows/triggers-actions#reminder-expired) workflow trigger so you can escalate, reassign, or close the ticket in a workflow. ### Conditions You can scope a policy to a subset of tickets by adding **conditions**. Each policy can have one or more condition groups built from the same ticket fields you use elsewhere in Ravenna (queue, priority, form, requester attributes, and so on). * Leave conditions empty to remind on every ticket the policy type applies to. This is the default. * Add one or more conditions and the policy only sends reminders for tickets that match. Within a group, all conditions must match (AND). Across groups, any group matching is enough (OR). * Conditions are re-evaluated **every time a reminder is about to fire**, not just when the work starts. A ticket that no longer matches is skipped for that cycle, but the schedule keeps running. If the ticket changes back into scope (for example, priority is raised back to `High`), reminders resume on the next interval. * Skipped fires do not count toward the **Maximum reminders** cap. Only delivered reminders count. * To prevent a never-matching ticket from rescheduling forever, a reminder chain is capped at **30 days** from when it first scheduled. After that, the chain stops on its own without firing a Reminder Expired event. ### Business hours and weekends Reminders respect the **business schedule** you select on the policy. If a reminder would fire outside the schedule's working windows, Ravenna defers it to the next working window so people are not pinged overnight or on weekends. * If the policy has no schedule selected, reminders fire on a straight wall-clock interval, including nights and weekends. * The interval is measured in real time, not business time. A 24-hour interval still resumes 24 hours after the work started; the deferral only shifts the *delivery* moment forward to the next working window. * Only schedules that belong to the same workspace can be selected. Automation settings are admin-only. Each workspace has its own policies. There is no per-queue, per-form, or per-ticket override. Disable a workspace's policy to stop those reminders everywhere in that workspace. *** ## Approval reminders When a round becomes active, Ravenna schedules the first reminder using your workspace's interval setting. Each time the reminder fires: 1. Ravenna looks up the round's pending approvers (anyone who has not yet approved or declined). 2. If there are no pending approvers, nothing is sent and no further reminders are scheduled. The round has either completed or been reset. 3. Otherwise, Ravenna delivers a private reminder to each pending approver through three independent channels, each gated by that approver's **Approvals** [notification preferences](/documentation/platform/notifications): * An in-app notification in the notification center. * A Slack DM in the approver's existing ticket DM thread with the message *"⏰ Reminder: your approval is still pending on this ticket."* * An email with the subject line for the ticket, containing *"Your approval is still pending on this ticket."* 4. If the round still has pending approvers and the cap has not been reached, Ravenna schedules the next reminder one interval out from the reminder it just delivered. 5. When the cap is reached, Ravenna fires a [Reminder Expired](/documentation/automate/workflows/triggers-actions#reminder-expired) workflow trigger of type `Approval`. Reminders are tied to the **round**, not the ticket. A ticket with three sequential rounds gets up to three independent reminder cycles, one per round, each starting when the round activates. Approvers who are added to a round mid-flight (for example, when an admin edits the round) are picked up automatically on the next reminder. They do not need to wait for a new cycle to start. Approval reminders are private to the pending approvers. No public message is posted on the ticket, and the requester, followers, and assignee are not notified. The bot user is never a recipient. Every fire is recorded on the ticket timeline as a **Reminder sent** event for audit purposes. Approvers respond using the existing Approve and Decline controls in the ticket or in the original approval Slack DM. ### Configure approval reminders Go to **Settings** → **Workspace** → **Automation**. The page is admin-only. Find the **Approval Reminders** card and toggle **Enable approval reminders** on. Set how long Ravenna waits after a round opens (or after the last reminder) before sending the next nudge. Enter a whole number and select **hours**, **days**, or **weeks**. The default is `24 hours`. Set how many nudges Ravenna sends per round before giving up. Select from `1`, `2`, `3`, `5`, `10`, or **Unlimited**. The default is `3`. Under **Business hours**, select a [business schedule](/documentation/platform/workspaces/settings#business-schedules) to restrict when reminders can fire. Leave it set to **No schedule** to send on a wall-clock interval, including nights and weekends. Under **Conditions**, select **Add condition set** to limit reminders to tickets matching specific filters (for example, only `Priority` is `High` or `Urgent`). Leave empty to remind on every pending approval round. ### When approval reminders stop A reminder cycle ends as soon as any of the following happens: * All approvers on the round have responded (the round is approved, declined, or reset). * The round has no pending approvers when a reminder is about to fire. * The configured **Maximum reminders** count has been sent. * An admin disables the **Enable approval reminders** toggle. * The reminder chain has been running for 30 days without delivering, because the ticket never matched the policy's conditions. *** ## Assignment reminders When a ticket is assigned, Ravenna schedules the first reminder using your workspace's interval setting. Each time the reminder fires: 1. Ravenna checks the ticket. If the ticket is unassigned, was reassigned to someone else, archived, or has moved to a terminal status (`Done` or `Closed`), the reminder is cancelled. 2. Otherwise, Ravenna delivers a private reminder to the current assignee through three independent channels, each gated by their **Assignments** [notification preferences](/documentation/platform/notifications): * An in-app notification in the notification center. * A Slack DM in the assignee's existing ticket DM thread with the message *"⏰ Reminder: this ticket is still assigned to you."* * An email with the subject line for the ticket, containing *"This ticket is still assigned to you."* 3. If the cap has not been reached, Ravenna schedules the next reminder one interval out from the reminder it just delivered. 4. When the cap is reached, Ravenna fires a [Reminder Expired](/documentation/automate/workflows/triggers-actions#reminder-expired) workflow trigger of type `Assignment`. Reminders are tied to the **ticket and its current assignee**. Reassigning the ticket replaces the schedule with a fresh cycle for the new assignee. Assignment reminders are private to the current assignee. No public message is posted on the ticket, and the requester, followers, and approvers are not notified. The bot user is never a recipient. Every fire is recorded on the ticket timeline as a **Reminder sent** event for audit purposes. Only one assignment reminder runs at a time per ticket. The schedule is keyed by ticket, not by assignee, so a new assignment supersedes the previous reminder. ### Configure assignment reminders Go to **Settings** → **Workspace** → **Automation**. The page is admin-only. Find the **Assignment Reminders** card and toggle **Enable assignment reminders** on. Set how long Ravenna waits after a ticket is assigned (or after the last reminder) before sending the next nudge. Enter a whole number and select **hours**, **days**, or **weeks**. The default is `24 hours`. Set how many nudges Ravenna sends per assigned ticket before giving up. Select from `1`, `2`, `3`, `5`, `10`, or **Unlimited**. The default is `3`. Under **Business hours**, select a [business schedule](/documentation/platform/workspaces/settings#business-schedules) to restrict when reminders can fire. Leave it set to **No schedule** to send on a wall-clock interval, including nights and weekends. Under **Conditions**, select **Add condition set** to limit reminders to tickets matching specific filters (for example, only tickets in a particular queue, or only `Priority` is `High` or `Urgent`). Leave empty to remind on every assigned ticket. ### When assignment reminders stop A reminder cycle ends as soon as any of the following happens: * The ticket is **unassigned** or reassigned to a different user. A new cycle begins for the new assignee. * The ticket is **archived**. * The ticket moves to a **terminal status** (any status in the `Done` or `Closed` system group). * The configured **Maximum reminders** count has been sent. * An admin disables the **Enable assignment reminders** toggle. * The reminder chain has been running for 30 days without delivering, because the ticket never matched the policy's conditions. When the maximum is reached, the ticket stays open and assigned. The signal that reminders have given up is the **Reminder Expired** workflow trigger. *** ## Escalate stale work with workflows Pair reminders with the [Reminder Expired](/documentation/automate/workflows/triggers-actions#reminder-expired) workflow trigger to escalate work that exhausts its reminder budget without progress. Filter the trigger's **Reminder Type** to `Approval` or `Assignment` so the workflow only fires for the reminder type you intend. Common patterns: * **Notify a backup approver or the assignee's manager.** Add a manager or fallback group when the cap is hit so the request keeps moving. * **Reassign to a fallback group.** Move the ticket to a backup queue or assign it to a different team so it does not stall. * **Post an escalation note.** Add a [private note](/documentation/tickets/private-notes) summarizing who is still pending and ping a lead for triage. * **Auto-close stalled requests.** If a request has been ignored for too long, change the ticket status or decline the round in a workflow. Learn more about the [Reminder Expired trigger](/documentation/automate/workflows/triggers-actions#reminder-expired) and [building escalation workflows](/documentation/automate/workflows/overview). *** ## Tips * **Start conservative.** A 24-hour interval with a 3-reminder cap is the default for a reason. Tighter cadences create noise without changing outcomes. * **Select a business schedule.** Without one, reminders fire 24/7 and people get pinged in the middle of the night. * **Use conditions to focus the policy.** If only high-priority or queue-specific work warrants nudging, add conditions so routine tickets are not pinged. Conditions are re-checked on every fire, so a ticket can drop out and back into scope without losing its place. * **Use Waiting statuses to pause assignment reminders.** Assignment reminders only stop when a ticket reaches a terminal status group (`Done` or `Closed`). Use [statuses](/documentation/tickets/organize/statuses) and [SLA pauses](/documentation/automate/slas) deliberately so reminders fire only when the assignee actually owns the next step. * **Always design the expiry path.** Reminders only nudge, they do not move the ticket. Build a Reminder Expired workflow so stalled work gets reassigned or escalated automatically. * **Combine approval reminders with [Wait for Approval](/documentation/automate/workflows/triggers-actions#wait-for-approval) timeouts.** Reminders push approvers to act; the workflow's On Timeout branch handles the case where they never do. ## Mental model Approval and assignment reminders are workspace-level automation policies that schedule recurring, private nudges to the users responsible for pending work on a ticket. Both use the shared `Reminder` infrastructure, the same scheduling primitive keyed by a URN. Each successful fire records a `REMINDER_SENT` ticket event and dispatches on three private channels; a `REMINDER_EXPIRED` ticket event is dispatched when the cap is hit. Each policy is configured once per workspace. There is no per-ticket, per-queue, per-form, per-round, or per-assignee override. * **Approval reminders** are keyed by `(ticketId, roundId)`. Scheduled when a round opens, cancelled when the round closes (approve, decline, reset). * **Assignment reminders** are keyed by `ticketId`. Scheduled when a ticket is assigned, cancelled when the ticket is unassigned, reassigned, archived, or moves to `Done` or `Closed`. *** ## Configuration Each workspace has at most one policy of each type. Both expose the same fields: | Field | Type | Default | Notes | | --------------- | ---------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `enabled` | boolean | `false` | Master switch. `false` means no reminders are scheduled or dispatched even if other fields are set | | `intervalHours` | number ≥ 1 | `24` | Hours between the work starting (or the last reminder) and the next reminder | | `maxReminders` | integer ≥ 1 or `null` | `3` | Maximum reminders per round (approval) or per assigned ticket (assignment). `null` means unlimited | | `scheduleId` | string or `null` | `null` | Optional [business schedule](/documentation/platform/workspaces/settings#business-schedules) ID used to defer delivery to working windows. Must belong to the same workspace | | `filterGroups` | filter-group array or `null` | `null` | Optional ticket condition filter, expressed as an OR of AND groups. Empty/null means "remind for every ticket". Evaluated against the ticket's hydrated context every time a reminder is about to fire | The UI exposes the interval in hours, days, or weeks, but the value is normalized to hours on save. Days and weeks are converted via `24` and `168` respectively. `computeReminderFireAt(baseTime, intervalHours, schedule)` returns `baseTime + intervalHours` adjusted forward to the next working window of the policy's selected business schedule. If the policy has no schedule, the returned time is the raw wall-clock offset. The schedule is the one attached to the policy, not the workspace default. Upserting a policy with a `scheduleId` that does not belong to the same workspace is rejected. *** ## Approval reminder lifecycle 1. **Round opens.** When an approval round transitions to ACTIVE, an approval reminder is scheduled for the round. 2. **Policy check.** The workspace's approval reminder policy is loaded. If `enabled = false`, no reminder is scheduled. 3. **First reminder scheduled.** A reminder is enqueued with: * `uri`: `REMINDER_URN.approvalRound(ticketId, roundId)`, which guarantees idempotency per round. * `type`: `ReminderType.Approval`. * `fireAt`: `computeReminderFireAt(round.openedAt, intervalHours, policy.schedule)`. * `metadata`: `{ ticketId, roundId, workspaceId, organizationId, reminderCount: 0 }`. 4. **Reminder fires.** The handler runs: * Re-fetches pending approvers. Empty list → cancels the reminder URN and returns (round resolved between fire-at and execution). * Re-reads the policy. If `enabled = false` mid-cycle → cancels and returns. * Evaluates `policy.filterGroups` against the hydrated ticket context. On no match, the reminder is marked `skipped` and **no delivery is attempted**; on match, proceeds to delivery. * Creates a `REMINDER_SENT` ticket event authored by the workspace bot user with `source: SYSTEM`, referencing the ticket, the `roundId`, and the `reminderId`. This event is timeline-only and is not mapped into a notification group directly. * If the ticket is unpublished (draft), delivery is skipped for that fire. The event is still recorded. * Otherwise, resolves recipients (the round's currently pending approvers) and dispatches on three independent private channels in parallel: in-app notification, Slack DM, and email. Each channel is gated by the recipient's **Approvals** notification preference for that channel. A channel failure is logged and does not block the other channels. No public ticket message is posted and no `@` mention is generated. * Computes `nextCount`. A delivered fire increments it; a `skipped` fire leaves it unchanged. If `maxReminders !== null && nextCount >= maxReminders`, dispatches a `REMINDER_EXPIRED` ticket event with `reminderType: Approval`. Otherwise, if the chain has been running less than `REMINDER_CHAIN_MAX_AGE_DAYS` (30 days from `chainStartedAt`), schedules the next reminder. Past that ceiling the chain stops without dispatching `REMINDER_EXPIRED`. 5. **Round closes.** When the round becomes APPROVED, DECLINED, or RESET, the reminder is cancelled via the URN. URN: ```text theme={"system"} ravenna:reminder:approval-round:{ticketId}:{roundId} ``` Scheduling with the same URN replaces any existing reminder for that key, so re-opening or re-activating a round does not double-schedule. *** ## Assignment reminder lifecycle 1. **Assignee set.** When a ticket gains an assignee, an assignment reminder is scheduled. 2. **Policy check.** The workspace's assignment reminder policy is loaded. If `enabled = false`, no reminder is scheduled. 3. **First reminder scheduled.** A reminder is enqueued with: * `uri`: `REMINDER_URN.assignment(ticketId)`, one in-flight reminder per ticket. * `type`: `ReminderType.Assignment`. * `fireAt`: `computeReminderFireAt(now, intervalHours, policy.schedule)`. * `metadata`: `{ ticketId, assigneeId, organizationId, workspaceId, reminderCount: 0 }`. 4. **Reminder fires.** The handler runs: * Reloads the ticket. If the ticket is missing or no longer assigned to `metadata.assigneeId`, is archived, or its status group is in `TERMINAL_STATUS_GROUPS` (`Done`, `Closed`) → cancels the URN and returns. * Re-reads the policy. If `enabled = false` mid-cycle → cancels and returns. * Evaluates `policy.filterGroups` against the hydrated ticket context. On no match, the reminder is marked `skipped` and **no delivery is attempted**; on match, proceeds to delivery. * Creates a `REMINDER_SENT` ticket event authored by the workspace bot user with `source: SYSTEM`, referencing the ticket, the `assigneeId`, and the `reminderId`. This event is timeline-only and is not mapped into a notification group directly. * If the ticket is unpublished (draft), delivery is skipped for that fire. The event is still recorded. * Otherwise, resolves the current assignee as the sole recipient and dispatches on three independent private channels in parallel: in-app notification, Slack DM, and email. Each channel is gated by the assignee's **Assignments** notification preference for that channel. A channel failure is logged and does not block the other channels. No public ticket message is posted and no `@` mention is generated. * Computes `nextCount`. A delivered fire increments it; a `skipped` fire leaves it unchanged. If `maxReminders !== null && nextCount >= maxReminders`, dispatches a `REMINDER_EXPIRED` ticket event with `reminderType: Assignment`. Otherwise, if the chain has been running less than `REMINDER_CHAIN_MAX_AGE_DAYS` (30 days from `chainStartedAt`), schedules the next reminder. Past that ceiling the chain stops without dispatching `REMINDER_EXPIRED`. 5. **Assignment changes or ticket closes.** The URN is cancelled. Reassigning to a new user schedules a fresh cycle keyed on the same URN, which supersedes any prior schedule. URN: ```text theme={"system"} ravenna:reminder:assignment:{ticketId} ``` One reminder per ticket. Reassignment replaces the schedule rather than running two cycles in parallel. *** ## Notifications Every reminder fire creates a `REMINDER_SENT` ticket event and then dispatches on three independent private channels: **in-app**, **Slack DM**, and **email**. There is no public ticket message. Recipients: * **Approval reminders** → the round's currently pending approvers (approvers whose status is `PENDING`), re-resolved at fire time. Approvers who have already approved or declined are not notified. * **Assignment reminders** → the ticket's current assignee at fire time. If the assignee changed between the schedule and the fire, the handler cancels rather than notifying the new assignee (the reassignment starts its own cycle). * The bot user is never a recipient. Preference gating: * Each channel is gated independently by the recipient's effective preference for the relevant notification group. Approval reminders use `BaseNotificationGroup.Approvals`; assignment reminders use `BaseNotificationGroup.Assignments`. The helper `reminderNotificationGroup(reminderType)` returns this mapping. * Effective preferences are resolved via the standard `NotificationPreferenceStore.getEffectivePreferences` path, so organization defaults and user overrides both apply. * Slack approval DMs cannot be disabled at the group level (Approvals is a forced-on Slack group). Assignment DMs, and all email deliveries, are user-controllable. * `TICKET_EVENT_TO_NOTIFICATION_GROUP[REMINDER_SENT]` is `null`. The event does not go through the generic timeline-event-to-group mapping. Delivery is initiated directly by `ReminderDeliveryService.deliver` and its per-channel handlers, each of which reads the group derived from `reminderType`. Delivery gates: * **Ticket must be published.** If `ticket.published === false`, delivery is skipped for that fire. The `REMINDER_SENT` event is still recorded, so audit history stays consistent, but no channel is called. * **Slack context must exist for the recipient.** If `getSlackAppForUser(recipient, ticket)` returns nothing, the Slack DM is skipped for that recipient. Other channels still run. * Each channel runs inside `Promise.allSettled` under the delivery service, so a Slack failure does not block email and vice versa. Failures are logged with `[ReminderDeliveryService] reminder delivery failed`. Message copy (fixed, no personalization beyond the ticket link/mirror): * Approval Slack DM: `⏰ Reminder: your approval is still pending on this ticket.` * Assignment Slack DM: `⏰ Reminder: this ticket is still assigned to you.` * Email body value: `Your approval is still pending on this ticket.` / `This ticket is still assigned to you.` The email uses the standard ticket-updated template with `action: REMINDER_SENT` and title `Reminder`. *** ## REMINDER\_EXPIRED dispatch When `maxReminders` is hit, the handler dispatches a `TicketEventAction.REMINDER_EXPIRED` event with: * `ticketId`: the ticket * `reminderType`: `Approval` or `Assignment` * `organizationId` * `source`: `SYSTEM` The **Reminder Expired** workflow trigger consumes this event. Filter by `Reminder Type` to target a specific reminder type. The round or ticket is **not** modified by the expiry. Any state change must come from a workflow or manual admin action. *** ## Constraints and gotchas * Each workspace has at most one policy of each type. There is no per-queue, per-form, or per-ticket override. * Approval reminders are per-round. A ticket with three sequential rounds gets three independent reminder cycles. Assignment reminders are per-ticket-per-assignee. Reassigning a ticket cancels the existing cycle (via the URN) and starts a new one with `reminderCount: 0`. * The `intervalHours` clock restarts after every reminder. It is measured from "work started or last reminder", not from ticket creation. * The cap (`maxReminders`) counts dispatched reminders, not scheduled ones. If a reminder fires and is cancelled early (no pending approvers, terminal status, mismatched assignee, archived), or is `skipped` because the ticket did not match `filterGroups`, the count is not incremented. * `filterGroups` is evaluated against the ticket's hydrated context (reference id `reminder`, section `input`) on every fire. A non-matching fire is recorded with status `skipped` instead of `fired`, no delivery is attempted, and the chain reschedules without advancing the count. Reminder records can be in one of four statuses: `pending`, `fired`, `skipped`, or `cancelled`. * Reminder chains carry `chainStartedAt`, the wall-clock time the first reminder was scheduled. Once the chain age exceeds `REMINDER_CHAIN_MAX_AGE_DAYS` (30 days), the handler stops rescheduling and does **not** fire `REMINDER_EXPIRED`. This prevents a ticket that never matches its policy filters from rescheduling forever. Chains scheduled before this field existed have no cap. * Reminder deliveries are private to the recipient. There is no public ticket message, no `@` mention on the ticket surface, and no email to the requester or other stakeholders. The only ticket-wide artifact is the `REMINDER_SENT` audit event on the timeline. * Delivery only runs for published tickets. If a reminder fires against a draft ticket (`ticket.published === false`), the `REMINDER_SENT` event is still created but every channel is skipped. * Each of the three channels (in-app, Slack DM, email) is independently gated by the recipient's effective notification preference (`Approvals` for approval reminders, `Assignments` for assignment reminders). Slack approvals cannot be disabled at the group level; assignment DMs and all emails can. A recipient who has disabled a channel simply does not receive that channel's copy — the reminder still fires and other channels still run. * Channel calls run inside `Promise.allSettled`. A Slack outage or missing Slack context does not block email, and vice versa. Individual channel failures are logged and reported to the active tracing span. * The bot user is never a reminder recipient. * Tickets in any sub-status of the `Done` or `Closed` status groups stop assignment reminders. Tickets in `Waiting` do **not**, so move a ticket to `Done` if you want reminders to cease. * Disabling a policy mid-cycle cancels future dispatches but does not delete already-scheduled reminders. The handler re-checks the policy at fire time and cancels the URN if disabled. # Roles Source: https://docs.ravenna.ai/documentation/tickets/roles Understand ticket roles in Ravenna including requester, assignee, followers, and stakeholders, and how each affects access, notifications, and workflow. Every ticket has specific roles that control access, notifications, and workflow permissions. Understanding these roles helps ensure the right people are involved at the right time. Ticket roles are the most granular of three access layers. See [Roles and access](/documentation/platform/roles-access) for how organization roles, workspace access, and ticket roles combine. *** ## Requester The requester is the person who needs help or submitted the ticket. This is typically the end user requiring assistance. Each ticket has exactly one requester, assigned when the ticket is created. The requester receives updates about status changes and new messages throughout the ticket lifecycle. When the requester changes (manually, through an agent, or through a workflow), Ravenna records the change as an event on the ticket timeline. The event shows who made the change, the previous requester, and the new requester. ### Setting the requester When creating tickets in the Portal, the requester field is available in the ticket creation form. The field automatically defaults to you (the person creating the ticket), but you can change it to create tickets on behalf of others. **How it works:** * The requester field appears in the ticket attributes bar * Defaults to your user account * Click the field to select a different user * Useful for creating tickets on behalf of team members or end users Tickets created through Slack messages, form submissions, email, or the Portal automatically set the requester based on who submitted the request: * **Slack**: The user who sent the message * **Forms**: The user who submitted the form * **Email**: The sender of the email * **[Portal](/documentation/platform/portal)**: The user who submitted the form or started the chat that created the ticket *** ## Author The author is the person who physically created the ticket in Ravenna. This may be the same person as the requester or someone acting on their behalf. Each ticket has one author who cannot be changed once set. The author remains fixed throughout the ticket lifecycle. **Common scenarios:** * **Self-service**: Author and requester are the same person * **Proxy creation**: A support agent creates the ticket on behalf of someone needing help * **Escalation**: A manager creates a ticket for a team member's issue requiring formal tracking The author is who created the ticket record in Ravenna. The requester is who the ticket is for (the person needing help). In self-service scenarios, they're the same person. *** ## Assignees The assignee is the person responsible for working on and resolving the ticket. This role can change throughout the ticket lifecycle as work is transferred between team members. Each ticket can have only one assignee at a time, though tickets can exist without an assignee. The assignee receives updates about ticket changes and new messages. ### Assign tickets Assign tickets directly from several locations: * Ticket detail page * Bulk operations in ticket lists * Slack using commands or shortcuts * "Assign to me" quick action button Configure automatic assignment through: * **Channel auto-assignment**: Assign tickets to specific users automatically * **Round-robin**: Distribute tickets evenly among team members * **Workflow automation**: Assign based on ticket conditions, content, or events Unassigned tickets remain in the channel until manually assigned or picked up by team members. *** ## Working on it (agent owner) When an AI agent is actively working a ticket before it's escalated to a human, the agent is shown as the **Working on it** owner on the ticket. This is separate from the human assignee so internal AI routing never affects human-facing systems like notifications, CSAT attribution, or out-of-office delegation. **Where it appears:** * A read-only **Working on it** chip in the ticket attributes bar, alongside Assignee. The chip is only rendered while an agent owns the ticket. * Timeline events when the agent takes or releases ownership. These events are recorded for auditability but do not trigger assignment notifications. **When it's set:** * Inbound Slack DMs, Slack channel messages, and [Portal](/documentation/platform/portal) conversations routed to a configured agent. * The agent owns the ticket while it's still in the pre-publish, agent-only phase. **When it's cleared:** * Automatically when the ticket is published to a human channel (escalation or any other publish path). The human assignee is set at the same time. See [Handoff to a human](#handoff-to-a-human). * The chip disappears from the ticket once cleared. Tickets created through the Portal, email, Slack message shortcuts, integration webhooks, or workflow actions don't get an agent owner. Those paths are human-driven or already published. ### Handoff to a human When the agent escalates a ticket (for example, by publishing it after gathering context), Ravenna picks the human assignee in this order: 1. The specific user the agent's rule names (e.g., a rule that says "after escalation, assign to @Jane"). 2. The first auto-assignee configured on the channel. 3. Unassigned, picked up manually by a team member. The **Working on it** owner is cleared the moment the ticket publishes, so the human assignee always represents the current human owner. *** ## Followers Followers are users who need to stay informed about ticket progress but aren't directly responsible for resolving it. Multiple users can follow a single ticket. Any number of users can follow a ticket and receive updates about changes and new messages. Followers can be added or removed at any time. Following a ticket doesn't grant additional access permissions. ### Manage followers Add followers through: * Ticket detail page * Workflows based on conditions * @mentions in ticket messages (from Slack or the Admin) * CC recipients on inbound emails (added automatically) When you @mention a user in a ticket message, they're automatically added as a follower. This works for both new messages and edits. **Email CC recipients**: When tickets are created or updated via email, CC recipients are automatically added as followers. This respects your channel's guest user settings and allowlist configuration. The system filters out: * Users already following the ticket * The ticket's requester and assignee * Bot users * The message author Users can remove themselves from following tickets. Workflows can also remove followers when conditions are met. Followers receive DM notifications for ticket updates through Slack. Email preferences can be configured for follower updates. For private tickets, @mentions do not automatically add users as followers. This prevents unintended access to sensitive information. Followers receive notifications when tickets are updated, helping teams stay informed without being directly assigned *** ## Approvers Approvers are users who have authority to approve or decline tickets before work can proceed. Approvals use a rounds-based system where each round has its own set of approvers and policy. Tickets can have one or more approval rounds, each with approvers who can approve or decline. Approvals trigger automated actions through workflow integration, and approvers receive notifications across web and Slack. ### Add approvers Add approvers through: * Ticket sidebar Approvers field (individual users or user groups) * Approvals section on the ticket detail page * Workflow automation based on ticket type or conditions * Approval templates for pre-configured round configurations When you select a user group as an approver, the group is automatically expanded into individual users when saved. Only the individual users are stored as approvers on the round. Learn more about [approvals](/documentation/tickets/approvals/overview) including policies, multi-stage rounds, and admin controls ## Mental model Every ticket has a set of roles that determine who can see the ticket, who gets notified, and who can take specific actions. Roles are the fundamental access and notification primitives on a ticket. There are six distinct roles: | Role | Cardinality | Mutable | Purpose | | ----------------- | ------------ | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Requester** | Exactly one | Yes (can be changed) | The person the ticket is for, the person needing help | | **Author** | Exactly one | No (fixed at creation) | The person who created the ticket record in Ravenna | | **Assignee** | Zero or one | Yes (can be changed or removed) | The human responsible for resolving the ticket | | **Working on it** | Zero or one | Set and cleared automatically | The AI agent actively working the ticket before human handoff. Read-only; cleared on publish. | | **Followers** | Zero or many | Yes (can be added or removed) | Users who receive notifications but are not responsible for resolution | | **Approvers** | Zero or many | Yes (can be added or removed) | Users with authority to approve or decline the ticket via [approval rounds](/documentation/tickets/approvals/rounds). User groups are expanded into individual users when saved. | Key distinction: the requester is who the ticket is **for**. The author is who **created** the ticket. In self-service scenarios these are the same person. In proxy creation (an agent creates a ticket on behalf of someone), they differ. *** ## Role assignment methods | Role | Automatic assignment | Manual assignment | Workflow assignment | | ----------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------- | | **Requester** | Set to message sender (Slack, email, form) | Can be changed in ticket creation form or ticket details | Yes, via workflow actions | | **Author** | Always the person who created the ticket | Cannot be changed | N/A | | **Assignee** | Channel auto-assignment, round-robin | Ticket details, bulk operations, Slack commands | Yes, via workflow actions | | **Working on it** | Set when an agent picks up an inbound conversation; cleared when the ticket is published | Not manually editable | N/A (managed by the agent runtime) | | **Followers** | @mentions in messages, email CC recipients | Ticket details page | Yes, via workflow actions | | **Approvers** | N/A | Ticket creation form (individual users or user groups), ticket details | Yes, via workflow actions | *** ## Roles and notifications All human roles except author receive notifications: * **Requester**: Notified of status changes and new public messages. * **Assignee**: Notified of ticket changes, new messages, and assignment changes. Also receives private [assignment reminders](/documentation/tickets/reminders#assignment-reminders) while the ticket remains assigned, gated by their **Assignments** notification preferences. * **Followers**: Notified of ticket updates via Slack DM. Email preferences are configurable. * **Approvers**: Receive approval request notifications with action buttons. Pending approvers also receive private [approval reminders](/documentation/tickets/reminders#approval-reminders) on a schedule, gated by their **Approvals** notification preferences. * **Working on it**: No notifications. Agent ownership is internal routing and is intentionally excluded from assignment notifications, CSAT attribution, and OOO delegation. *** ## Roles and private ticket access For private tickets, roles determine visibility: * Requester, assignee, followers, and approvers all have access while they hold their role. * Workspace members and admins always have access regardless of ticket roles. * Removing someone from a role (e.g., removing a follower) revokes their access unless they qualify through another role. * @mentions in private tickets do NOT automatically add users as followers. You must explicitly add them to a role. *** ## Roles in automation **Workflows:** Use roles as triggers, conditions, and actions. Common patterns: * Trigger on assignee change to notify the new assignee's manager. * Add approvers automatically based on ticket type or form. * Add followers based on ticket channel or category. **Agent rules:** The agent can reference roles when determining behavior. For example, the agent can check who the requester is to personalize responses, or add followers when escalating. **Dynamic values:** Role fields (requester name, assignee email, etc.) are available as dynamic values in workflow actions for notifications, messages, and routing logic. *** ## Constraints and gotchas * A ticket always has exactly one requester and one author. Author cannot be changed after creation. * A ticket can have at most one assignee. Assigning a new person replaces the previous assignee. * Followers added via @mention work in public tickets but not in private tickets. For private tickets, you must explicitly add followers. * Email CC recipients are added as followers automatically, but the system filters out the requester, assignee, bot users, existing followers, and the message author. * Assigning a user to a task within a ticket automatically adds them as a follower on the parent ticket. * Approvers operate within [approval rounds](/documentation/tickets/approvals/rounds). Each round has a policy (ANY, ALL, or THRESHOLD) that determines when the round completes. Rounds run sequentially. * Removing a follower or approver from a private ticket revokes their access immediately, unless they hold another qualifying role. # Snippets Source: https://docs.ravenna.ai/documentation/tickets/snippets Save reusable response templates as snippets and insert them into ticket replies for fast, consistent answers. Snippets are reusable response templates that live at the workspace level. Save a frequently used reply once, then insert it into any ticket to keep tone, formatting, and policy language consistent without retyping. *** ## When to use snippets Common acknowledgements, policy explanations, troubleshooting steps, or closing messages that you send across many tickets. Standardize how your team communicates so every requester gets the same brand voice and approved wording. Drop a known-good response in seconds instead of composing it from scratch each time. *** ## Anatomy of a snippet Each snippet is scoped to a single workspace and has two fields you edit: * **Name** - A short label used to find the snippet (for example, `Password reset acknowledged`). * **Content** - The reply text inserted into a ticket message. *** ## Create a snippet Snippets are created from the reply composer on any ticket. Place your cursor in the reply composer. Type `/` in the composer to open the snippet popover. Choose **New snippet**. Enter a clear, searchable **Name** and write the reply in **Content**. Click **Save**. The snippet is immediately available to everyone in the workspace. *** ## Insert a snippet into a reply Place your cursor in the reply composer. Type `/` in the composer to open the snippet popover. Search by name and select the one you want. Review the inserted text, personalize it if needed, and send. Snippets are plain text. They do not auto-fill requester or ticket details, so edit the inserted text before sending if it references a specific person or case. *** ## Edit or delete a snippet From the reply composer on any ticket, type `/` to open the snippet popover. Find the snippet you want to change and open it. Update the **Name** or **Content** and click **Save**, or click **Delete** to remove the snippet. Deleting a snippet is permanent. Sent messages that used the snippet are unaffected, but the template will no longer appear in the popover. ## Mental model Snippets are saved response templates scoped to a workspace. Each snippet has a `name` used to find it and a `content` body that is inserted into a ticket reply. Snippets are not tied to a specific ticket, requester, or channel. They are workspace-wide building blocks the agent can pull into any outgoing message. The agent can list, search, retrieve, create, update, and delete snippets through the snippet MCP tools. *** ## When to use snippets * Inserting an established response for a recurring question instead of generating new wording each time. * Reusing approved policy language (for example, security disclosures or refund terms) verbatim. * Saving a high-quality reply you just composed so a teammate or future ticket can reuse it. * Updating a snippet when the canonical answer changes so every future reply uses the new wording. *** ## Constraints and gotchas * Snippets are workspace-scoped. A snippet created in one workspace is not visible in another. * `name` and `content` are both required and must be non-empty when creating a snippet. * Deleting a snippet is permanent. It does not affect messages that were already sent using the snippet, but the template will no longer appear in searches or future inserts. * Snippets are plain text content. They do not personalize themselves. If the saved response references a specific requester or ticket, edit the inserted text before sending. # Snooze Source: https://docs.ravenna.ai/documentation/tickets/snooze Snooze tickets to hide them from views temporarily and have them automatically return at a chosen time so you can focus on immediate priorities. Snooze tickets to temporarily hide them until you're ready to work on them. Snoozed tickets disappear from default views and automatically return when their snooze period expires. Use snoozing for tickets that depend on other work, need follow-up after a specific date, or when you want to focus on immediate priorities. *** ## Snooze tickets Click the three dots on any ticket and select **Snooze** to choose: * **1 Day**: Returns tomorrow * **3 Days**: Returns in three days * **End of Week**: Returns Friday at 9 AM (or next Friday if already Friday afternoon) * **Next Week**: Returns Monday at 9 AM (or next Monday if already Monday afternoon) * **Custom Date**: Choose any specific date and time Select **Custom Date** from the snooze menu to open a date picker where you can choose exactly when the ticket should reappear. *** ## What happens when snoozed Snoozed tickets disappear from default ticket views, giving you a cleaner focus on current work. When snoozed tickets appear in filtered views, they show a snooze badge indicating when they'll become active again. Tickets automatically reappear in default views once their snooze date passes. No manual action needed. When you snooze a ticket, team members receive notifications through Slack if granular notifications are enabled for your channel. *** ## Manage snoozed tickets See all snoozed tickets using filters: Click **Filters** at the top of your ticket list. Add a **Snoozed** filter. Set the filter to **True** to see only snoozed tickets. Remove snooze to make the ticket active immediately: Locate the snoozed ticket in filtered view or on the ticket detail page. Click the action menu (three dots). Select **Remove Snooze**. The ticket immediately returns to active views. *** ## Best practices Use snoozing for tickets that genuinely can't be worked on yet, not just to clear your view. This keeps your active ticket list meaningful and focused on actionable work. When snoozing tickets that affect others, add a comment explaining why and when you plan to return to it. This keeps everyone informed about ticket status. Periodically check your snoozed tickets to ensure the timing still makes sense. Priorities change, and you might need to adjust snooze dates. ## Mental model Snooze is a time-based visibility filter on a ticket. When a ticket is snoozed, it is hidden from default views until the snooze expiration time. The ticket still exists and is fully accessible via direct link or filtered views. Snooze does not change the ticket's status, priority, assignee, or any other property. Think of snooze as "remind me later." It is not a status change, not a workflow action, and not an assignment change. It is purely a display filter tied to a timestamp. *** ## Snooze vs other deferral mechanisms | Mechanism | What it does | When to use | | --------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------- | | **Snooze** | Hides ticket from default views until a specific time | Ticket needs follow-up later but no status change is needed | | **Status change** (e.g., Waiting) | Changes ticket status, visible in all views | Ticket is blocked on external input and the status should reflect that | | **Due date** | Sets a deadline, does not hide the ticket | Ticket has a completion deadline but should remain visible | | **Assignee change** | Transfers responsibility | Someone else should handle the ticket now | Use snooze when the ticket does not need attention right now but should resurface automatically. Use status changes when the ticket's state has genuinely changed. *** ## Snooze behavior * Snoozed tickets are excluded from default ticket views but can be found using the "Snoozed = True" filter. * When the snooze period expires, the ticket reappears in default views automatically. * Snoozing does not suppress notifications. If the ticket receives new messages or updates while snoozed, normal notification rules still apply. * Snoozing a ticket sends a notification to team members if granular notifications are enabled for the channel. * Snooze can be removed early, making the ticket active in default views immediately. *** ## Constraints and gotchas * Snooze is a per-ticket operation. There is no bulk snooze. * Snooze does not pause SLA timers or due date tracking. A snoozed ticket can become overdue while hidden. * Snooze is not a workflow action. You cannot snooze tickets via workflow automation. It is a manual user action only. * Quick snooze options (1 day, 3 days, end of week, next week) use 9 AM as the default return time. Custom dates allow specific time selection. * "End of Week" targets Friday at 9 AM, or the following Friday if used on Friday afternoon. "Next Week" targets Monday at 9 AM, or the following Monday if used on Monday afternoon. # Tasks Source: https://docs.ravenna.ai/documentation/tickets/tasks Break tickets into tracked subtasks with assignees, completion checkboxes, nested subtasks, and reusable templates for common multi-step workflows. Break down complex tickets into actionable task items with descriptions, assignees, and completion tracking. Create reusable task templates to standardize common workflows and ensure consistency across your team. Add tasks to tickets, assign team members, track completion with checkboxes, and organize work with nested subtasks up to 3 levels deep. Create task templates at the workspace level for common workflows like onboarding, incident response, and feature launches. Import templates into tickets to save time and ensure consistent processes. Monitor progress with completion counters, see assigned owners at a glance, and automatically add assignees as ticket followers for updates. *** ## Creating and managing tasks Add tasks to any ticket to break down work into actionable items with assignees and completion tracking. Navigate to any ticket in your workspace. Open the **Tasks** section from the ticket's tab bar or sidebar, wherever your layout places it. Click **Add Task** to create a new task item. Enter a description for your task. The description field auto-expands as you type, making it easy to add as much detail as needed. Paste a multi-line list into a task row to create one task per line. Ravenna strips common list markers (`- `, `* `, `1.`, `- [ ]`, `•`) as it splits the text, so you can paste directly from a doc or issue tracker without cleaning it up first. Hover over the task and click the user icon on the right to assign one or more team members. Assigned users appear as avatars next to the task. When you assign users to a task, they're automatically added as followers to the parent ticket, ensuring they receive updates. Assignees also receive a Slack and email assignments notification for the task, controlled by their notification preferences. Mark tasks as complete by clicking the checkbox next to each task. Completed tasks show with a strikethrough. The Tasks section header displays progress with a counter (for example, "2/5" means 2 out of 5 tasks are complete). ### Organizing with subtasks Create subtasks to break down complex tasks into smaller steps. Tasks can be nested up to 3 levels deep (parent → child → grandchild). Hover over any task and click the **+** button on the right. Click the chevron icon next to parent tasks to expand or collapse their subtasks. Nested subtasks maintain visibility of the overall structure while allowing you to focus on specific task groups. Hierarchical tasks help you organize complex work into manageable chunks while maintaining visibility of the overall structure. ### Managing tasks **Remove tasks** Delete individual tasks by hovering over them and clicking the **X** button on the right. Removing a parent task will also remove all of its subtasks. **Remove tasks added from a template** When a ticket has tasks imported from a task template, a **Remove Template** action appears next to **Add Task** and **Template** in the Tasks section header. Clicking it opens a confirmation dialog and, once confirmed, deletes every task item that came from the template (including their subtasks). Any tasks you added manually are kept. Use this when you want to clear an applied template without wiping the ticket's manually added checklist items. To replace the entire checklist with a different template's tasks instead, use **Template** to import a new one — importing still replaces all existing tasks. **Cancel and restore tasks** Cancel a task when it no longer needs to be done but you want to keep it visible for context (for example, a step that was skipped because a customer changed their request). Cancelling is non-destructive: the task stays on the ticket in a **cancelled** state and can be restored at any time. * **Cancel a task**: hover over an open task, click the row action menu, and choose **Cancel task**. Cancelled tasks are frozen. The description, assignees, and completion checkbox cannot be edited until the task is restored. * **Restore a task**: hover over a cancelled task, click the row action menu, and choose **Restore task**. The task returns to its previous open state and can be edited and completed again. Completed tasks cannot be cancelled directly. Reopen the task first if you need to move it into the cancelled state. The Tasks section header shows a cancelled counter alongside the completion counter when any tasks are cancelled (for example, "2/5 · 1 cancelled"). When a ticket is moved to **Done** or **Closed**, your workspace's [Close ticket task policy](/documentation/platform/workspaces/settings#close-ticket-task-policy) decides whether Ravenna prompts to cancel remaining open tasks in bulk. The default is to leave tasks open. **Reorder tasks** Tasks are displayed in the order they were created. To reorder tasks, you'll need to delete and recreate them in your preferred order. We recognize that reordering tasks is an important feature. It's on our roadmap and coming soon! *** ## Task templates Task templates let you create reusable sets of tasks that can be quickly imported into any ticket. Standardize common workflows like onboarding, incident response, feature launches, or any repeatable process your team handles. Task templates are workspace-specific and can be managed by any team member with access to workspace settings. ### Organize templates with folders Group related task templates into folders to keep your template library organized as it grows. Go to **Settings > Task Templates** in your workspace. Click **+ Folder** to create a new folder. Give it a descriptive name (for example, "Onboarding" or "Incident Response"). Drag and drop existing templates into folders, or create new templates directly within a folder. Folders are purely organizational. They do not affect how templates are imported into tickets. ### Create a template Go to **Settings > Task Templates** in your workspace. Click **+ Template** in the top-right corner. Fill in the template information: * **Icon and color**: Select an icon and color to visually identify your template * **Name**: Give your template a clear, descriptive name * **Description**: Add details about when to use this template (optional) Click **Save** to create your template. You can now add task items to it. ### Add task items to templates After creating a template, add the task items that will be imported into tickets. Click any template in the list to open its detail page. The **Items** tab shows all tasks in your template. Click **Add** to create a new task item. For each task item, you can set: * **Description**: What needs to be done * **Assignees**: Default users who should be assigned (optional) * **Subtasks**: Create nested tasks by clicking the **+** button on any task Pasting a multi-line list into a task row creates one item per line. Ravenna strips common list markers (`- `, `* `, `1.`, `- [ ]`, `•`) so you can paste directly from an outline or checklist. Click **Save Changes** when you're done editing task items. Task templates support the same 3-level hierarchy as regular tasks (parent → child → grandchild). ### Edit task items Modify task items at any time: * **Edit descriptions**: Click into any task description field to update the text * **Add or remove assignees**: Click the user icon to manage default assignees * **Reorder tasks**: Tasks maintain their creation order * **Delete tasks**: Hover over a task and click the **X** button to remove it Changes to task templates only affect future imports. Existing tickets that used the template won't be updated automatically. ### Import templates into tickets Save time by importing pre-configured task templates into your tickets. In the Tasks section of a ticket, click **Import** next to the Add Task button. Select from your workspace's task templates in the modal. Click **Import** to add all tasks from the template to your ticket. Importing a template will replace any existing tasks in the ticket, including tasks you added manually. Make sure to save any work before importing. If you only want to remove tasks from a previously imported template, use **Remove Template** in the Tasks section header instead. After importing, you can modify descriptions, assignees, and completion status for this specific ticket. Importing a template creates a copy of the tasks in the ticket. Changes to the template won't affect previously imported tasks. ### Manage templates **Edit template details** Update a template's name, description, icon, or color: 1. Click the template in the list to open its detail page 2. Click the **Details** tab to access the template configuration form 3. Make your changes and click **Save** to update the template **Delete templates** Remove templates you no longer need: 1. In the task templates list, check the boxes next to templates you want to delete 2. Click the delete action in the table or use the row action menu 3. Confirm you want to delete the selected templates Deleting a template is permanent and cannot be undone. Tickets that previously imported the template will keep their tasks. **Search templates** Use the search bar at the top of the task templates page to filter templates by name or description. This is helpful when you have many templates in your workspace. *** ## Template examples Create a template with tasks like: * Set up email account * Provision laptop and equipment * Add to Slack channels * Schedule orientation meetings * Assign onboarding buddy * Complete HR paperwork Standardize your incident handling: * Acknowledge incident * Assess severity and impact * Notify stakeholders * Investigate root cause * Implement fix * Verify resolution * Write post-mortem Ensure nothing is missed during launches: * Write feature documentation * Create demo video * Update changelog * Notify customer success team * Send announcement email * Monitor for issues * Collect user feedback Handle account closures consistently: * Export customer data * Cancel subscriptions * Remove access credentials * Archive account information * Send confirmation email * Update CRM records *** ## Best practices Write clear, actionable task descriptions that describe a single piece of work. If a task feels too large, break it down into subtasks. Assign at least one person to each task to ensure accountability. Multiple assignees work well for collaborative tasks. Create task templates for recurring workflows to ensure your team follows consistent processes across similar tickets. Check off tasks as they're completed to keep everyone informed of progress. The progress counter helps stakeholders see status at a glance. Begin with a few essential templates for your most common workflows. You can always add more as your team identifies patterns. Give templates descriptive names that make it obvious when to use them. Include the workflow type or department if helpful. Only set default assignees for tasks that always go to the same person or role. Leave others unassigned for flexibility. Review and update templates regularly as your processes evolve. Remove outdated steps and add new ones as needed. Use the description field to explain when and how to use each template. This helps new team members understand your workflows. ## Mental model Tasks are checklist items within a ticket. They break down a ticket's work into discrete, trackable steps with optional assignees and completion status. Tasks are not separate tickets. They live inside a single ticket and share that ticket's context, channel, and permissions. Key distinction: tasks vs child tickets. | Feature | Tasks | Child tickets | | ------------------- | ---------------------------------------- | ---------------------------------------------------- | | **Scope** | Checklist items within one ticket | Separate tickets with their own lifecycle | | **Depth** | Up to 3 levels of nesting | Unlimited parent-child hierarchy | | **Assignee** | Multiple assignees per task | One assignee per ticket | | **Status** | Open, completed (checkbox), or cancelled | Full status workflow (Open, In Progress, etc.) | | **Notifications** | Task assignees become ticket followers | Each child ticket has independent notification rules | | **Cross-workspace** | No, tasks exist within one ticket | Yes, parent and child can be in different workspaces | | **Templates** | Task templates for reusable checklists | No template system for child ticket structures | Use tasks for simple checklists where each item is a discrete action step. Use child tickets when each item needs its own status workflow, assignee lifecycle, or cross-team visibility. *** ## Task templates Task templates are workspace-scoped, reusable sets of task items. When imported into a ticket, the template's tasks are copied into the ticket. After import, the tasks are independent of the template. Key behaviors: * Importing a template **replaces** all existing tasks in the ticket. It does not merge or append. * The ticket UI also offers a **Remove Template** action that deletes only the tasks (and their subtasks) added by a given applied template, leaving manually added tasks intact. It appears in the Tasks section header when the ticket has any template-sourced tasks. This is a UI-only action and is not exposed to the agent. * Changes to a template do not affect previously imported tasks. * Templates support the same 3-level nesting as regular tasks. * Templates can have default assignees. When imported, those assignees are automatically added as followers on the ticket. * Templates can be organized into folders for easier management. Folders are purely organizational and do not affect template behavior. Common template patterns: * **Onboarding checklists**: Account provisioning, equipment setup, orientation scheduling. * **Incident response**: Acknowledge, assess, notify, investigate, fix, verify, post-mortem. * **Change management**: Request, review, approve, implement, verify, document. *** ## Tasks in automation Tasks can be created and managed through the Ravenna API and agent tools. When the agent reads a ticket, the response includes the ticket's full task checklist (as a flat list with parent/child relationships to reconstruct nesting) and any task templates that have been applied, so the agent can reason over checklist state directly without a separate lookup. The agent can: * List tasks assigned to the current user across the workspace, with linked ticket context. * Create a task or section header on a ticket, with an optional description, assignees, parent task (for nesting), and position among siblings. * Update a single task item: rename it, change its assignees, switch between task and header, re-nest it under a different parent, reorder it among siblings, or mark it complete or reopened. Updates are partial — only the fields the agent sends are changed. * Complete or reopen one or more tasks on a ticket in a single update, or apply a task template to a ticket (which replaces the existing checklist, matching the in-app behavior). * Search the workspace's task templates by name or description, and read a specific template's full item list to preview what applying it would add. Task deletion is intentionally not exposed to the agent. To remove tasks, delete them in the ticket UI, use the ticket's **Remove Template** action to clear all tasks that came from a given applied template, or apply a task template, which replaces the current checklist. Workflow actions can also interact with tasks when building automated processes. *** ## Constraints and gotchas * Tasks nest up to 3 levels deep (parent, child, grandchild). Deeper nesting is not supported. * Deleting a parent task deletes all its subtasks. * Tasks cannot be reordered after creation. They display in creation order. * Importing a template replaces all existing tasks in the ticket. This is destructive and cannot be undone. To remove only the tasks that came from a specific applied template while keeping manually added tasks, use the **Remove Template** action in the ticket's Tasks section header instead. * Task templates are workspace-scoped. There is no cross-workspace template sharing. * Assigning a user to a task automatically adds them as a follower on the parent ticket. This cannot be disabled. * Task completion does not trigger ticket status changes. Completing all tasks does not automatically close the ticket. * The reverse direction is governed by the workspace **Close ticket task policy** (Automation settings). When a ticket transitions from a non-terminal status into the **Done** or **Closed** group and the policy is set to **Cancel remaining tasks**, Ravenna prompts the agent and, on confirmation, cancels every open task on the ticket. The default policy leaves tasks open. Moving between two terminal statuses does not re-run the prompt. * Tasks have three states: open, completed, and cancelled. Cancelled tasks are frozen. Description, assignees, and the completion checkbox cannot be changed until the task is restored. Cancelling and restoring are UI row actions on the ticket's task list and are not exposed to the agent. * Tasks do not have their own due dates, priorities, or statuses beyond open, completed, and cancelled. # Link directly to your AI assistant Source: https://docs.ravenna.ai/guides/best_practices/driving_adoption/deep_linking Create deep links to your Ravenna AI assistant in Slack so employees reach support in one click from email, intranet, Okta, or onboarding docs. Deep links let users reach your AI assistant or support channels instantly, removing navigation friction and driving higher engagement. Deep linking takes users directly to a specific feature or location in an app, skipping homepages and menus. For Ravenna, this means you can create links that open the AI assistant or a support channel with a single click. This matters for adoption because every extra step between a user and help reduces the likelihood they'll reach out. Deep links eliminate those steps. ## Common use cases Once you have your deep links, you can place them anywhere your users already spend time: * **Okta portal footer** - Add a "Get Help" link that opens the AI assistant directly * **Okta app chiclets** - Create a one-click support tile alongside other apps * **Internal wikis and documentation** - Embed support access where users look for answers * **Onboarding materials** - Give new hires immediate access to help * **Email signatures** - Let every team member share a direct path to support ## Get your deep links ### Link to the AI assistant Look for Ravenna in your Slack sidebar under Apps. Right-click the Ravenna app, then select **Copy** > **Copy link**. This link opens the AI assistant for anyone with access to your Slack workspace. ### Link to a public support channel If you want to direct users to a specific support channel instead of the AI assistant: Open the public channel you want to link to in Slack. Right-click the channel name in the sidebar, then select **Copy** > **Copy link**. This link works for anyone with access to your Slack workspace. ## Test your links Before rolling out deep links widely, test them: 1. Click the link from where you plan to use it (Okta, wiki, etc.) 2. Verify it opens the correct channel or AI assistant 3. Test with a user who hasn't used Ravenna yet to confirm the experience If you encounter issues with deep links, contact [Ravenna support](mailto:support@ravenna.ai) for help. # Bookmark for easy employee access Source: https://docs.ravenna.ai/guides/best_practices/driving_adoption/okta/bookmark Add a Ravenna bookmark app in Okta so employees can launch your support assistant directly from their dashboard with a single click for help. ![Okta bookmark](https://d1kzozfjh72w00.cloudfront.net/documentation/screenshots/guides/best-practices/okta.webp) The Ravenna platform is most effective when employees can easily access support through the AI agent in Slack. For customers that use Okta, we recommend creating an Okta bookmark app that provides direct access to your Ravenna-powered support bot. This gives employees a convenient one-click way to get help with issues and requests through your organization's service desk. ### Creating the Okta bookmark app Within the Okta Admin UI, navigate to the **Applications** tab. Click Add Application. Search for Bookmark App. Add the Bookmark App as an application. Fill out the bookmark application details: * **Application label** = Your Ravenna bot name or Support Channel name * **URL** = Link to your Ravenna support bot or channel name. If you haven't got your links yet, you can find out how to do so [here](/guides/best_practices/driving_adoption/deep_linking#creating-deep-links) Change the logo of the new bookmark application to match your AI Assistant bot avatar or the Ravenna logo. Assign the bookmark app to all employees. The Ravenna bot will now appear as a bookmark for all employees to directly access support. Clicking on the bookmark will open a chat window directly to your Ravenna support bot for the employee. # Footer Assistance Source: https://docs.ravenna.ai/guides/best_practices/driving_adoption/okta/footer_assistance Configure the Okta dashboard footer help link to point employees to your Ravenna AI assistant for instant support without leaving their portal. For customers that use Okta, we recommend pointing the footer help link on your Okta portal to direct users to your Ravenna-powered support bot or public support channel. This provides employees with a convenient way to get help with issues and requests through your organization's service desk, if they are having issues with Okta directly. Select **Admin > Settings > Account**. Select **Edit** for the `End User Support` section. **Help link** - Enter a URL to deep-link to your Ravenna AI agent. This link appears in the footer of your end-users’ Home page. If you use this option, the Help link replaces the email address entered in the Technical contact option. Make sure you **enable** the `End User Help Form` option as this will still allow employees to contact the technical contact email if they are unable to access Slack. Set the `Technical Contact Email` to your Ravenna support email address. Employees can still reach out if they are unable to access Slack, and your agents can triage the requests within Ravenna just like a normal ticket. # Public vs private support channels Source: https://docs.ravenna.ai/guides/best_practices/public_vs_private_channels When should internal support happen in public, and when should it be private? Here's how to think about it and how Ravenna supports both.
![Slack Channels](https://d1kzozfjh72w00.cloudfront.net/documentation/screenshots/guides:best-practicies:public-vs-private.png)
![Slack Channels](https://d1kzozfjh72w00.cloudfront.net/documentation/screenshots/guides:best-practicies:public-vs-private--dark.png)
You don't have to choose between public transparency and private accessibility. Ravenna supports both, with AI agents that triage requests automatically no matter where they come from. When a teammate needs help, where should they go? A shared support channel like `#ask-it`, or a private message to avoid feeling exposed? The answer is both. Each approach has real benefits, and forcing teams to pick one creates unnecessary friction. This guide walks through when each works best and how Ravenna lets you support both without adding complexity. ## Public channels: Transparency by default Public Slack channels are the traditional home for internal support: * `#ask-it` * `#help-people` * `#feedback-product` * `#support-eng` - **Shared context** - Everyone sees questions and answers, reducing repeat requests - **Visible workload** - Teams can see support volume and balance the load - **Searchable knowledge** - Past conversations become self-service documentation - **Controlled interruptions** - Responders reply when ready instead of being pinged directly * **Hesitation to post** - Some people avoid asking what they see as basic questions publicly * **Channel noise** - Busy channels can feel overwhelming without clear structure * **Unclear ownership** - Without triage, messages can go unanswered ## Private DMs: Lower barrier to entry Private requests in Ravenna go to the Ravenna bot, not to an individual's personal DMs. To the requester, it feels like a simple one-on-one conversation. For support teams, it keeps personal inboxes clear and routes all requests into your workspace. * **Easy to start** - Messaging a bot feels as simple as messaging a person * **Safe for sensitive issues** - Great for HR questions, access requests, or awkward problems * **Protected inboxes** - Agents aren't interrupted in personal DMs—requests appear in triage channels * **Still trackable** - Private conversations flow into the same system as public ones * **Limited visibility** - The wider team can't learn from private exchanges * **Risk of being missed** - Without proper routing, private messages can slip through * **False expectations** - Some people assume private means instant attention ## How AI agents help with both Ravenna's AI agents monitor both public channels and private DMs, triaging requests automatically regardless of where they originate. This speeds up support for everyone. **For requesters:** * Instant acknowledgment and initial triage in both public and private * Faster routing to the right person or team * Immediate answers to common questions without waiting for a human **For support teams:** * Requests arrive pre-categorized and prioritized * AI handles routine questions in both channels and DMs * Clear handoff when human help is needed * 24/7 coverage across all entry points Agents remove the friction from both models. Public channels stay organized without manual triage, and private requests get routed correctly without agents checking their DMs constantly. ## How Ravenna supports both approaches You don't have to force your team into one model. Ravenna makes both work smoothly. ### In public channels * Turn any message into a tracked request with a shortcut or emoji reaction * Ravenna creates a thread and manages it as a structured ticket * Multiple responders can collaborate without cluttering the channel * Requesters get automatic updates as work progresses ### In private DMs * Teammates message the Ravenna bot directly for private requests * Sensitive issues stay private but are still tracked in your workspace * Support teams manage all requests from one place, whether they started in a channel or a DM Ravenna adapts to how your team already works, whether that's public by default, private when needed, or a mix of both. ## Recommendation: Default to public, allow private Use public channels as your default for transparency, knowledge sharing, and balanced support. But give people a clear path to private requests when privacy or comfort matters. With Ravenna, you can support both approaches without losing visibility, dropping requests, or overloading your team. AI agents handle the heavy lifting of triage and routing, so both paths work efficiently. Learn more about [setting up your first channel](/guides/day-one/set-up-first-channel) # Setting up an AI Agent Source: https://docs.ravenna.ai/guides/day-one/ai/agents Configure your first Ravenna AI agent with rules, knowledge access, and tool integrations to automate ticket triage and answer common questions. AI Agents are your customizable AI assistants that automate ticket creation, routing, and responses across your support channels. Create agents with specific rules, personalities, and capabilities to handle different types of requests.