}}` in the message or subject, for example `{{Trigger.incidentTitle}}`.
A trigger variable is one value per fire: the *same* for every recipient of that send. That's different from `{{Recipient.*}}` and `{{CSV.*}}` variables, which vary per recipient. Use trigger variables for facts about the event that fired the campaign (an incident title, a system name), and recipient variables to address each person.
You can use both in the same message. For example, `Hi {{Recipient.FirstName}}, a new incident ({{Trigger.incidentTitle}}) was opened. Please take a look.` renders each recipient's own first name next to the one incident from this fire. (Note that `{{Trigger.*}}` doesn't address the recipient: the campaign sends to its statically configured recipients, and the trigger value is shared across all of them.)
The set of `{{Trigger.*}}` keys your message references is the campaign's fire-time contract: every referenced key must be supplied on each fire, or that fire is rejected and nothing sends. (An empty value is allowed, but a *missing* key isn't.) The workflow you build from **Create trigger in Workflows** is pre-seeded to map each key, so it satisfies the contract out of the box.
Trigger variables only resolve for a triggered campaign. If you reference `{{Trigger.*}}` in a one-time or recurring campaign, Serval flags it and blocks activation: those campaigns have no trigger to fill the value.
You can preview how the message renders, and use **Send preview** to send yourself a test with sample values for each trigger variable, before activating.
### Wiring the workflow
The **Trigger Campaign** action is what fires the campaign from a workflow. **Create trigger in Workflows** sets it up for you, but it helps to understand what it does:
| Input | Purpose |
| - | - |
| **Campaign** | The campaign to fire, by ID. |
| **Trigger variables** | The values that fill `{{Trigger.*}}` in the message, read from the trigger payload. Supply every key the message references. |
| **Event ID** *(optional)* | A stable de-duplication key. See below. |
Serval de-duplicates fires by event ID so the same event never sends twice:
* **Provide an event ID** (for example, the webhook's delivery ID) and re-deliveries of that same event are ignored: the campaign fires exactly once for that event, even if the workflow runs again later.
* **Omit it** and the event ID defaults to the workflow run's ID, so an automatic retry of a run doesn't double-send: one run, one send. A new run sends again.
Don't hardcode a constant event ID. Serval treats it as "this one event," so the campaign would fire once and then quietly ignore every later call. Use the trigger's natural delivery ID, or omit it to get one-send-per-run.
### Activating, pausing, and runs
Triggered campaigns use the same lifecycle as recurring campaigns: **Activate** to arm the campaign so workflow fires send, **Pause** to stop sending on new fires (a run already in progress finishes), and **Resume** to re-arm it (fires that arrived while paused aren't replayed). Each fire creates a run on the campaign's **Runs** tab with its own delivery and response data.
### Good to know
* **Recipients are static.** The trigger fires the send and supplies per-fire variables, not the audience. Set recipients on the campaign itself.
* **Activate it first.** A draft or paused campaign ignores fires (nothing sends, and the workflow doesn't error).
* **Same team only.** A workflow can only fire campaigns in its own team.
***
## Choosing a Schedule
| Scenario | Recommended mode |
| - | - |
| "Send this right now" | One-time: Immediate |
| "Everyone should see this at 2:00 PM ET on March 15" | One-time: Scheduled |
| "Everyone should see this at 9:00 AM their time" | One-time: Local time |
| Urgent security notice or outage alert | One-time: Immediate |
| Weekly IT satisfaction pulse every Monday | Recurring: Day of week, local time |
| Monthly compliance check on the 1st | Recurring: Day of month |
| Quarterly tool check-in | Recurring: Month(s), select Jan/Apr/Jul/Oct |
| "When our HRIS posts a new hire, welcome them" | Triggered: fired by a workflow |
| "When a ticket is escalated, message the requester" | Triggered: fired by a workflow |
***
## Related
Walk through the campaign wizard step by step
Run, activate, stop, and manage campaign lifecycle
Build the workflow that fires a triggered campaign
Track delivery progress and response data
# Background agents
Source: https://docs.serval.com/sections/documentation/catalyst/agents
Set up agents that run on a schedule and surface findings for you to review
Background agents are Catalyst runs that execute on a schedule without you sending each message manually. An agent works over your team's tickets, workflows, databases, and connected apps on a recurring cadence, then surfaces what it found as a **finding** you can review, act on, or dismiss.
Use background agents for recurring, proactive work: summarizing the last day of tickets, scanning your device fleet for at-risk endpoints, reclaiming unused licenses, or spotting automation opportunities across your ticket volume.
## How background agents work
1. The agent runs on its schedule (or when you run it manually).
2. Each run is a Catalyst session you can open to see exactly what the agent did.
3. When a run produces something worth reviewing, it becomes a **finding** in the **New findings** feed on the Background Agents page.
4. You review the finding and apply, propose, dismiss, or acknowledge it.
A run only becomes a finding when it produces reviewable substance: an action the agent took or a highlight worth surfacing. Runs that find nothing actionable complete without creating a finding.
## Create an agent
You can start from a blank agent or install a prebuilt one.
Go to **Background Agents** in the team sidebar. It opens to your findings feed; the top right has **New agent**, **Agent library**, and **Past findings**.
Click **New agent**. In the **Build your custom agent by providing instructions** box, describe what you want the agent to do, and Catalyst opens a chat session and drafts it for you. Alternatively, install a prebuilt agent from **Browse ready to use agents** on the same screen (see [Installable agents](#installable-agents)).
Catalyst drafts the agent and opens it in the resource panel marked **Unpublished changes**. Review the configuration (below), adjust anything you want, then click **Publish** to start it running. Until you publish, the agent stays a draft.
### Agent configuration
Catalyst writes a first draft of the agent from your description, and you refine it. The agent's **name** appears as its title and can be edited. Review and change these settings in the resource panel while building, or later on the agent's **Agent configuration** tab. The sections are the same in both places.
The system prompt that runs every time the agent runs: what to look at, what to do, and what to produce.
When the agent runs. **Run manually** is always available. Add a schedule to have it run on its own: hourly, daily, on weekdays, or weekly, with a time of day (and the days of the week for a weekly schedule). Start times may vary by a few minutes.
**Run as** sets the user whose permissions the agent uses while it runs, so it can only see and do what that user can. **Share runs with team** controls visibility: when it's off, runs are visible only to the run-as user and org admins.
The agent always asks for approval before running a workflow that makes changes; read-only workflows run without asking. Add workflows here to let the agent run them without approval.
Who to notify, and when. Choose a **Notification method** (send to a **Recipient**, or use **Custom agent instructions**), then set the **Notification conditions**: **Report ready** (the agent produced a report), **Action required** (it needs your input to proceed), and **Session completed** (it finished, regardless of outcome).
The **Run as** user determines the agent's permissions on every run. If that user's access changes, the agent's capabilities change with it.
## Installable agents
Instead of writing instructions from scratch, install a prebuilt agent for a common use case and customize it. Each ships with a recommended schedule you can change.
Find installable agents from the Background Agents page: click **New agent**, then look under **Browse ready to use agents**. Search the list, and each card shows whether it's already **Installed** and who built it.
| Agent | Cadence | What it does |
| - | - | - |
| **Daily Ticket Digest** | Daily | Summarizes new and unresolved tickets from the last 24 hours and highlights what needs attention, with links back to each ticket. |
| **Service Desk QA / Quality Review** | Daily | Grades how human agents handled escalated tickets on clarity, correctness, comprehension, and collaboration, and produces a coaching scorecard. |
| **Proactive Device & Endpoint Remediation** | Daily | Scans the device fleet for at-risk endpoints, flags emerging issues, and drafts remediations for you to review. |
| **Ticket Trend & Volume Analytics** | Weekly | Tracks week-over-week ticket volume by category and surfaces the most common and critical failure patterns. |
| **Automation Opportunity Finder** | Weekly | Reviews recent tickets for repetitive, manual requests with no coverage and drafts the top workflows and help desk skills for you to review and publish. |
| **Proactive License Reclamation** | Weekly | Finds unused application licenses, reports the savings, and drives reclamation through your deprovision workflows. |
| **Identity Audit Log Anomaly Watch** | Daily | Watches your identity provider's audit log for suspicious sign-in and privilege activity, reports only what clears a stated threshold, and never changes an account itself. |
When an installed agent gets a new version, its entry shows **New version available** so you can pull in the updated instructions.
## Review findings
Each finding is the agent's pitch for a single run. The Background Agents page opens to your findings feed, split into **New findings** and **Marked as read**. Open a finding to see:
* **Highlights**: the key points on why the run matters.
* **Activity**: the concrete actions the agent took during the run.
* **Sources**: the tickets, resources, and web pages the agent drew on.
* **Changes to review**: any staged changes (workflows, skills, knowledge) the agent drafted, ready to inspect before publishing.
From a finding you can:
* **Apply** the suggested changes, or **Propose for review** on teams that require approval before publishing (see [Changes and reviews](/sections/documentation/catalyst/changes-and-reviews)).
* **Dismiss** the finding when there are staged changes you don't want.
* **Acknowledge** the finding to clear it when there is nothing to apply.
* **Chat about this** to open the agent's session and continue the work in Catalyst.
Findings you have already handled move to **Past findings** (top right), organized into **Applied**, **Acknowledged**, and **Dismissed** tabs and filterable by agent, where you can revisit them and open the underlying run.
## Manage agents
Open **Agent library** (top right of the Background Agents page) to see your active agents, each showing its owner and its schedule or trigger. Open one to reach its **Agent configuration** and **All runs** tabs, where you can **Run agent** on demand, **Pause schedule** to stop scheduled runs without losing the agent or its history (resume it later), **Open in Catalyst** to keep working on it in a chat, or **Delete agent**. Every run, scheduled or manual, creates a Catalyst session you can open to inspect exactly what the agent did.
## Learn more
The Catalyst chat surface and resource pane
How staged changes are reviewed and published
Build automations with Catalyst
Who can create and manage agents
# Building workflows
Source: https://docs.serval.com/sections/documentation/catalyst/building-workflows
How to build and edit workflows with Catalyst: prompting, manual edits, versioning, and temporary workflows
Catalyst can create and modify workflows through conversation. Most authoring starts in **Chat**, with results opening as tabs in the **resource panel** on the right.
***
## Natural language prompting
Describe what you want in plain language. Catalyst searches your team (workflows, tickets, knowledge, connected apps), drafts workflow code, and stages changes for review.
### Tips for effective prompts
* **State the outcome**: "Create a workflow that provisions Okta access when a manager approves"
* **Name integrations**: mention the dependent apps you expect to use
* **Reference existing resources**: "Update the @password-reset workflow to also notify the security channel"
* **Ask Catalyst to check first**: "Search installable workflows before writing one from scratch"
After Catalyst creates a workflow, it asks whether you want to test it. Testing is recommended but optional, and only runs when you explicitly agree.
***
## Workflow tab
You are not limited to chat. When Catalyst opens a workflow in the resource panel, you can make adjustments on the summary view or edit the TypeScript code directly.
When you start a new chat using a workflow’s **Run** button or the `/` workflow picker, the chat title includes the workflow name, such as **Run Onboarding**. Running a workflow in an existing chat preserves its established title.
Hover over the version status in the action bar and select **Full version history** to explore published versions and drafts. Use **Compare versions**, when available, to inspect differences. For workflow version history outside an active session, see [Workflow versioning](/sections/documentation/workflows/Manage/versioning).
### Published vs unpublished changes
Catalyst stages new and updated workflows as drafts. The **Publish** button on a workflow tab applies the change and exposes it to the help desk agent.
When **Require approval before publishing** is enabled under **Settings → Catalyst → Approval settings → Catalyst**, direct **Publish** is hidden. Publishing happens through structured reviews with designated approvers. See [Changes and reviews](/sections/documentation/catalyst/changes-and-reviews) for the full flow and settings.
***
## Connecting external apps
Catalyst needs working integrations before it can call Okta, Slack, Jira, and other services in workflows.
When an app integration is missing or needs credentials, Catalyst shows **Configure integrations** cards in chat. Each card shows the service and a **Connect**, **Configure**, or **Reconfigure** action:
* **Connect**: Built-in service not yet connected: starts OAuth or setup and creates the app instance
* **Configure**: App instance exists but authentication is incomplete
* **Reconfigure**: App is connected but credentials or scopes need refresh
Complete the setup by following card instructions. Credentials go directly to the integration, not through chat. Catalyst won't ask you to paste API keys, client secrets, or passwords in the message thread.
Don't paste secrets into chat. Use the in-chat setup cards instead. If you do paste a secret in chat, Catalyst won't use it. As a security best practice you should rotate any secrets posted into chat.
After you finish connecting, the card updates automatically.
### Choose which instance a step uses
If you connect more than one instance of the same app (for example, separate Okta tenants for US and EU employees), a workflow step could match any of them. To specify, select the specific instance a step should call from the instance dropdown, so there's no ambiguity about which one runs. Different steps can target different instances.
***
## Temporary workflows
Catalyst sometimes creates a **temporary workflow**, a short-lived workflow used to probe an API, fetch data, or validate an integration before building the real automation. Temporary workflows are not published to your team's catalog.
When Catalyst proposes a temporary workflow, a card appears in chat showing:
* The workflow name and a link to open it in the resource panel
* **Run** and **Reject** actions (unless the workflow is read-only, in which case it runs automatically)
***
## Confirming workflow inputs
When Catalyst runs a workflow that requires input confirmation, it presents the workflow's inputs as a **Confirm workflow inputs** form in chat instead of starting the run right away. Catalyst prefills any values it already gathered from the conversation. You review the inputs, complete or adjust them, and select **Confirm** to start the run.
***
## Related
What Catalyst can do
Get familiar with the Catalyst interface
Open your first session and publish a change
Using Catalyst to analyze ServiceNow tickets and build automations
Stage changes, propose reviews, and configure approvers
Building analytics dashboards with Catalyst
# Catalyst skills
Source: https://docs.serval.com/sections/documentation/catalyst/catalyst-skills
Teach Catalyst how to build your workflows and automations
Catalyst skills provide a way to teach Catalyst about how to build your workflows and common automations.
To create a skill, do the following:
1. From the team sidebar, open **Skills**.
2. In the top-right corner, click **New skill**.
3. In the **Create a new skill** modal, choose **Catalyst Skill**.
## Catalyst skills vs Help Desk skills
Catalyst skills are distinct from Help Desk skills. The two are compared in the table below.
| | Help Desk skills | Catalyst skills |
| :-: | :-: | :-: |
| How Serval uses them | The help desk agent handling employee requests | Catalyst when building automations |
| Where to manage them | **Skills → Help Desk Skills** tab | **Skills → Catalyst Skills** tab |
| Purpose | How the agent behaves when handling requests: tone, procedures, when to run workflows | Reusable context and instructions for Catalyst: team conventions, naming, deployment patterns |
| Visible to end users | Indirectly, through agent responses | No: builders only |
For more information, see [Help Desk skills](/sections/documentation/skills/overview).
## Examples
* **Help Desk skill**: "When someone asks for laptop replacement, gather the reason, run the laptop-request workflow, and set expectations on turnaround time."
* **Catalyst skill**: "Our team prefix is ENG. Always use installable workflows for Okta group changes when one exists."
***
## Related
Build automations in the Catalyst chat
Instructions for the help desk agent on end-user requests
# Catalyst workspace
Source: https://docs.serval.com/sections/documentation/catalyst/catalyst-workspace
Get familiar with the Catalyst interface
The **Catalyst** page is where you build automations by prompting the Catalyst agent. The page is accessed from the team sidebar and has two views: **Chat**, where you work with Catalyst, and a **Reviews** view for approving drafted changes (for teams that require approval before publishing).
***
## Chat
Chat with Catalyst to build automations from natural language descriptions. Above the chat composer are a number of ways to get started quickly, including **Quickstart**, **Browse prompts**, **Workflow types**, and **Install workflows**.
### Team vs private chats
Every Catalyst chat has a visibility setting:
* **Team chat**: Anyone on the team with Catalyst access
* **Private chat**: Only you
Choose visibility when starting a new chat from the picker on the composer. For an existing session, use the visibility picker in the chat header to switch between team and private.
Use **private chat** for experiments you are not ready to share. Switch to **team chat** when you want collaborators to find the session in the sidebar or continue the work.
### Fast vs thinking mode
Catalyst offers **Fast** and **Thinking** modes that trade off between speed and depth of reasoning:
* **Fast:** Best for quick edits, small changes, or straightforward questions
* **Thinking**: Best for complex implementations and multi-step builds
Select the mode from the dropdown in the chat composer. The choice applies to the current chat and is remembered per chat.
Managers can set a **default chat mode** under **Settings → Catalyst**. New sessions start with that default and individual users can still change mode in the composer.
### Read responses while Catalyst works
Scroll up in the conversation to pause automatic scrolling. New output continues to arrive without moving the text you're reading. Scroll back to the bottom or select **Jump to bottom** to follow new output again. Sending a message also returns you to the latest output.
You can also scroll up inside an expanded **Thinking** panel to pause scrolling there. The panel stays open when thinking finishes so you can keep reading.
### Interactive cards in chat
Catalyst sometimes renders interactive UI in the message thread instead of plain text.
#### Configure integrations
When a workflow needs an app that's not connected, Catalyst shows cards with **Connect**, **Configure**, or **Reconfigure** actions. Complete setup using the card instead of pasting credentials in chat. See [Connecting external apps](/sections/documentation/catalyst/building-workflows#connecting-external-apps).
#### Questions
Catalyst may ask clarifying questions with selectable options (single or multi-select). When you pick an option and submit, Catalyst will note your answer and resume working.
#### Temporary workflows
Catalyst may create a temporary workflow to probe an API, fetch data, or validate an integration in the process of completing a task. When Catalyst proposes a temporary workflow, a card appears in chat showing:
* The workflow name and a link to open it in the resource panel
* **Run** and **Reject** actions (unless the workflow is read-only, in which case it may run automatically)
### @Mention resources
You can mention existing resources (such as workflows and Help Desk skills) when chatting with Catalyst. Type "**@**" to see a list of existing resources, and keep typing to specify.
### File attachments
Attach files to Catalyst messages to share screenshots, data, or other context.
* Click the **plus** in the composer to pick files
* **Drag** files onto the chat area (a "Drop files to attach" overlay appears)
* **Paste** files from your clipboard when supported by your browser
#### Limits and supported types
* **Maximum file size:** 50 MB per file (under 25 MB recommended)
* **Maximum attachments:** 10 per message
* **Supported file types:**
* **Images**: PNG, JPEG, GIF, WebP
* **Documents**: PDF, DOCX, XLSX, Visio (.vsd)
* **Text**: CSV, TXT, Markdown, JSON
### Resource panel
When Catalyst creates or opens a resource such as a workflow or skill, a tab appears in the **resource panel** on the right side of the chat. Edits made via chat or directly in the panel are not live until you publish or complete a review.
Ticket labels also use this draft-and-publish flow. Click a label in the session resource list to open its resource tab and review its settings before publishing.
The panel keeps up to 50 resource tabs open, with reports outside that limit. Opening another resource closes the leftmost inactive resource tab. Closing a tab keeps its resource and staged changes intact; reopen it from the session resource list when needed.
***
## Learn more
What Catalyst can do
Open your first session and publish a change
Using Catalyst to analyze ServiceNow tickets and build automations
Stage changes, propose reviews, and configure approvers
Natural language prompting, manual edits, versioning
Building analytics dashboards with Catalyst
Teach Catalyst how to build your workflows
Scheduled agents that surface findings for review
***
## Related links
Instructions for the help desk agent on end-user requests
Builder access and team capabilities
Published versions and history for individual workflows
# Changes and reviews
Source: https://docs.serval.com/sections/documentation/catalyst/changes-and-reviews
Propose changes for review, configure approvers, and publish to your team
Catalyst requires users to expressly publish any changes to workflows, skills, and other resources. All updates made within a chat are grouped into a change set, which can be published directly or proposed for review depending on your team settings.
***
## Change sets
A change set collects every resource Catalyst modified in a chat session: workflows, help desk skills, Catalyst skills, dashboards, and more. You can view the change set in the collapsible changes slip above the chat composer.
Until you publish (or a review is approved and published), changes exist only as drafts tied to the chat session.
### Apply or reject a promotion
Open a promotion from either the sending or receiving team to apply or reject it. **Apply promotion** and **Reject** both require configuration-transfer permission in the receiving team, which team managers have. Managing only the sending team doesn't grant either action. If you lack this permission, both buttons stay visible but disabled. Hover over a disabled button to see which receiving team requires permission.
When a promotion doesn't require approval, **Review ready** notifications go to receiving-team members with configuration-transfer permission, excluding the requester. Open the review to inspect the changes before applying or rejecting them.
Required approvals, CI checks, and user matches must still be complete before you can apply the promotion.
While an apply attempt is running or has failed, the review shows **Apply attempted by** with the person's name. **Published by** identifies the person whose apply completed. Check the review status and resource results to see which changes reached the receiving team.
Where workspace environments are enabled, the workspace's **Reviews** page remembers your promotion path, application status, author, and title search when you return from a review or reload the page. These filters are saved in your browser separately for each signed-in user and workspace.
With **Test & Release** enabled, you can choose **Withdraw** on a promotion you proposed and confirm **Withdraw promotion**. The review moves to **Closed**. If no resource changes have been applied, its header shows **Withdrawn** even if an approval is still pending. The receiving team can't apply the withdrawn promotion.
### Review CI policy changes
Catalyst can stage your team's Review CI settings as a portable resource. Where Review CI is enabled, choose **Open resource → Review CI policy** to view required workflows and evaluation suites. In a Catalyst session, you can stage changes to these checks and inspect additions and removals before proposing or publishing them.
You can also open **Promotion checks** from **Test & Release → Reviews** or an environment or branch row on **Environments**. Promotion links open Reviews with promotions selected. The dialog identifies the team whose policy you're viewing. Users with permission to manage that team's SDLC settings can select checks and choose **Save checks**; users with settings-view permission can inspect the policy without editing it.
Each CI attempt captures the checks it runs and their results. The review's check list links to the resulting workflow or evaluation-suite run so reviewers can inspect the evidence before publishing.
Promotion workflow checks run in the source team before the promotion is applied. A target team's policy can require checks, but those workflows still execute in the source team. Resource lookups within a check use the team specified by the workflow; `ctx.currentTeam` refers to the source team. To investigate a failure, open the linked run and inspect its error rather than inferring the cause from the target team's configuration.
For each selected evaluation suite, choose **Minimum pass** to set a whole-number percentage from **1% to 100%**, then choose **Apply** and save the policy. The default is **100%**. This threshold belongs to that suite's entry in the CI policy; workflow checks still have to pass individually.
Suite CI waits for the run to finish and divides evaluations that met their expected result by **all evaluations in that run**. Missing scores count against the total. An empty suite or an execution error fails CI regardless of the percentage. The linked suite run shows this CI result separately from the **Scored evaluation pass rate**, which considers only scored evaluations.
During a branch promotion, required checks come from the receiving team's current policy plus any CI policy included in the review. Unrelated checks in the source team's policy do not block the promotion. Checks run against the source team's published configuration, using the stricter minimum pass percentage when both policies require the same suite. Removing a selected check from the source team's live policy does not stop it from running for that review. Reviewers can inspect suite changes and percentage changes in the promotion diff. Removing a receiving-team requirement from the selected policy cannot bypass it; unavailable required workflows or evaluation suites still fail CI.
The review's **Rerun all** action creates a fresh CI attempt and reruns the full required suites. Rerunning an individual evaluation separately does not update an earlier CI attempt's result. Each attempt retains the threshold used for that attempt.
For branch promotions, **CI not started** means required checks haven't started; open the checks and choose **Start checks**. **CI rerun required** means the last attempt doesn't cover the current policy, and **CI blocked** means a required check failed. **Apply promotion** stays disabled until the required checks pass. If a required workflow or suite is missing from the source policy, use **Pull latest** to bring the parent's changes into the branch, apply that update, and choose **Rerun all** on the original review. Pulling the policy doesn't replace the original review's CI results.
### Publishing and discarding individual changes
You don't have to publish an entire change set at once. When approval isn't required, you can publish or discard individual changes from the changes slip above the composer, or from a resource's own tab. Publishing a change also applies any drafts it depends on; discarding one also discards the drafts that depend on it, so the change set stays consistent.
***
## Direct publish vs review
Which path you use depends on the Catalyst review approval settings. Team managers can open **Settings → Catalyst → Approval settings → Catalyst** to configure the policy.
* If **Require approval before publishing** is off, users with Builder permissions or higher can directly publish changes drafted by Catalyst.
* If **Require approval before publishing** is on, users with Builder permissions or higher must propose the change set for review. Designated approvers must sign off before anyone can publish.
When approval is required, per-resource **Publish** buttons are hidden. Publishing happens only after a review is approved and someone clicks **Publish**.
***
## Team settings for reviews
Managers can configure review behavior under **Settings → Catalyst** by clicking **Approval settings**.
In the **Approval settings** dialog, select **Catalyst** to configure publishing approvals for Catalyst changes.
### Require approval before publishing
When enabled:
* Builders must propose change sets for review rather than publishing directly from the chat.
* Configured approvers must approve or deny each review.
* After approval, an authorized user clicks **Publish** on the review to apply the change set.
When you require approval before publishing, configure at least one approver step, which can consist of users, groups, or special members like Team owners. Click **Save changes** after editing approvers.
Leave approval off for small teams that trust every builder to publish. Turn it on when changes need a second pair of eyes before they go live.
***
## Propose for review
When approval is required and you have pending changes:
1. **Finish staging changes**: Confirm every resource in the change set shows the state you expect.
2. **Click Propose for review**: In the collapsible bar above the composer, click **Propose for review**.
3. **Add title and description**: Enter a short title (required) and optional description explaining what changed and why. Click **Propose**.
4. **Notify reviewers**: The review appears in the **Reviews** view of the **Catalyst** page for teammates with access. They can inspect changes without opening your private chat (unless you shared it as a team chat).
Each pending change set can have one review. Reviewers approve the change set as it stood when the review was created. If newer changes are saved in the same chat, the original review shows **Needs new review** and disables **Publish**. Choose **Go to Catalyst session**, then **Propose for review** to submit the latest changes for approval.
***
## Reviewer workflow
Slack change set approval messages show the **Target environment**, so you can check where the changes will apply before approving.
When email notifications are enabled, designated approvers receive a **Change set approval** email for Catalyst changes. The email includes the review title, a summary of up to 500 characters, requester, and resource count. Click **Open review** to read the full description, inspect the changes, and approve or deny them in Serval.
1. Open the **Catalyst** page from the sidebar and switch to the **Reviews** view. Reviews show a title, proposer, linked resources, and status.
2. Select a review to see title and description (editable by reviewers with access), Catalyst session link that opens the originating chat if you have access, per-resource diffs (workflow code changes, skill content, etc.)
3. Approve or deny the review
When all required approvers have signed off, the review shows **Approved**. Someone with publish permissions can now click **Publish** on the review to apply the change set.
***
## After publishing
* Resources show as **Published** in the originating chat session
* Workflows appear in **Workflows**, skills in **Skills**, and dashboards in **Analytics**
* The review status updates to **Published**
If publishing or applying a promotion fails, select the failed resource in the review. Its error message identifies the resource, explains the cause when known, and suggests a next step. For example, invalid workflow code requires a correction and an updated change; a temporary service failure can be retried later.
If a simulation config's name is already used in the receiving team, rename the incoming config or resolve the existing config before submitting an updated change.
Failure guidance is currently shown in English. Older failures without readable guidance show a support fallback.
If a workflow references a custom app that can't be resolved in the target team, connect the required custom app in **Integrations** and retry the failed change. If the workflow's `HttpIntegration` alias is incorrect, correct it to match a configured app and submit an updated change.
The review keeps successfully applied changes separate from failed changes. Follow the failed resource's guidance before retrying. For an unknown failure, choose **Copy support reference** and include the reference when you contact support.
You can also ask Catalyst in the originating chat to inspect the latest publish results and identify failed resources and their dependencies. A successful simulation run doesn't establish that other draft changes published. Check the remaining drafts before discarding them.
***
## Read reviews through the API
Use the read-only `/v2/reviews` API to inspect an existing review from an integration or approval workflow. It supports reviews from Catalyst sessions, background-agent sessions, and promotions.
1. Call `GET /v2/reviews?teamId=TEAM_ID` to find reviews owned by a team. Use `outgoing=true` to list promotions from that team.
2. Call `GET /v2/reviews/REVIEW_ID` for the source and target organizations and teams, session context, current approval status, and change-set apply status. `origin` is `REVIEW_ORIGIN_CATALYST` for session-owned reviews (including background-agent sessions) or `REVIEW_ORIGIN_PROMOTION` for config pushes. If a source or target team has been deleted, its organization ID is omitted.
3. Call `GET /v2/reviews/REVIEW_ID/items` for item metadata. Pass `nextPageToken` back as `page_token` until it is empty. Both list endpoints default to 50 results and accept a `page_size` up to 100.
4. Call `POST /v2/reviews/REVIEW_ID/items:batchGet` with `{"itemIds":["ITEM_ID", "OTHER_ITEM_ID"]}` for up to 20 unique items' `before` and `after` resource documents. Results follow request order; a missing item or an item from another review fails the entire request. You can also read one item with `GET /v2/reviews/REVIEW_ID/items/ITEM_ID`. Creates have no `before` document; deletes have no `after` document. Updates merge the proposed patch onto the comparison's before state.
The documents use the same backend comparison behavior as the review UI. Pending updates and deletions may use live resource data, so later edits can change the comparison. Pagination doesn't freeze the review. Documents use the portable review format, not the public API's create or update request format. Recognized credential patterns are redacted. If `contentStatus` is `REVIEW_ITEM_CONTENT_STATUS_MISSING_BASE` or `REVIEW_ITEM_CONTENT_STATUS_UNSUPPORTED`, stop automated approval and send the item for manual inspection.
Each item's `resourceKind` uses the backend's canonical kind, such as `workflow` or `skill`. Its `applyResult` contains exactly one outcome: `pending: {}`, `applied: {}`, or `failed: {"reason": "…"}`. This is the result of applying the staged change, not the resource's runtime status. Failure reasons are redacted. `contentStatus` separately describes whether its comparison documents are available; an applied item can still have unavailable documents.
Scoped API keys need **Read reviews** (`reviews:read`) and access to the source or target team. A workflow in either team can read the promotion's details, items, and comparison documents. Session reviews require access to the session's team. Cross-organization programmatic reads aren't supported.
`approval.status`, `approval.required`, `review.applyStatus`, and `review.closedAt` describe separate states. An approved review is not necessarily published. These endpoints don't create, approve, close, or publish reviews.
### Read a review in an approval workflow
Get the review ID from the approval context and call the public API with `serval.apiRequest`. It uses the workflow's authenticated connection and existing retry handling.
```typescript theme={null}
const reviewId = serval.context.getChangeSetReviewForApproval(ctx)?.subjectId;
if (!reviewId) throw new Error("This approval step has no configuration review");
const response = await serval.apiRequest(
{
method: "GET",
path: "/v2/reviews/{review_id}",
pathParams: { review_id: reviewId },
},
ctx,
);
const review = response.data;
```
Use the item-list and batch-read endpoints above to inspect every page of changes. Your workflow decides how to route approval and handles missing or unsupported content. Reading a review doesn't approve or publish it.
### Ask Catalyst to inspect a review
In a team workspace, give Catalyst a review link, ID, or title and ask it to identify behavioral risks. The review-reading skill isn't available in personal workspaces. Catalyst finds the review, reads its item pages, and fetches before/after documents in batches. It reports what it inspected, any unavailable content, and questions a human should resolve before approving.
Review text and code are treated as untrusted content. Catalyst respects access restrictions and does not approve or publish the review. Continue in **Reviews** to make the human decision.
## Related
What Catalyst can do
Get familiar with the Catalyst interface
Open your first session and publish a change
Using Catalyst to analyze ServiceNow tickets and build automations
Natural language prompting, manual edits, versioning
Building analytics dashboards with Catalyst
# Configure access management
Source: https://docs.serval.com/sections/documentation/catalyst/configuring-access-management
Use Catalyst to automate access requests by configuring roles, profiles, policies, and provisioning
Catalyst can configure Serval's [access management](/sections/access-management/overview) from a plain-language description: the roles employees can request, whether requests need approval, how long access lasts, and how access is actually granted. Catalyst drafts everything for you to review and publish, so nothing goes live until you approve it.
## What Catalyst can configure
* **Set up an app for access requests**: create the roles employees can request on an app or a specific resource inside it (a Slack channel, GitHub repo, AWS database, and more). If the app isn't connected in Serval yet, Catalyst can create it too (native or custom), so access setup works end to end in one session.
* **Access profiles**: control which users or groups can request access to a role in the Help Desk.
* **Access policies**: configure approvals, max access length, and business justification for a role.
* **Provisioning**: how access is granted, whether by a linked identity-provider group, a manual task assigned to a person or group, or a custom workflow.
## How it works
Describe what you want in a Catalyst session. Catalyst identifies the app, the resource, and the roles involved (creating the app in Serval if it isn't connected yet), then drafts the roles, policies, and profiles as items in the side panel. Review the drafted items and click **Publish** to make them live. Nothing changes until you publish. For information on how staging and publishing work, see [Changes and reviews](/sections/documentation/catalyst/changes-and-reviews).
## Example tiered access flow
A single prompt can set up a full access flow, including creating the app in Serval if it isn't connected yet. Consider the following example prompt:
> Set up access management for Figma. Employees should be able to request Editor or Admin. Editor is self-serve, no approval. Admin requests need my approval, and access should expire after 30 days. Provision both roles from our Okta groups: `figma-editors` for Editor and `figma-admins` for Admin.
From that description, Catalyst drafts three items:
* An **Editor** role: self-serve with no approval, provisioned through the `figma-editors` Okta group.
* An **Admin** role: gated by an access policy, with access that expires after 30 days, provisioned through the `figma-admins` Okta group.
* A **Figma Admin Approval** access policy: a 30-day access duration with you as the single approver.
Review the three items in the side panel and click **Publish**. You can publish the whole change set at once, or use the **Publish** button on an individual resource's tab to publish just that item. If it depends on other staged items, Catalyst publishes those alongside it. The result is a tiered flow: Editor is instant and self-serve, while Admin requires your approval and expires automatically after 30 days. Both roles provision automatically through their linked Okta groups, so each grant is a single membership change you can audit.
## Provisioning methods
When Catalyst sets up a role, it configures how access is actually granted. A role can't grant access until it has a provisioning method:
* **Linked group**: the grant maps to an IdP group (Okta, Microsoft Entra, Google Workspace). Prefer this when possible, since it makes each grant a single membership change you can audit, with no custom workflow to maintain.
* **Manual**: a person or group grants access by hand.
* **Custom workflow**: a workflow provisions and deprovisions access for systems that need bespoke API calls.
## Usage tips
* **Access profiles grant request eligibility, not automatic access.** A profile controls which roles a group is allowed to request in the Help Desk. It doesn't assign those roles to group members automatically.
* **Changes are drafted, then published.** Catalyst stages access changes for review. Click **Publish** to apply them. Nothing is live until you do.
## Related
Roles, access policies, provisioning, and the full access lifecycle.
How Catalyst stages changes and how you review and publish them.
Build the workflows that access requests and provisioning rely on.
# Building dashboards
Source: https://docs.serval.com/sections/documentation/catalyst/dashboards
Building analytics dashboards with Catalyst
Catalyst can build analytics dashboards for your team directly from natural language.
When you describe what you want to see, Catalyst will:
* Design the widgets
* Run them against your data
* Stage the dashboard as a draft you can review
***
## What Catalyst can build
An analytics dashboard is a collection of widgets arranged on a grid, backed by workflows that query your data. This can include Serval data (like tickets, access requests, assets, and workflow runs), as well as any data from connected apps (like ServiceNow or GitHub data) or public APIs.
Catalyst can author dashboards with any combination of:
* **Charts**: bar, line, area, and pie charts
* **Tables**: row-level views, top-N lists, detail grids
* **Stats**: single-number KPIs (counts, averages, sums) with trend indicators and sparklines
* **Text**: section headers and inline commentary
* **iFrame**: embeds of external content (only certain sites that explicitly support embedding)
* **JSON**: raw structured output, useful for debugging
Charts, tables, stats, and JSON widgets require a workflow connection. Text and iFrame widgets can display static content without one. Widgets can share workflows when they read the same dataset (for example, a stat and a table both summarizing the same query), which keeps the dashboard lean.
***
## Tips for better dashboards
Catalyst handles dashboards best when you give it three things up front:
* **Purpose**: What question the dashboard answers ("ticket triage health", "access request volume by team", "device fleet status").
* **Time range:** The default window for the data ("last 30 days", "this quarter", "year to date").
* **The widgets you have in mind**: A rough sketch is enough ("a count, a trend chart, and a breakdown by priority").
If your request is ambiguous, Catalyst will ask a couple of targeted clarifying questions before building.
For comparison colors, describe what improvement means: lower response time,
higher availability, or no preferred direction for a metric such as request
volume. You can also request specific series colors. See
[Chart colors and stat comparisons](/sections/documentation/platform/analytics#chart-colors)
for how these choices appear on the dashboard.
### Example prompts
* "Build me a dashboard for ticket triage over the last 30 days. Total open tickets, a trend chart, top assignees, and a breakdown by priority."
* "Access requests by app (Figma, GitHub, AWS, Salesforce, Ramp) with approval times and denial rates."
* "CrowdStrike detections and Qualys vulnerabilities by severity, trended weekly."
* "Offboarding SLA dashboard: time from Workday termination to Okta deactivation and license reclaim."
***
## Time-range variables
Most dashboards include a time-range variable so the whole dashboard can be scoped to a window from a single control. Catalyst wires this up automatically when you mention a time range in your request, and uses the range you specified as the default. After publishing, you can change the range from the dashboard controls without re-running Catalyst.
To choose specific dates, open the time-range control and select **Custom…**. Choose **From** and **To** dates in the calendars, then select **Apply** in the side panel. Both dates use UTC; changes stay in the panel until you apply them.
When the selected range differs from the saved default, **Temporary view** appears beside the time-range control. Select **Reset** to return to the saved range, or **Set as default** to save the current range for the dashboard. Setting a default requires edit permission. You can switch to **Editing** while keeping a temporary range; switching modes does not save it as the default.
If you'd rather lock a widget to a specific data slice (for example, a "Q1 results" widget that shouldn't move with the dashboard's time control), say so explicitly, and Catalyst will use concrete values for that widget instead of wiring it to the variable.
***
## The build process
When Catalyst builds a dashboard, you'll see activity in three phases:
* **Register the dashboard.** Catalyst commits the dashboard's name, time-range variables, and an empty layout. The dashboard appears as a draft in the side panel immediately.
* **Build each widget.** For every widget on the plan, Catalyst writes a workflow, runs it against your data, optionally previews the widget inline in chat so you can confirm it looks right, then attaches it to the dashboard.
* **Finalize the layout.** Once every widget is built, Catalyst arranges them on the grid and updates the dashboard with the final layout.
Throughout the build, you can view and explore the draft dashboard. After Catalyst builds the initial version of the dashboard, you can continue to chat with Catalyst to iterate on dashboards before publishing.
Catalyst checks required workflow connections when creating or updating a dashboard draft. If a widget is missing its required connection, the change is rejected so Catalyst can correct it before it reaches review.
### Sharing workflows across widgets
Catalyst is deliberate about workflow reuse. If two widgets read the same dataset (for example, a count and a table both summarizing tickets by priority over the same window), they'll share a single workflow. This makes the dashboard easier to maintain and faster to refresh.
When widgets read genuinely different data (different time windows, different fields), Catalyst writes separate workflows.
***
## Editing a dashboard
Catalyst can edit dashboards you've already published. Common edits include:
* **Add a widget**: "Add a stat showing total resolved tickets to my triage dashboard."
* **Edit a widget in place**: "Change the trend chart to weekly buckets instead of daily."
* **Remove a widget**: "Drop the assignees table from the triage dashboard."
* **Rename or re-describe the dashboard.**
* **Change the time-range variable**: "Default to last 90 days instead of last 30."
Simply @mention the dashboard and Catalyst will find it. Edits are staged in the resource panel in the same way a brand new dashboard does, and **Publish** applies the changes to the live dashboard.
### Removing widgets
Removing a widget is an explicit action. If you want a widget removed, you must explicitly ask Catalyst to remove it.
### Iterating on a widget
If a widget doesn't look right (wrong chart type, wrong columns, wrong grouping), tell Catalyst what to change. It will update and re-render the preview so you can confirm the new format before publishing.
***
## Reviewing and publishing
When Catalyst finishes, you'll have a dashboard draft in the resource panel. From there you can:
* Open the dashboard preview to confirm the widgets render correctly and the layout reads well.
* Open any individual widget to inspect its workflow and configuration.
* Click **Publish** to save the dashboard. Widget workflows are scoped for dashboard rendering only and are not exposed to the help desk agent.
### Refresh dashboard data
On a published dashboard, open **Data Sources** from the dropdown beside the refresh control. Search by workflow name to narrow the list, or select a source to open its workflow.
Select **Refresh all** at the bottom to refresh the dashboard’s data sources, including sources hidden by your search. In a temporary view, refresh uses the selected time range without changing the saved default.
***
## Related
What Catalyst can do
Get familiar with the Catalyst interface
Open your first session and publish a change
Using Catalyst to analyze ServiceNow tickets and build automations
Stage changes, propose reviews, and configure approvers
Natural language prompting, manual edits, versioning
# Getting started with Catalyst
Source: https://docs.serval.com/sections/documentation/catalyst/getting-started
Start your first Catalyst session and publish your first workflow
This guide walks you through your first working Catalyst session.
***
## Prerequisites
Catalyst is on by default. To publish workflows, you need **Builder** permissions or higher.
***
## Configure defaults (optional)
**Catalyst** appears in the team sidebar, at the top of the group with **Workflows**, **Skills**, and **Background Agents**. As a Manager, you can set the default chat mode and whether publishing requires review under **Settings → Catalyst**. See [Changes and reviews](/sections/documentation/catalyst/changes-and-reviews#team-settings-for-reviews).
***
## Start your first session
Click **Catalyst** in the sidebar. You land on the chat view with a new-session composer.
Before sending a message, set **Team chat** or **Private chat** (who can see this session) and **Fast** or **Thinking** (speed vs depth for the agent's reasoning).
Send a concrete prompt, for example: "Create a workflow that adds a user to the "all-staff" Slack channel when they're onboarded. Search installable workflows first before writing new code."
Click **Quickstart** above the chat window for common first steps, or **Browse prompts** for more example requests.
Inspect the workflow summary and the code if desired. Ask follow-up questions in chat or edit the code directly in the resource panel.
After you create a workflow, Catalyst asks if you want to test it.
If your team allows direct publishing, click **Publish** on the workflow tab or above the chat composer. If your team requires review before publishing, click **Propose for review** above the chat composer. See [Changes and reviews](/sections/documentation/catalyst/changes-and-reviews).
Once published, your workflow appears in **Workflows**. Configure [triggers](/sections/documentation/workflows/Run/triggers), check [run history](/sections/documentation/workflows/Run/run-history), and debug from Catalyst as needed.
***
## Related topics
What Catalyst can do
Get familiar with the Catalyst interface
Using Catalyst to analyze ServiceNow tickets and build automations
Stage changes, propose reviews, and configure approvers
Natural language prompting, manual edits, versioning
Building analytics dashboards with Catalyst
# Building journeys
Source: https://docs.serval.com/sections/documentation/catalyst/journeys
Creating multi-threaded journeys using Catalyst
A journey is a multi-step, structured process in Serval that coordinates many tasks across many people, in the right order, over days or weeks. Journeys are used most often for onboarding and offboarding, but can be useful anywhere a process spans multiple people or systems. Catalyst can design and build these journeys for you through natural language or with an uploaded flowchart.
To learn more about journeys, see [Journeys](/sections/documentation/journeys/overview).
***
## What journeys don't do
Journeys don't directly control access provisioning (adding users to IdP groups, granting app roles, assigning licenses). You can set a journey to *trigger* access requests and track the completion in tasks, but you will need to handle the access logic itself in [**Access Management**](/sections/access-management/overview).
***
## Cross-team journeys
Journeys frequently cross team boundaries. IT, HR, Security, and Finance each own pieces of onboarding. Catalyst handles this natively: tell it which team owns each task and it will route assignments accordingly. Each team sees only their tasks in their queue, while the journey as a whole tracks end-to-end completion. You can include workflows and automations from other teams to attach to tasks.
For information on how cross-team journeys appear to admins and end users, see [Cross-team journeys](/sections/documentation/journeys/cross-team).
***
## Create a journey in Catalyst
### Use natural language instructions
Open a Catalyst chat and describe the journey in plain language. The more concrete you are about *who does what, in what order*, the less Catalyst has to ask back. A useful prompt covers:
1. **The trigger**: What kicks the journey off (a form submission, a date, an event in your HRIS)
2. **The tasks**: The discrete steps, in order
3. **The owners**: Which team or role handles each task
4. **The dependencies**: Which tasks must wait for others
For example:
> "Build me an onboarding journey for new engineers. When there's a new-hire event in Workday, IT should create an Okta account and order a laptop in parallel. Once the account exists, HR runs a background check and the hiring manager gets a task to prepare a welcome doc. The new hire's first-day checklist task only opens after the background check is complete."
### Use a flow chart diagram
You can also upload a flow chart diagram. For a list of file formats, see [File Attachments](/sections/documentation/catalyst/catalyst-workspace#file-attachments). Catalyst will read the diagram and create a journey based on the chart. As with a text description, the more concrete information you include, the fewer follow-up questions Catalyst needs.
You can upload a flow chart to start and then use natural language prompts to iterate.
## Attaching workflows to tasks
Each task or subtask can optionally have an attached workflow that runs automatically or after collecting inputs from the employee. If the workflow requires inputs, the journey task shows a form to collect them and runs the workflow once the assignee fills it out.
Tell Catalyst to attach a published workflow to a task by @-mentioning it in the prompt, or describe a new workflow for Catalyst to build, publish, and attach.
For example:
> "Attach the @Create Okta account workflow to the 'Set up accounts' task, and run it when the task starts, using the new hire's email from the journey."
For more information about tasks and attached workflows, see [Journey tasks](/sections/documentation/journeys/tasks).
## Live journey preview
Your draft is immediately testable in the Catalyst chat. You can run it on yourself or a test user without publishing first. If a task is assigned to the wrong group, a dependency is backwards, or you want to split a step into subtasks, just tell Catalyst in the same chat and it will update the draft in place.
When you build a journey with Catalyst and initiate a test run, Catalyst's run-details panel automatically switches into a **live journey preview**. The preview shows the overall layout of the full journey page, with tasks organized in columns by assignee. For more information on tasks and task states, see [Journey tasks](/sections/documentation/journeys/tasks).
## Publishing
When the journey looks right, click **Publish** in the side panel. That exposes it to the help desk agent and any external triggers (scheduled runs, webhooks, HRIS events) so it can run for real employees.
## Use databases to save journey state
A journey often needs to carry state across its tasks. For example, in an employee onboarding journey, an account ID created in an earlier task is needed by a later task once a background check clears. [Serval databases](/sections/documentation/databases/overview) store that state and let you reference it from tasks and tickets throughout the journey.
You don't have to build this manually. When you build the journey in Catalyst, describe the state you want to keep. Catalyst gives each journey type its own entity type in a Serval database (for example, `onboarding-journey-state`), keyed by the journey ticket ID so each journey has exactly one row, and sets up the steps that read and write it.
## Tips for working with Catalyst on journeys
* **Name tasks the way employees will read them.** "Sign offer letter" beats "Execute employment agreement workflow."
* **Be explicit about parallelism.** Specify if two tasks can happen at the same time. Otherwise, Catalyst may chain them sequentially.
* **Mention reminders and SLAs.** If a task should escalate after 2 days, tell Catalyst up front rather than bolting it on later.
* **Test before publishing.** Run the draft against yourself or a test user to walk through the task assignments and dependencies in a real ticket queue.
* **Ask for a flow chart diagram with dependencies.** As you're building a journey, you can ask Catalyst to show you the journey as a flow chart diagram with dependencies. Catalyst will create a visual diagram you can inspect and use. Open the diagram fullscreen to zoom and pan. Diagrams display as images; embedded links and external images are inactive.
* **Use manual tasks for tasks without attached workflows.** Manual tasks have no attached workflow. The assignee completes the task on their own and finishes it by clicking **Mark complete.**
## Troubleshooting
### Why are tasks not showing up in the columns I expect?
If a task isn't in the column you'd expect, check its assignee. Journeys group tasks into columns by assignee:
* Any task assigned to the requester (for example, the new hire) shows up in the requester column.
* Any task assigned to a member of a Serval team shows up under the column for that team.
* Any task assigned to a user who isn't the requester or a member of a Serval team shows up in the stakeholder column.
### Why are certain automation tasks not automatically firing?
This normally means the workflow still requires inputs, or the workflow is set with **Use a form to collect inputs.** If you want to auto-run an attached workflow that requires inputs, tell Catalyst to auto-submit inputs with hardcoded values or variables from the journey, like the new hire's email.
### Why are some journey tasks showing up in a team column but others aren't?
A team column shows tasks that are assigned to a member of that team and hides the rest.
If a task you expected to see is missing, check its assignee.
## Related
What Catalyst can and can't do
Get familiar with the Catalyst interface
Stage changes, propose reviews, and configure approvers
Natural language prompting, manual edits, versioning
Coordinate multi-step, cross-team processes
# Catalyst overview
Source: https://docs.serval.com/sections/documentation/catalyst/overview
Serval's automation agent for building workflows, skills, dashboards, and more
**Catalyst** is an admin-facing agent that can create and edit workflows, skills, dashboards, journeys, and more. It can also analyze data, generate reports, and proactively investigate issues in your environment.
Catalyst is how you build and publish workflows and skills. Workflows themselves are unchanged: they still run on triggers, appear in run history, and integrate with the help desk.
***
## How it works
Simply start a chat with Catalyst and describe what you want to automate. When Catalyst creates or updates a workflow, skill, or dashboard, the draft appears in the resource side panel for you to review. You can view, test, and iterate on drafts end-to-end before publishing. When you're ready to use the resource you created, click **Publish** or **Propose for review**, depending on your Catalyst settings.
***
## What Catalyst can do
### Build workflows
Catalyst authors Serval workflows, the deterministic automations that power your help desk. Reset passwords, onboard new hires, sync data between systems, post to Slack on a schedule, and more. Describe the outcome and Catalyst drafts the workflow for you to review and publish.
### Author skills
Skills shape how the help desk agent behaves: tone, escalation paths, troubleshooting flows, and when to invoke specific workflows. Catalyst drafts skills from your description including both the "when to use it" and "what to do."
### Create journeys
Journeys are multi-step workflows, most often used for onboarding/offboarding, that coordinate tasks and dependencies across teams. Catalyst can build and edit journeys for you through natural language.
### Configure access management
Catalyst sets up access requests based on details like the roles employees can request, whether requests need approval, how long access lasts, and how access is provisioned. It drafts the roles, policies, and profiles for you to review and publish. For more information, see [Configuring access management](/sections/documentation/catalyst/configuring-access-management).
### Build dashboards
Catalyst can build [analytics dashboards](/sections/documentation/catalyst/dashboards) against any data from Serval, connected apps, and public APIs. Each dashboard widget is powered by a workflow that Catalyst writes for you.
### Investigate issues and send reports
Need to know which Okta groups are empty, which tickets are stuck, or what's in your knowledge base? Catalyst can run complex queries, return answers directly in chat, and email a report.
### Debug workflow runs
When inspecting any workflow run, hit "Investigate in Catalyst" to analyze what happened. This enables your team to debug failed or stalled workflow runs.
Catalyst keeps gaining new capabilities, so you may find it can do more than what's listed here.
***
## Learn more
Get familiar with the Catalyst interface
Open your first session and publish a change
Using Catalyst to analyze ServiceNow tickets and build automations
Stage changes, propose reviews, and configure approvers
Natural language prompting, manual edits, versioning
Building analytics dashboards with Catalyst
Set up roles, approvals, and provisioning with Catalyst
***
## Related topics
For roles, approval policies, and provisioning rules. Configure who has access to what resources.
How workflows run, trigger, and integrate after you build them in Catalyst
Instructions for the help desk agent on end-user requests
Builder access and team capabilities
Published versions and history for individual workflows
# Tutorial: Build automations from ticket history
Source: https://docs.serval.com/sections/documentation/catalyst/tutorial
Using Catalyst to analyze ServiceNow tickets and build automations
In this tutorial, you'll use Catalyst to mine your ServiceNow ticket history for patterns and turn the top automation candidates into working Serval workflows and skills. If you don't use ServiceNow, you can replicate this tutorial with Serval ticket history or a different ITSM such as Jira Service Management or FreshService.
Due to the probabilistic nature of LLMs, you may see different responses from what's listed below. Follow up with refined requests as needed while following these steps.
**Time required:** \~30 minutes\
**You'll need:** A Serval team with ServiceNow connected, and Manager or Builder permissions on that team.
***
## What you'll build
* A read-only investigation that pulls recent ServiceNow tickets and groups them by category.
* A Serval workflow that automates the most common request type Catalyst surfaces.
***
## Step 1: Connect ServiceNow (if you haven't already)
Open Catalyst from the side panel in Serval and ask:
*"Is ServiceNow connected to this team?"*
If it isn't, Catalyst will surface a Connect card. Click through the integration flow and return to the chat. Catalyst will pick up where you left off.
***
## Step 2: Ask Catalyst to analyze your ticket history
In the chat, describe what you want to accomplish:
*"Pull the last 90 days of ServiceNow incidents for our team. Group them by category and show me the top 10 most common request types, with counts and example tickets."*
Catalyst will:
* Draft a temporary read-only investigation that queries ServiceNow's incident table.
* Run it immediately (read-only investigations auto-approve).
* Return a summarized table directly in chat.
You'll see something like this:
| Category | Count | Example |
| :-: | :-: | :-: |
| Password reset | 187 | INC0012345 |
| New laptop request | 94 | INC0012402 |
| VPN access | 71 | INC0012498 |
| … | … | … |
***
## Step 3: Pick an automation candidate
Look at the results and pick the highest-volume request that's also the most mechanical. In this example, **password reset** at 187 tickets in 90 days is the obvious starting point.
Ask Catalyst:
*"Can you build a workflow that resets a user's password in Okta and notifies them in Slack?"*
Catalyst will:
* Check whether a password reset workflow already exists in the team
* Confirm which integrations to use (Okta for the reset, Slack for the DM)
* Draft the workflow and stage it in the resource side panel
You'll see the draft appear alongside the chat with the full TypeScript visible for review.
***
## Step 4: Test the workflow before publishing
You can run draft workflows immediately inside Catalyst before publishing. Catalyst may prompt you to do so, or you can click **Run** in the resource panel. We recommend testing the workflow against a dummy user account.
To make adjustments to the workflow, describe the update in chat and Catalyst will edit the draft.
*"Update the Slack message to include a link to our password manager at passwords.example.com."*
***
## Step 5: Publish
When the draft workflow looks right, click **Publish** in the resource panel. Publishing exposes it to:
* The help desk agent (so it can run on incoming requests from Slack, Teams, email, or web)
* External triggers (scheduled runs, events, webhooks, API calls)
Until you publish, the changes only exist inside your Catalyst session, without affecting live tickets.
***
## Tips
* **Start narrow.** "Reset password in Okta" is a better first workflow than "handle all account problems." Small, focused workflows are easier to test and reuse.
* **Let Catalyst search first.** Before building, Catalyst checks for existing workflows and the installable gallery.
* **Access provisioning isn't a workflow.** If your analysis surfaces "grant access to X" requests, configure those in **Access Management**, not as a standalone workflow. Catalyst will guide you there.
***
## What's next
* Connect more sources (Jira, Zendesk, your existing knowledge base) so Catalyst can analyze across systems.
* Use Catalyst to build an analytics dashboard tracking how often each new workflow runs and how many tickets it deflects.
* Set up a background agent to re-run the analysis monthly and surface new automation candidates as your ticket mix shifts.
***
## Related links
What Catalyst can do
Get familiar with the Catalyst interface
Open your first session and publish a change
Stage changes, propose reviews, and configure approvers
Natural language prompting, manual edits, versioning
Building analytics dashboards with Catalyst
# Data flow diagrams
Source: https://docs.serval.com/sections/documentation/data-flow-diagrams
## End-to-end flows between Serval and Customer applications
The diagram below highlights system boundaries, data transmission paths, and key security controls within Serval. Hover over a component to isolate its flows, or over a line to trace it.
Customer applications are provided as examples only — Serval can be connected with as many or as few external applications as needed.
View full screen ↗
## Hybrid self-hosted deployments
In a [Hybrid Self-Hosted](/sections/self-hosting/hybrid) deployment the Credential Proxy runs alongside the Serval worker inside your own infrastructure. Integration credentials are stored encrypted in Serval Cloud by default; the proxy fetches them at call time, injects them into the outgoing request, and sends that request to the target service from inside your network. Workflow code never sees them. A connection configured with [worker-local credentials](/sections/self-hosting/deployment/worker-local-integrations) instead reads its credential from a Kubernetes Secret in your cluster, and Serval Cloud holds only a placeholder. The worker opens an outbound HTTPS connection to Serval Cloud; the workflow engine sends it signed integration requests and the result flows back. Everything else — the web app, the workflow engine, inbound webhooks, and application storage — stays in Serval Cloud.
View full screen ↗
# Administration
Source: https://docs.serval.com/sections/documentation/databases/administration
Permissions, change history and provenance, and safe deletion
## Permissions
Access to items follows two layers: the team role of the user, and the Help Desk Agent visibility of each item type.
### Team roles
Every team role grants a specific level of access to item data:
| Role | Can do |
| :- | :- |
| **Viewer** | Read items and their history. No edits. |
| **Agent** | Read items relevant to assigned tickets (resolves to requester-associated items by default). |
| **Contributor** | Read item field values. Can't edit field values or change the schema. |
| **Builder** | Everything Contributor does, plus create, edit, archive, and delete items and item types. Can configure ingestions. |
| **Manager** | Everything above, plus share item schemas to other teams. |
See [Team roles and permissions](/sections/documentation/platform/permissions) for the full matrix across all platform resources.
### Help Desk Agent visibility
Team-role access doesn't automatically grant access to the Help Desk Agent. Each item type has its own visibility setting that decides what the agent can read at runtime:
| Setting | What the agent sees |
| :- | :- |
| **None** | Nothing. The agent can't query this type. |
| **Requester associated** (default) | Only items linked to the requester. |
| **Always** | Every item of this type. |
Set **None** for sensitive types (compensation, security audit logs) that should never reach the agent, even if a Builder has otherwise granted broad access. Set **Always** for catalog and reference data the agent might need across requests.
### Table and field access
A table or field can narrow the audience it gets from the database above it, but never widen it. Open a table's access from the access badge in its header (**Everyone**, **Write restricted**, or **Restricted**), or a field's access from **Edit field permissions** in the field's actions menu.
When the database is shared with specific teams rather than the entire organization, select **Add teams, roles, or people** to limit the table or field to a role, group, or person. These rows show **Only if they also have access above**: they reach the table only if the database already gives them access. For example, to let only the Security Lead role inside Corporate IT see and edit a table:
1. Open the table's access.
2. Select **Add teams, roles, or people** and pick the **Security Lead** role.
3. Set the role to **Can write**.
4. Set **Corporate IT** to **No access**.
Members of Corporate IT who hold Security Lead can read and edit the table. The rest of Corporate IT can't see it. A role, group, or person added this way can only get **Can write** if someone above them already has write access.
### Record-level access rules
Beyond the type-wide audience, a manager can restrict a single record. Open the record and select the **lock** icon in its header to narrow who can read or write that row below the item type's audience. People without access see the record as a **Restricted record** placeholder with a lock instead of its field values, and its detail page explains that a manager of the database can grant access. Filtered lists note when restricted records can't be included in the results.
### Editing items from workflows
Workflows run with the permissions of their owning team. A workflow exposed to the Help Desk effectively gives end users access to whatever it touches.
A workflow can read and write any item in its team regardless of the calling user's role. Audit any workflow that writes to a sensitive item type before publishing.
## History and provenance
When a field value changes, Serval records the change in field value history. Each change creates a new history entry; the prior value is kept as a deleted row.
History captures:
* **What changed.** The field, the new value, and (by comparing earlier entries for the same field) the previous value.
* **Who changed it.** A user (manual edits via UI or API), or an ingestion source (shown as the connected app instance). Workflow runs aren't recorded on individual field history entries.
* **When.** Timestamp of the write.
Unchanged rewrites don't create new history entries. History is per field, retained indefinitely, and queryable in the item activity tab and via the API (`ListEntityFieldValueHistory`).
### Reading history in the UI
Open any item and click **Field History** in the side panel. Each row is one change to one field. Filter by field to trace a single value's lineage, or by author to see what a workflow has been writing.
### Reading history from workflows
You can build workflows to read field history programmatically. The common use cases:
* **Alert on field change.** A scheduled workflow reads recent history for an item and notifies users when it changes.
* **Debug a stale value.** Walk back through history to see which source last wrote the field and when. Useful when a sync isn't refreshing what you expected.
* **Provenance reports.** List every value on a sensitive field along with its source, for compliance audits.
### Provenance and source of truth
Each value carries the identity of whoever wrote it. For fields with multiple ingestion mappings, history shows which source won at each write. This is the audit-grade answer to "where did this number come from?" for finance and compliance teams.
## Archiving and deletion
Removing an item has two lifecycles: **archive** (reversible) and **delete** (permanent).
**Archive** hides an item from the default list and per-type counts while keeping it intact: it stays loadable by ID or key, still resolves when referenced, and keeps its key reserved. Use the **Show archived** toggle on the list to see archived items and **Unarchive** to restore one. In references, an archived item shows muted and labeled **(archived)**; a deleted item shows struck through and labeled **(deleted)**.
**Delete** removes an item permanently: there's no restore, and its key is freed for reuse (change history is still retained for audit). Prefer archive when you might need the item back. If the item is fed by an ingestion config, disable the source mapping or change the source data, or the next sync recreates it.
### Delete items in bulk
To remove every item matching a filter, use a workflow that searches and deletes. The list view doesn't expose bulk delete by default, to avoid accidents.
### Delete missing items vs. manual deletions
The **Delete missing items** toggle on an ingestion config controls whether deletions at the source cause Serval to delete the corresponding item. Hand-deleting an item is independent of this: it removes the item from Serval, regardless of whether the source still has it. See [Ingestion](/sections/documentation/databases/ingestion#deletions).
### Delete an item type
Deleting an item type also deletes all of its child types. The items themselves aren't permanently removed. Instead, they stay hidden from queries, but are kept for audit. You can't recover a deleted item type through the API.
Before deleting an item type, check for:
* Any workflow that reads or writes it. The workflow will fail on its next run.
* Any skill that references it. The agent will fail to resolve the reference.
* Any custom ticket field or catalog item that uses it as the reference target.
* Any other item type with reference fields pointing at it.
See [Schema design](/sections/documentation/databases/schema-design#deleting-an-item-type).
### Delete a field
Removes the field from the type and by default from every descendant that inherits it.
## What's next
The full role matrix across all platform resources.
Configure what the Help Desk Agent can read.
Add, evolve, and delete item types and fields.
How deletions propagate from external sources.
# Browsing and querying
Source: https://docs.serval.com/sections/documentation/databases/browsing-and-querying
List view, filters, saved views, and the context graph
The list view shows every item of a type in a sortable, filterable grid. The context graph visualizes the relationships between items and lets you traverse them. Most day-to-day work happens in the list view. The context graph comes out when you need to understand impact, ownership, or dependencies.
## The list view
Open any item type in the Databases tab to see its list view. By default, the columns are the key field, the name field, and a handful of others Serval picks based on the type.
In the list view, you can:
* Click **Columns** to pick which fields show
* Filter on any column
* Click on a column to sort ascending or descending
* Search in the search box
* Move between pages (500 items per page by default)
* Save and share views
* Set a default view
## The context graph
Click any item on its detail view to see its context graph.
The context graph visualizes the item reference fields you set up in [Schema design](/sections/documentation/databases/schema-design#item-reference-field) as a navigable network. Every item is a node. Every reference field, and every relationship type, is a directional edge.
### A person's items
A user's profile has an **Items** tab that works like a database dashboard scoped to that person. The **Tables** pane on the left lists every table whose items reference the user through a user reference field, grouped by database, with the field name and the number of items under each table.
* **Graph**: the first row opens the user's context graph across every table. A table with more than a handful of references collapses into a footer such as **54 Accounts**; click it to browse those items. The legend starts with items only, and you can switch on groups, teams, tickets, and other neighbors.
* **A table**: pick a table to see its items in the familiar table view, pinned to the user with a read-only filter chip such as **Account Manager is Aashna Panchal**. Add filters, search, and show archived items as usual. **Open in \[database]** takes you to the table in its database with the same filter applied.
When you view someone else's profile, the tab only shows items in teams you belong to.
### What the Help Desk Agent sees
The Help Desk Agent traverses the same graph when it resolves tickets. If a user opens a ticket about "my laptop," the agent walks from the user's item to their assigned computer, then to that computer's recent incidents, hardware specs, and assigned software. Configure which item types the agent can see in [Administration](/sections/documentation/databases/administration).
### Workflows on the graph
Workflows can traverse the same relationships from code. The typical pattern: a server goes down, a workflow reads the graph to find every service that depends on it, then fans out remediation or notifications to the owners of each.
# Ingestion
Source: https://docs.serval.com/sections/documentation/databases/ingestion
Pull data from any connected app into an item type, with AI-suggested field mappings
An ingestion pulls data from a connected app on a schedule and writes it into an item type. You point it at an app, pick or describe the ingestion workflow, accept or adjust the AI-suggested field mappings, and Serval handles the rest: deduplication against the key field, delta detection, and deletion reconciliation.
One item type can be populated by many sources. "Computer" can pull hardware specs from your MDM and financial data from your procurement tool simultaneously, with mapping priority deciding which source owns which field.
## Connect a source
Before you connect a source:
* Create the item type (see [Schema design](/sections/documentation/databases/schema-design))
* Connect to the source app (see [Connect an application](/sections/integrations/application))
Once the item type exists and the source app is connected at the team level, follow these steps:
1. Open the item type in **Databases**.
2. Click **Configure Ingestion**.
3. Select your source app.
4. Pick or build the ingestion workflow (**Installable ingestion**, **Natural language**, or **Custom code**). See below for details
5. Run the first sync. Serval extracts a sample of raw external records.
6. Review the AI-suggested field mappings. Accept, adjust, or add to them.
7. Save. Subsequent syncs run on the schedule you set.
## Three ways to build the ingestion workflow
* **Installable ingestion:** Use when an off-the-shelf workflow for your source exists in Serval's gallery (Jamf, Iru, Okta, ServiceNow, Workday, AWS, and others).
* **Natural language:** Use when no installable exists, but the source has a documented API. Describe what you want to ingest ("Ingest all cards from Ramp." "Pull all active employees from BambooHR.") and [Catalyst](/sections/documentation/catalyst/overview) generates the ingestion workflow.
* **Custom code:** Use when you want full control: complex pagination, custom auth, conditional logic, or a source that needs special handling.
### Installable ingestions
Browse the installable gallery filtered by your connected apps. Each entry lists the source, what it pulls, and the expected fields. Install with one click and skip to mapping review.
### Natural-language ingestions
Describe what you want to ingest in plain English. Be specific about the source, the resource, and any filters:
* "Pull all active users from Okta, including their group memberships."
* "Ingest all open expenses from Brex in the last 90 days."
* "Pull every device from Intune, only Windows machines."
Catalyst asks follow-up questions if it needs them (which scopes, which fields, pagination strategy), generates a draft workflow, and lets you publish once it looks right.
### Custom-code ingestions
Write the workflow yourself when the source needs handling the natural-language builder can't infer: cursor-based pagination with state, multi-step ingestion (list IDs, then fetch each), conditional filtering, or auth beyond what the integration template handles.
## Review the AI-suggested mapping
After the first sync brings back a sample of raw external records, Serval analyzes them and proposes mappings between external field paths and internal fields on your item type.
The review screen shows each suggestion alongside a sample value:
| Internal field | External field path | Sample value |
| :- | :- | :- |
| Serial Number | `general.serialNumber` | `C02XL0KNJG5H` |
| Hostname | `general.name` | `joes-macbook` |
| OS Version | `general.osVersion` | `14.5.0` |
| Owner | `general.userAndLocation.email` | `joe@acme.com` |
| Cost | *no suggestion* | *no match in source* |
For each row you can:
* **Accept** the suggestion as-is.
* **Adjust** the external field path. Pick a different field from the raw record.
* **Add a mapping** for an internal field the AI didn't catch.
* **Skip** an internal field that doesn't have a matching source field.
Mapping changes apply to items you've already ingested right away — Serval re-reads the data it already stored for them, so you don't need to wait for a sync or run one. You can come back and refine anytime.
## Fields likely to require intervention
Keep an eye on the following situations, as they may require adjusting or overriding AI suggestions.
* **Ambiguous source fields**. A source field named `serial` mapped to Serial Number is usually correct. A source field named `id` mapped to Serial Number probably isn't.
* **Computed fields.** If your item type has a derived field (Total Cost = Unit Cost \* Quantity), the AI can't compute it. Map only what the source provides, and build derived fields with a workflow that runs after sync.
* **User references.** Serval will look for fields that look like an email address, but the email must match an existing Serval user. When ingesting user reference, be sure that the source uses the same email domain.
## Multiple sources for one item type
An item type can have any number of ingestion workflows, each writing different fields from a different source. This is the canonical CMDB and ITAM setup: hardware specs from your MDM, financial data from procurement, ownership and employment data from your HRIS, all written into one Computer item type.
Every item is deduplicated by its key field. Each source contributes the fields it maps.
### Picking the source of truth per field
When two sources both map to the same internal field, you can order them by **priority** to decide which source is more authoritative. The lower priority source still feeds the field if the higher priority source doesn't have a value.
A common pattern for a "Computer" item type:
| Internal field | Source of truth | Why |
| :- | :- | :- |
| Serial Number | MDM | Authoritative for hardware identity |
| OS Version | MDM | Updates in near real time |
| Hostname | MDM | Reflects what's actually deployed |
| Owner | HRIS | HRIS knows employment changes first |
| Cost | Procurement | Procurement has the invoice |
| Status | Workflow output | A workflow sets status on its own |
## Sync schedules and deletions
### Schedule
Each ingestion runs on its own interval. Set **sync frequency** explicitly, or leave it on **Default (4 hours)**. Manual sync is always available via the **Sync now** button on the ingestion config.
### Deletions
The **Delete missing items** toggle controls whether Serval propagates deletions from the source:
* **On:** When a record disappears from the source, the corresponding item in Serval is deleted.
* **Off (default):** Disappeared records are left in place. Use this when you want to retain history of devices that left the fleet, or when the source has known cases of records flickering in and out.
Serval checks for missing records after a workflow returns a complete inventory and all pages finish successfully, including on repeat syncs. Each page must identify itself as part of the full inventory. If Serval cannot confirm this for the whole sync, it skips missing-record cleanup. Incremental (delta) results must explicitly identify deleted records. An item remains if another ingestion source still supplies it.
## Troubleshooting
### Reading sync status
Each ingestion shows its last sync time, current phase, and whether the most recent run succeeded. The sync history lists every sync with start and end time, records added, updated, or deleted, and any failure details. A run that stored records but published none reads `Ingested, not published`: the source has no field mappings yet. For what each status and failure cause means, and for the records a sync couldn't publish, see [Issues](/sections/documentation/databases/issues).
### Sync failed
A failed sync could stem from a number of reasons:
* **Workflow error:** Auth expired, source API returned 5xx, pagination broke, etc. Open the failed run and investigate with Catalyst.
* **Field mapping error:** An external field path no longer exists in the source, or a value doesn't match the internal field's type (e.g. string where number expected). Fix the mapping, then re-sync.
* **Schema drift:** The item type schema changed in a way that breaks the workflow. Update the schema to match what the workflow submits, or update the workflow to match the current schema. See [Schema changes](/sections/documentation/databases/schema-design#schema-changes).
### Sync runs forever
Long-running syncs usually mean pagination is broken. The best troubleshooting step is to investigate the failed workflow run with Catalyst.
### Items disappearing
If items are getting deleted unexpectedly:
1. Verify the **Delete missing items** toggle matches your intent.
2. Ask Catalyst to investigate the ingestion workflow and why items are disappearing
3. Cross-check the source. Is the record actually gone, or is the source paginating differently than the workflow expects?
### Mapping suggestions look wrong
Re-run the first sync after the source has more representative data. The AI builds suggestions from a sample; with a few records of low diversity, suggestions may not be accurate.
## What's next
Get the item type and key field right before connecting sources.
Filter, sort, and traverse the context graph.
Read items from workflow code. Surface them to the Help Desk Agent.
Provenance shows which source wrote which value, and when.
Every record a sync couldn't publish, grouped by cause.
## Workflows that run after ingested changes
A workflow rule that runs after saving also runs from ingested and CSV-imported changes: one run per changed item, and none for items the sync left unchanged. Publication never waits for these workflows and never fails because of them; a failed run does not undo the published item. Runs beyond the hourly limits are held. Held and failed runs appear on the item type's **Issues** tab, where you can replay them.
# Issues
Source: https://docs.serval.com/sections/documentation/databases/issues
See what failed to reach a database, which records it affected, and what to change
An issue is one root cause on one item type. When the same problem stops twenty records from publishing, you get one issue that says it affects twenty records, not twenty near-identical rows to read through.
Open an item type in **Databases** and go to the **Issues** tab. The tab itself carries a count of the records still affected, so you can see there's something to fix without opening it.
## What the list shows
Each row is one issue:
* **Status**: `Open` while anything is still failing, `Resolved` once everything it held up has gone through.
* **Issue**: the category, a short title, and a sentence naming the field and value behind it.
* **Affected**: how many records are still affected. Ingestion and workflow issues count runs, schema issues count changes, and a resolved issue reads `None open`.
* **First seen** and **Last seen**: when Serval first hit this cause, and the most recent time it hit it again.
Above the list, a summary counts the whole page: `12 affected records across 3 issues`. A trailing `+` means more issues are still to load.
### Categories
| Category | What it means |
| :- | :- |
| Validation | A validation rule rejected the records. |
| Publishing | A record couldn't be published for a reason other than a rule: a missing key, an unresolved relationship, or a value another record already holds. |
| Ingestion | A sync run, or one of its pages, failed. |
| Schema | A schema change failed, or left records to fix. |
| Workflow | A workflow that runs after a saved change was held, failed, or expired. |
### Filters
* **Category**: narrow to one of the categories above.
* **Source**: only issues from one ingestion source.
* **Rule**: only issues from one validation rule.
* **Time range**: how far back to look, by the last time each issue was seen.
* **Include resolved**: add issues that nothing is failing on any more.
## What an issue tells you
Select a row to open it. The drawer names the item type, when the issue was first and last seen, and how many records are open out of everything it has ever affected.
**Message** says what went wrong in plain terms, with the field, the value from the source row, and the record involved resolved to their names. Alongside it are the one or two places worth going next: the ingestion sources for a relationship that matched nothing, the source rows for an empty key, the record that already holds a value, or the rules that rejected a record.
**Diagnostics** is collapsed and holds the raw error text, for issues that have one.
**Affected records** lists every record, run, or change under the issue, 50 at a time. Each entry links to the record where there is one, lists the source rows that fed it, names the rules it broke, and gives the times it was seen and resolved. **Load more** pages through the rest.
An issue involving fields or records you can't see reads **Details restricted**: the category, the counts, and the times stay visible, but the message and the evidence are withheld. Individual entries under **Affected records** are withheld the same way.
## Fixing an issue
Nothing here is marked done by hand. An issue resolves when the thing that failed succeeds: the next sync publishes the record, the schema change is retried and applies, the held run is replayed. Fix the cause and the issue clears on its own.
Common causes and what to change:
* **Relationship target not found**: the source value doesn't match any record in the linked table. Check that the linked table is ingested and that the field is mapped.
* **Key field is empty**: the source row has no value for the key field. Fix it at the source, or map the key to a field the source always fills.
* **A value already belongs to another record**: two records want the same unique value. Give one of them a value of its own.
* **Records rejected by validation rules**: either the data is wrong or the rule is. The issue names the rule so you can decide which.
* **Run failed**: the sync itself stopped. See [Reading sync history](#reading-sync-history) below.
## Reading sync history
Open the ingestion's **Sync History** to see each run's status and result.
| Status | What it means |
| :- | :- |
| Running | The sync is in progress. The result shows the page it's on and how many records it has handled. |
| Success | The run finished and published what it ingested. |
| Ingested, not published | The run stored records but published none, because the source has no field mappings yet. Accept or add mappings and the next sync publishes the backlog. |
| Published with failures | The run finished, but publishing rejected some of the records it ingested. |
| Publishing unconfirmed | The run finished without publishing ever reporting an outcome, so what reached the database is unknown. The next sync republishes anything still missing. |
| Cancelled | Someone stopped the run before it finished. |
| Failed | The run stopped. The result names the cause. |
A run that published only some of what it ingested says how many records publishing rejected, with a **View issues** link to the item type's issues for anyone who can open them.
### Failure causes
A failed run reports a specific cause rather than a generic error:
* **The extraction workflow failed on page N**: the ingestion workflow returned a failure. Open the run to see why.
* **The extraction workflow didn't finish page N in time**: the workflow ran past its time limit. Usually pagination pulling too much per page.
* **The extraction workflow returned a result Serval couldn't read**: the response didn't match what an ingestion workflow returns, or the run switched between a full and an incremental result mid-sync.
* **The extraction workflow isn't published**: publish it, then sync again.
* **Couldn't store the ingested data**: Serval couldn't write a page of records. Retry the sync.
* **Ingested data couldn't be published**: the records were stored but publishing them failed. The reason is on the **Issues** tab.
* **The sync stopped making progress**: the run made no headway across several attempts and stopped retrying on its own. Use **Resume** on the run to try again from where it left off.
* **A newer sync run replaced this one**: a later sync started before this one finished. Nothing to do.
### Run timeline
Expand a run to see its timeline: when it started, resumed, changed phase, or continued, and every failure along the way. Each event names the page it's about and carries its own diagnostics. Three events explain a run that looks clean but did less than you expected:
* **Rows skipped**: a page couldn't stage some of its rows, and the event counts each kind: rows with no id, duplicate ids within one page, and deletes naming rows Serval isn't currently ingesting.
* **Publishing skipped**: the run ingested records but published none, because the source has no field mappings.
* **Sync ended after stalling**: the run stopped making progress and Serval ended it.
## What's next
Most publishing issues trace back to a field mapping.
A rule that rejects good data is a rule worth changing.
# Manual data entry and bulk import
Source: https://docs.serval.com/sections/documentation/databases/manual-data-entry
Add and edit items through the UI, or bulk import from CSV
Manual entry is the right tool for items that aren't ingested: spreadsheet-sourced data with no API behind it, a quick correction to a single value, or a one-time load while you wait to wire up the ingestion. For anything ongoing, use [Ingestion](/sections/documentation/databases/ingestion).
## When to use manual entry
Use manual entry for unique, non-recurring cases that can't be synced with an API.
* **Importing from a spreadsheet:** For bulk data from a spreadsheet with no API behind it, use CSV import.
* **One-off item:** For a one-off item that isn't tracked anywhere else, add through the UI.
* **Editing:** To fix a wrong value on a single item, edit through the UI.
Don't use manual entry for recurring data from any system with an API or data you need refreshed automatically. Instead, use [Ingestion](/sections/documentation/databases/ingestion).
Any value you set manually is overwritten on the next sync unless you pin the field to keep a manual value. See [Multiple sources for one item type](/sections/documentation/databases/ingestion#multiple-sources-for-one-item-type)
## Add an item
1. Open the item type in the Databases tab.
2. Click **Add Item->Create item manually**.
3. In the **Create Item** popup, fill out the fields.
The key and name fields are required. All other fields are optional unless you're creating an edge-type relationship (which requires both endpoint fields). If you enter a key that already exists, creation fails. If you need to update by key, use edit on the existing item or update by CSV import.
## Edit field values
For an item reference field, select the item type if needed, then search for the item or scroll to load more options.
1. Click any item to open its detail view.
2. Click any field to edit inline, or click the edit (pencil) icon to edit all fields.
3. Changes write through immediately. Every edit is recorded in the item's history with author, timestamp, and the previous value. For more on item history, see [Administration](/sections/documentation/databases/administration).
### Edits and ingestion
If a field is fed by an ingestion config, a manual edit gets overwritten on the next sync that maps to that field. To make a manual edit persist:
* Pin the field when prompted, which keeps your manual value until you unpin it, or
* Remove the mapping for that field on the ingestion config, or
* Lower the ingestion mapping's priority so manual entry wins, or
* Update the value at the source instead of in Serval.
Fields that no ingestion maps to are safe to edit. Provenance in the item's history shows whether each value came from manual entry or from a specific ingestion run.
## Bulk import from CSV
Use CSV import for one-shot loads from a spreadsheet, vendor export, or migration from another system.
### CSV format
* The first row is a header row.
* Map a column to the item type's key field. This is required for a successful import.
* All other mapped columns are optional.
* Columns you don't map are ignored.
* Column order doesn't matter.
| Type | How to format the value |
| :- | :- |
| Text | Raw string |
| Number | `1234` or `1234.56`. No commas for thousand separators |
| Boolean | `true` or `false`. Also accepted: `1`/`0`, `yes`/`no`, `on`/`off`. |
| Timestamp | ISO 8601 is recommended (e.g. `2026-06-25T14:00:00Z`). Date-only values such as `2026-06-25` are also accepted. |
| Enum | The option **value** (canonical key), not the display label. Matching is case-insensitive. |
| Multi-select | One option value per cell. Pipe-separated values (e.g. `Engineering\|Security\|Finance`) aren't supported in CSV import. |
| Entity reference | The referenced entity's (item's) key value. UUID and external ID are also accepted. |
| User reference | The user's email address. UUID is also accepted. |
| File | Not supported in CSV import. Upload files through the UI. |
### Importing
1. Open the item type in **Databases**.
2. Click **Add Item->Import from CSV.**
3. Upload the file. Serval validates the header row against the item type's fields.
4. Review the preview. Serval shows how many rows will be inserted, how many will update existing items (matched by key), and any parse errors per row.
5. Confirm.
Rows with parse errors are skipped, not retried. Fix them in the source CSV and re-import.
Matching by key means re-importing a corrected row updates the right item, not a duplicate
### Key collisions and updates
Import deduplicates by the key field. A row whose key matches an existing item updates that item's fields with the values in the CSV. Fields not present in the CSV are left unchanged.
## What's next
Replace manual loads with an ingestion that keeps the data fresh.
Verify the import landed correctly and start querying.
Provenance shows whether each value came from manual entry, CSV, or a specific ingestion run.
## Workflows that run after a change
A workflow rule on the item type can run a workflow after an item is created, edited, archived, restored, or deleted, whether the change comes from the database interface or the API. Rules are configured on the item type's **Rules** tab; see [Workflow rules](/documentation/databases/schema-design#workflow-rules).
The item is saved first. The workflow then receives the item's values before and after the change and who made it. A failed run never undoes the edit, and repeating an edit without changing its values does not start another run. Runs are limited per rule and per team each hour; changes beyond the limit still save, and their runs are held.
Held, failed, and expired runs appear on the item type's **Issues** tab, where you can open the run or replay it.
# Databases overview
Source: https://docs.serval.com/sections/documentation/databases/overview
Ingest assets and configuration items from any source, and reference them in tickets, workflows, and more.
Serval uses databases to read and write data from workflows, skills, tickets, campaigns, and journeys. Each database can hold one or more tables, each of which contains one or more items. An item is a single table row with typed fields like text, dates, numbers, or references to other items.
**"Items" and "Entities" are interchangeable terms.** Both terms are used in relation to Serval databases. Item is the term used in the UI that refers to a single row in a database table. Entity is the technical term used in the workflow code, API, and field types.
## Database features
* **AI-native ingestion.** Describe a new ingestion in plain English ("ingest all computers from Iru") and Serval generates the requisite workflow. Serval also suggests how external fields map to your schema, so you review and accept instead of wiring mappings by hand.
* **Multi-source per type.** One item type can pull from many sources. Sync a computer's specs from your MDM and its financial data from your procurement tool. Pick the source of truth per field.
* **Context graph.** Relationships between items are first class, traversable, and visible. See every device downstream of a server, every license assigned to a user, the full dependency chain of a CI.
* **Connected to the rest of Serval.** Workflows read and write items. Skills surface item data to the Help Desk Agent. Campaign responses can be written to databases. See every ticket associated with an item.
* **Full provenance.** Every change to every field is recorded with author, source, and timestamp. Trace what changed and when, even as assets move between owners.
* **Custom fields on people.** The built-in Users database takes your own fields, populated from your IdP, and surfaces them on every user profile. See [User custom fields](/sections/documentation/databases/user-custom-fields).
## When to use databases
* **Single source of truth for hardware, software, and licenses.** Pull from your MDM, procurement tool, and IdP into one schema. Pick the source of truth per field. Track provenance through every transfer.
* **CMDB for change management and impact analysis.** Model CIs and their relationships as item types. The context graph traces downstream dependencies. Workflows can fire when an upstream CI changes.
* **Reference data for tickets, catalog items, or workflow state.** Any item type can back custom ticket fields, catalog reference options, journey metadata, and persistent workflow state.
## What you can do with Databases
Define item types, fields, and relationships. Evolve the schema as your needs change.
Pull data from connected apps with AI-suggested field mappings, multi-source reconciliation, and scheduled syncs.
Filter, sort, save views, and traverse the context graph.
Reference items from workflow code, surface them to the Help Desk Agent, and report on them in dashboards.
***
## Next steps
Define an item type, add fields, populate, and query end to end.
Start syncing from your MDM, IdP, or procurement tool.
# Build your first item type
Source: https://docs.serval.com/sections/documentation/databases/quickstart
Define a schema, populate it, and query the result
This guide walks you through creating an item type, populating it with a few items, browsing the result, and connecting an ongoing data source. By the end, you'll have a working table you can query from anywhere in Serval.
## Create your first item
1. **Navigate to your team in the left panel and select Databases**
2. **Create the item type**
Click "New item type" in the top right. Name it after the thing you want to track. For this example, use "Computers." For this example, skip the optional field **Parent Item Type**.
3. **Add anchor fields**
Every item type needs two anchor fields:
* A unique **key field**, used for deduplication when syncing from external sources. For this example, use "Serial Number."
* A descriptive **name field**, used as the display label. For this example, use "Hostname."
4. **Add other fields**
Add typed fields for everything else you want to track. For this example, add these:
* "OS Version" (text)
* "Cost" (number)
* "Owner" (user reference)
* "Status" (enum: Active, In Repair, Retired)
5. **Add a few items by hand**
Click **New item** and fill in the fields for two or three computers. Hand entry is fine for a quick test. Once you're ready to sync from a real source, you will set up ingestion.
6. **Browse and filter**
Open the item type's list view. Filter on any field. Sort on any field. Save the view if you'll come back to it. Filters and saved views are private unless you share the view explicitly. Try filtering by "Status = Active" and sorting by "Cost" descending to see the most expensive active machines.
7. **Connect a source**
Once the schema is settled, replace manually-created items with a live ingestion. Click **Connect a source** on the item type. Pick an app you've already connected to Serval (your MDM, IdP, or procurement tool), choose an installable extraction workflow or write one in natural language, and accept the AI-suggested field mappings. Serval handles the first sync and keeps the item type fresh on the schedule you set.
For more information on ingestion (including full setup, multi-source reconciliation, and troubleshooting), see [Ingestion](/sections/documentation/databases/ingestion).
## Tips for building an item type
### Pick a stable key
Choose a key field that's unique and unchanging. Serial numbers, asset tags, and email addresses make better keys than display names.
### Type narrowly
Use enums for fixed sets and user references for ownership. Use text fields as a fallback, not a default.
### Settle the schema before ingesting
Changing field types after ingestion is supported but triggers a schema migration. Take time to think through your schema before you begin ingestion.
## What's next
Model relationships, evolve fields safely, and use reference-data schemas for lookup tables.
Feed one item type from multiple apps and pick the source of truth per field.
Read and write items from workflow code. Surface item data to the Help Desk Agent.
# Schema design
Source: https://docs.serval.com/sections/documentation/databases/schema-design
Define item types, fields, relationships, and how to evolve them over time
Every database in Serval is a typed schema: a set of item types, each with named fields. Workflows, skills, ticket fields, and Help Desk Agents all read from this schema. It needs to stay stable enough to query reliably, and flexible enough to evolve as your business changes. This page covers how to model item types, choose field types, model relationships, and change the schema after data is in place.
## Item types
An item type is the schema for one kind of thing you track, such as computers, software licenses, services, or cost centers. Each instance of the type is a single item.
In other database architectures, an item type would correspond to a table, and each item would correspond to a row.
### Creating an item type
1. In a database, use the **New table** button to create a new item type. (Its chevron menu also offers **New relationship** — see [Relationship (edge) types](#relationship-edge-types).)
2. Enter a name for the item type.
3. Optionally choose a **parent item type.** Use a parent when several related types share a base set of fields. For instance, setting "Asset" as the parent of "Computer", "Phone", and "Monitor" means you can query "all assets" without joining three tables, while each child still carries its own type-specific fields.
4. Add additional fields as needed
### Parent-child hierarchy
Child types inherit every field from their parent type. For instance, add a field to "Asset" and it appears on "Computer", "Phone" and "Monitor" automatically. Child types can add their own fields as well.
Multiple levels of nesting are supported, but deep hierarchies can make schema changes difficult to understand. One or two levels of inheritance should handle most real-world models.
## Fields
Fields are typed columns on an item type. The available field types:
| Field type | What it stores |
| :- | :- |
| Text | Single-line string |
| Number | Integer or decimal |
| Boolean | True or false |
| Timestamp | ISO 8601 timestamp |
| Enum | One value from a fixed list of options |
| Multi-select | Zero or more values from a fixed list |
| Item reference | Pointer to another item, typed by entity type |
| User reference | Pointer to a Serval user |
| Unique | String guaranteed unique across the entity type |
| File | Attached file, one per record |
### File fields in workflow emails
A file field's value is the file's id. A workflow that reads the record can embed an image stored in that field inline in an email sent with `serval.common.sendEmailToUser`, so a header or footer banner travels inside the message instead of loading from a link:
```typescript theme={null}
await serval.common.sendEmailToUser({
recipientEmail: person.email,
subject: "Your laptop is ready",
body: `
Pick it up at the front desk.
`,
inlineImages: [{ contentId: "banner", entityFileId: brand.header_banner }],
});
```
Each `inlineImages` entry pairs a `contentId`, the token the HTML body references as `cid:`, with the file id from a record in the sending team's database. The file must be a PNG, JPEG, or GIF of 2 MB or less, and the workflow's team must be able to read the record that holds it. Files on sensitive fields can't be embedded.
### The key field
Every item type designates one field as the key field. The key is what Serval uses to deduplicate when syncing from external sources. If a sync sees the same key twice, it updates the existing item instead of creating a duplicate.
Primary-key lookups with `serval.common.getEntity` or the search API's `key` parameter use the same normalization as key uniqueness: `CAM-000004`, `cam-000004`, and `CAM 000004` identify the same item. The stored field value keeps its original casing. Filtering directly on a field still uses the selected filter operator's comparison rules.
Pick a stable and unique identifier from the source system. For example:
* **Computer:** serial number, MDM device ID, or asset tag
* **User:** email address or IdP user ID
* **Software License:** license key
* **Service:** service code or CMDB `sys_id`
Display labels (hostname, employee name, product name) aren't stable keys. People rename things; serial numbers don't change.
### The name field
The name field is the display label shown in the list view, ticket attachments, workflow output, and the context graph. Pick whatever a human would call the item: hostname for computers, full name for users, "Adobe Creative Cloud, Marketing seat" for licenses.
### Item reference field
Two item types can be linked with an item reference field. A computer can carry an "owner" field pointing at a user. A service can have a "depends\_on" field pointing at other services. An incident can have an "affected\_asset" field pointing at a computer.
An item reference declares which item types it accepts: a single type, several types (an "affected item" field might allow both computers and software licenses), or **Any item type** to leave it open. When more than one type is allowed, picking a value starts with choosing one of the allowed types.
Item references are first-class: queries traverse them, and the [context graph](/sections/documentation/databases/browsing-and-querying#the-context-graph) visualizes the result.
## Validation rules
Rules are available only when validation rule management is enabled for your team. You also need permission to manage rules. Workflow rules additionally require workflow rules to be enabled for your team and permission to manage workflow rules.
Validation rules reject item changes that do not meet your requirements. A rule can combine required values, text patterns, number limits, field comparisons, and conditions about field changes. Teams with workflow rules can also create rules that run a workflow after an item changes; see [Workflow rules](#workflow-rules).
1. Open the item type's **Rules** tab.
2. Select **Create rule**.
3. Enter a **Rule name**.
4. Under **Check on**, select **Creating**, **Updating**, or **Unarchiving**.
5. To limit when the rule applies, select **Only apply when** and add conditions.
6. If your team has workflow rules, keep **Require values** selected under **Then**.
7. Under **Require**, add the conditions that the item must meet.
8. Enter the **Error message** that people see when the rule rejects a change.
9. Select **Create rule** to save it.
Both condition sections support **Add condition** and **Add group**. Conditions in a group are joined with **AND** or **OR**. Select the connector between two conditions to change it for the whole group. Groups can contain one additional level of groups.
**Only apply when** controls whether the rule runs. If these conditions are false, Serval skips the rule. Otherwise, the conditions under **Require** must pass.
For example, a rule can apply only when Status is Active. Its requirements can combine Email **is not empty**, Email **matches regex**, and Seats **is between** 1 and 100.
An empty field fails every value condition except **is empty**. **is between**, **is at least**, and **is at most** include their boundary values.
Regular expressions use Go (RE2) syntax. The anchors `^` and `$` restrict a pattern to the entire value.
Each condition picks a field and then a condition from three sections. **Value** checks the field's value. **Another field** compares the field with another field of the same type. **Change** supports changed, did not change, changed from one value to another, and increased or decreased for numbers and dates. **Change** conditions are available only when **Updating** is the only selected operation.
Rules do not scan existing items when you save them. On subsequent selected operations, applicable rules evaluate all their requirements, including fields that did not change. Schema requirements, such as the key field, still apply independently.
### Workflow rules
When workflow rules are enabled for your team, the **Rules** tab lists validation rules and workflow rules together. The **Then** column shows what each rule does: **Require** for validation rules and **Run** a workflow for workflow rules.
To create a workflow rule, follow the steps above and, under **Then**, choose **Run a workflow after saving**. Workflow rules can also check on **Archiving** and **Deleting**.
* **Workflow** lists the team's deployed workflows. **Build the workflow in Catalyst**, next to it, opens Catalyst with a prompt that already names the table, the rule, and what the workflow receives; describe what should happen and it drafts the workflow. Publish the workflow, then choose it here.
* **Version** defaults to **Deployed version**, which runs whichever version is deployed when a change is saved. Pin a version to keep running it after a new deployment.
The item is saved first; the workflow runs with the values from that change and never blocks or undoes it. Held and failed runs appear under **Issues** below the rules, where you can open the run or replay it.
The rule type can't change after the rule is created.
### Normalization rules
A normalization rule maps the values people and syncs type into a text field onto a link or choice field on the same item type. For example, a rule can read a Manufacturer (raw) text field and set a Manufacturer item reference, so that `Microsoft Corp.`, `microsoft corp`, and `Corp, Microsoft` all link to the same Microsoft item.
1. Open the item type's **Rules** tab.
2. Select **Create rule**, then **Normalization**.
3. Under **Raw value**, select the text field to read.
4. Under **Maps to**, select the item reference or choice field to set.
5. Optionally, under **Save version to**, select a text field to receive version numbers.
6. Keep **Run on existing records** selected to normalize items that already have a raw value.
7. Select **Create rule**.
The rule runs whenever an item is created, updated, or synced, before validation rules. It matches a value when it is the same as the name of an item or option in the output field, or as an alias, ignoring case, punctuation, accents, and word order. When **Save version to** is set, a version number such as `2.4.1` or `v10.2` is moved from the raw value to that field first, so every version maps to the same item. A plain number such as `2013` stays part of the name.
A value with no match leaves the output field empty, and appears on the rule's **Pending values** tab and as an **Unmatched value** issue. Map a pending value to an existing item or option, create a new one, or ignore it. Where Serval finds a likely match, it suggests it. Mapping a value adds an alias and updates every item that has that value. The **Aliases** tab lists the aliases, and you can import aliases from a CSV file with `raw` and `canonical_name` columns.
A rule doesn't overwrite an output value that someone set directly. Disabling a rule stops it from mapping new values. Deleting a rule keeps the values it already set. The output field can't change after the rule is created; to map to a different field, delete the rule and create another one.
## Relationship (edge) types
When a relationship is many-to-many and carries information of its own (such as a software license assigned to a user with a start date, a seat ID, and an approver), an item reference field on one side isn't enough. Create a **relationship (edge) type**: a type that exists to connect two others.
An edge type has exactly two single-valued item reference fields, one for each endpoint. You name both directions when you create the relationship type. The field names become the direction labels in the context graph.
### Creating a relationship type
Relationship types have their own creation flow, separate from item types:
Open the **New table** button's chevron menu and choose **New relationship**.
Enter a name for the relationship type, such as **Software access**.
Choose the **Source item type** and **Target item type**, such as **Employees** and **Software**. Leave either unset to allow any type on that end.
Enter the two **Label** values. These name the relationship's reference columns; they aren't columns you select from either existing table. A live preview shows how the relationship reads in each direction.
Use **Add Field** to store information about the connection, such as grant date or access expiration date.
Click **Create relationship type**.
Populate the relationship using an ingestion workflow, or manually link existing items by opening an item and selecting **Related → Link**. If ingestion can't find a linked item, see [Relationship target not found](/sections/documentation/databases/issues#fixing-an-issue).
The source and target item types are fixed once the relationship type is created. In its settings you can rename the direction labels (the underlying field keys stay locked), but you can't change or delete the endpoint types.
Use an edge type when:
* The relationship is many-to-many
* The relationship carries fields of its own (dates, seat IDs, justifications, costs)
* You want both endpoints queryable by relationship
For one-to-many relationships with no extra fields, a plain item reference on the "many" side is simpler.
## Reference data schemas
Reference data schemas hold lookup values used by other item types: department codes, cost centers, region IDs, and ServiceNow reference rows. They're queryable like any other item but don't show up in asset-style browse experiences.
Use a reference data schema when:
* The data is a lookup, not a primary asset
* You expect to reference it from other item types via an item reference field
* You don't want it cluttering the main asset list
## Schema changes
Serval supports adding, renaming, retyping, and deleting fields after data is in place. Most changes run as asynchronous schema migrations; you can poll the migration to track completion.
### Adding a field
Adding a field is the safe operation. Existing items start with the field unset. New and updated items populate it. No data conversion runs.
### Renaming a field
Renaming a field updates the display name and regenerates the field key from the new name. Workflow code that references the old key needs to be updated. Existing field values are untouched.
### Changing a field's data type
You can retype a field after the fact. The migration runs asynchronously and converts existing values where possible. Most type changes are attempted value-by-value and fail the migration on the first unconvertible value.
Common conversions and how they behave:
| From | To | Conversion |
| :- | :- | :- |
| Text | Number | Parsed; rows that don't parse fail the migration |
| Text | Timestamp | ISO 8601 strings convert; other formats fail |
| Text | Enum | Existing values must already match a defined option |
| Enum | Multi-select | Each single value becomes a one-element list |
| Number | Text | Always succeeds |
The following conversions are always blocked:
| From | To | Conversion |
| :- | :- | :- |
| File | (Can't convert) | Always fails |
| Item references to edge endpoints | (Can't convert) | Always fails |
| Key fields | (Can't convert) | Always fails |
| Item reference | Unique | Refused; add a new Unique field instead |
A conversion to **Unique** fails validation when two or more items already share a value on that field. Values are compared the same way as key lookups, so `CAM-000004`, `cam-000004`, and `CAM 000004` count as the same value. The error reports how many values are shared. Make those values distinct, then retry.
If conversion fails for any row, the migration fails and the field stays at the old type. Fix the offending rows first, then retry.
Converting to **Unique** is the exception: two items can hold the same text, but only one can hold it once the field is unique. The migration completes, the first item to be converted keeps the value, and every later item that wanted the same value is left with the field empty. Each one is listed on the item type's **Issues** tab as "Value already used by another record", with a link to the item. Give those items a value of their own and the issue clears. Values match the same way keys do, so `CAM-000004`, `cam-000004`, and `CAM 000004` count as the same value.
Saved views that filter on the field drop that filter, because its value was typed to the old type. If an audit plan's scope filters on the field, the retype is refused until you edit the plan.
A retype is one change per request. To rename **and** retype a field, run two migrations back to back.
### Deleting a field
Deleting a field removes it from the item type and, by default, from every descendant type that inherits it. Saved views drop any filter, sort, or column on the field. If an audit plan's scope filters on the field, the deletion is refused until you edit the plan.
Deletion is destructive. Field values for the deleted field aren't recoverable through the API.
## Deleting an item type
Deleting an item type also deletes all of its child types. The items themselves aren't permanently removed. Instead, they stay hidden from queries, but are kept for audit.
Confirm the impact before deleting. There's no API recovery once you delete. Any workflow, skill, or ticket field that references the type will fail to resolve.
## What's next
Connect an external source and let AI-suggested mappings handle the wiring.
Add or import items through the UI and bulk CSV.
Read and write items from workflow code. Surface them to the Help Desk Agent.
Control who can view and edit items, and trace every field change.
# User custom fields
Source: https://docs.serval.com/sections/documentation/databases/user-custom-fields
Define org-wide custom attributes on people, populated from your IdP and surfaced on every user profile
Every organization gets a built-in **Users** database, holding one row per person in Serval. Turning on user custom fields lets you add your own typed fields to it: cost center, employee type, badge ID, start date, or anything else your IdP knows about people that Serval doesn't model natively.
Once defined, those fields appear as **Custom attributes** on each person's profile, and become available as criteria in access profiles, routing rules, SLA attachment, queue filters, and ticket list filters.
**"User custom fields" and "custom attributes" are the same thing.** User custom fields is the capability you turn on and the schema you define. Custom attributes is the section those fields render in on a person's profile.
## Turn on the capability
The toggle is in a team's **Settings → Capabilities**.
1. Enable **Databases** first. Custom fields are defined on the Users database, so the User custom fields toggle stays locked until Databases is on.
2. Enable **User custom fields**.
On enable, Serval creates the organization's Users schema and immediately kicks a sync sweep, so values populate right away instead of waiting for the next scheduled user sync.
**The setting is org-wide, even though it lives in a team's settings.** The team that turns it on becomes the owner and ingests users for the whole organization. Every other team's toggle locks with a note naming the owner. To hand ownership to a different team, turn it off on the owning team first.
**Choose IT as the owner in most cases.** The owning team is the one whose connected apps populate these fields, and IT typically administers the identity and directory apps that carry the attributes you want: Okta, Google Workspace, Slack, and similar. Putting ownership anywhere else means the team that manages those app connections isn't the team that owns the schema they feed.
The dependency also runs backwards. While user custom fields are on, that team's Databases toggle stays locked, so turn custom fields off before disabling Databases.
## Define the fields
The Users table appears in the owning team's Databases alongside your other tables. Add fields to it exactly as you would any other item type, and every field type is available. See [Schema design](/sections/documentation/databases/schema-design#fields) for the field types and for how renames, retypes, and deletions behave.
The Users table's key field holds Serval's internal user ID rather than a user-facing attribute, so it's excluded everywhere fields are listed or picked.
The Users table behaves differently from a table you create:
* There's no **Add item** button. Rows are created by user ingestion, or on the first manual save against a person who doesn't have one yet.
* It can't be deleted.
* User search backs the browse experience rather than the standard item list, so the archived-items toggle doesn't apply.
## Populate the fields
### From a connected app
Values come from your connected IdP's user payloads. Map them on the Users table's **Sources** tab, using the same multi-source mapping UI as any other database. Several sources can contribute to the same table, and you pick the source of truth per field. See [Ingestion](/sections/documentation/databases/ingestion).
### By hand on a profile
Open a person's profile, go to the **Attributes** tab, and click any value under **Custom attributes** to edit it in place. Values you can edit show a pencil next to them.
### Pinning
A manual edit pins the value by default, which stops ingestion from overwriting it. Unpin it to let connected apps update the field again, or pin an unpinned value to freeze what's currently there.
Every write is recorded. Expand a row to see its history: previous values, whether each was pinned, the user or connected app that set it, and when.
## Where user custom fields can be used
| Surface | Available fields |
| :- | :- |
| Access profile membership criteria | Text, Unique, Enum, Multi-select |
| Routing rule requester conditions | Text, Unique, Enum, Multi-select |
| SLA attachment criteria | Text, Unique, Enum, Multi-select |
| Queue filters | All field types |
| Ticket list filters | All field types |
The split isn't arbitrary. Access profiles, routing rules, and SLA criteria match on value labels, so they only offer the types that can produce a populated value picker. Offering the others would let you build a rule that matches nobody. Queue and ticket filters use typed predicates instead, so they can express Number, Boolean, Timestamp, and User reference comparisons too.
Surfaces that author criteria against these fields hide the option entirely until the org has opted in and defined at least one usable field.
## Permissions
| Action | Required permission |
| :- | :- |
| Turn the capability on or off | Update settings, on that team |
| View custom attributes | View items, on a team that can see the schema |
| Edit custom attributes | Update items, on the **schema-owning** team |
**Editing custom attributes isn't gated the same way as the default attributes on the same tab.** Default attributes (name, timezone, language, manager) are editable by the person themselves or any org admin. Custom attributes are entity writes, authorized against the team that owns the Users schema. An org admin who lacks item-edit permission on the owning team sees custom attributes as read-only while the default fields stay editable.
Both sections are read-only on a deactivated user's profile. System users show no default attributes at all, and their custom attributes are read-only.
## What's next
Field types, key fields, and how to change a schema after data is in place.
Connect an IdP and map its user payload onto your fields.
Build profile membership criteria from user attributes.
Control who can view and edit items, and trace every field change.
# Access for Users
Source: https://docs.serval.com/sections/documentation/end-user/end-user-access
How to request, extend, and manage access to applications
## Requesting Access
Request access through Slack, Teams, or app.serval.com. Serval guides you to the right access level, even if you don't know the specific role you need. For example, you may know you need Figma access but not whether that's Editor, Admin, or Group Admin.
**Request access two ways:**
1. **Natural language requests** through a conversational portal (Slack, Teams, or any help desk portal). You can make imperfect requests and Serval guides you to the correct type of access.
2. **Catalog in app.serval.com**: Click **New Request** → **Browse Catalog** → select **Access** → choose the application and role → fill in required details → click **Request access**
### Scheduling a Start Time
When you request access, you can choose a start time instead of right away. Set a start time on the request, and after it's approved, Serval provisions the access at that time rather than immediately. You can schedule up to 90 days out, and the start time can't be in the past.
This is useful when you know you'll need access on a specific future date, so the access is ready without anyone remembering to provision it manually. Common use cases include a project kickoff or a new hire's start date.
***
## Managing Active Access
Once your access request is approved and provisioned, you can manage it throughout its lifecycle. View your current access duration, time remaining, and expiration time directly in the access request card.
### Extending Access
Need more time? Request an extension before your access expires:
* **Via Slack/Teams**: Ask Serval to extend your access. For example: "Can I extend my AWS access for another hour?"
* **Via app.serval.com**: Open the ticket where you requested access and use the edit option to request more time.
You can request an extension even while your access is still being provisioned. The new duration takes effect once both provisioning completes and the extension is approved.
### Shortening Access
If you finish early and no longer need access, you can request to shorten it:
* Ask Serval to reduce your access time, or edit the duration in the access request card.
* Shortening access helps maintain least-privilege principles.
Both extensions and shortenings may require approval depending on your organization's access policies.
***
## Amending Requests Before Approval
Changed your mind about how long you need access? You can amend your request before it's approved:
1. Open the original ticket where you requested access.
2. Request a different duration (longer or shorter).
3. Your new request replaces the pending one.
The approver sees only your final requested duration. If you amend multiple times before approval, only the last amendment matters.
***
## Canceling Requests
You can cancel access requests at different stages:
If you no longer need the access you requested, cancel it before approval:
* Ask Serval to cancel the request, or use the Cancel button in the access request card.
* The entire access request is concluded and no access is granted.
If you requested an extension but changed your mind:
* Cancel the pending extension using the Cancel button.
* Your original access remains active with its current duration.
* Only the extension request is canceled, not your existing access.
***
## Reviewing Personal Access
View your personal access history from app.serval.com: Access sidebar → select "My Access" → View historical log of all access requests and relevant tickets.
Admins can create a workflow that lets you request a CSV download of all your historical access requests.
***
## Common Questions
When your access duration ends, Serval automatically revokes the access using the same method it was granted (removing you from a group, calling an API, etc.). You'll need to request new access if you need it again.
If your access recently expired but hasn't been fully deprovisioned yet, you may be able to extend it without starting a new request. Otherwise, you'll need to submit a new access request.
Approvers can modify the duration when approving your request. For example, you might request 2 hours but be approved for 30 minutes based on policy or business needs.
The access request card shows your current duration, time remaining, and expiration time. You can also ask Serval about your active access.
# End User Guide
Source: https://docs.serval.com/sections/documentation/end-user/end-user-guide
Your complete guide to getting help through Serval on day one and beyond
Welcome to Serval! This guide shows you how to get help from your company's support teams using Serval—an AI-powered help desk that makes getting assistance fast and easy.
The specific questions and workflows available to you depend on what your organization has configured. The examples below illustrate the types of requests you can make.
***
## How Serval Works
When you ask for help, Serval's AI assistant works to resolve your request:
1. **Understands your question** — Serval reads your message and determines what you need
2. **Searches for answers** — Checks your company's knowledge base and documentation and provides you with the proper answer or link to an article
3. **Automatically takes action** — Executes automations for common requests
4. **Connects you to a human** — Escalates to the right team member when needed, with full context
You'll always know what's happening—Serval keeps you informed throughout the process and tells you when a human takes over.
***
## Ways to Get Help
Depending on how your organization has configured Serval, you can reach out through multiple channels. Your admin will tell you which of these channels are configured and how they are named.
Message Serval directly in Slack or Microsoft Teams—either via DM, slash commands, or designated help channels
Send an email to your company's support address
Go to [app.serval.com](https://app.serval.com), log in, and submit a ticket directly. Confirm with your IT admin that you can directly access the portal
Your admin will let you know which channels are available at your organization.
### Routing Your Request
**If you know which team to contact:** Either use the designated Slack/team channel provided by your admin, or select the appropriate team from the dropdown menu (e.g., IT, HR, Operations) in app.serval.com.
**If you're not sure:** Just send your message via DM to Serval, relevant email, or [app.serval.com](https://app.serval.com)—Serval will automatically route your request to the right team based on your question.
### Submitting a Private Request
For sensitive requests—like salary questions, personal device issues, or HR matters—you have options to keep your conversation private:
* **Direct message the Serval bot** in Slack or Teams for a one-on-one conversation
* **Submit via the web portal** at [app.serval.com](https://app.serval.com) where only you and the support team can see it
* **Email** your support address directly
Private requests are only visible to you and the support team handling your ticket. Other employees in your workspace cannot see your conversation.
Learn about slash commands, message actions, @mentions, and other Slack-specific features
***
## What You Can Ask
The questions you can ask depend on which channel or team you're reaching out to. Here are common examples organized by team. This will differ across organizations:
**Software & Access**
* "I need access to \[application name]"
* "How do I install \[software]?"
* "I forgot my password"
* "Can I get access to the shared drive?"
* "I need a license for Figma/Notion/etc."
**Equipment & Devices**
* "My laptop is running slowly, can you help?"
* "I need to request a new monitor"
* "How do I connect to the office printer?"
* "My keyboard stopped working"
**Connectivity & Troubleshooting**
* "I can't connect to VPN"
* "WiFi isn't working in the office"
* "My email isn't syncing"
* "Two-factor authentication isn't working"
**Security**
* "I think I clicked on a phishing link"
* "How do I report a suspicious email?"
* "I need to encrypt a file"
**Benefits & Compensation**
* "Where can I find information about health benefits?"
* "How do I update my direct deposit?"
* "When is open enrollment?"
* "How do I access my pay stubs?"
**Time Off & Leave**
* "How do I request PTO?"
* "What's the parental leave policy?"
* "How many sick days do I have left?"
* "How do I request a leave of absence?"
**Policies & Documents**
* "Where's the employee handbook?"
* "What's the remote work policy?"
* "How do I update my emergency contact?"
* "Where do I find the expense policy?"
**Career & Development**
* "How do I sign up for training?"
* "When are performance reviews?"
* "How do I request a job title change?"
* "Where can I find internal job postings?"
**Office & Workspace**
* "How do I book a conference room?"
* "The AC isn't working on floor 3"
* "I need a standing desk"
* "Where are the office supplies?"
**Access & Badges**
* "I lost my office badge"
* "Can I get visitor access for a guest?"
* "How do I get building access after hours?"
* "I need parking garage access"
**Travel & Expenses**
* "How do I book travel?"
* "What's the process for expense reimbursement?"
* "I need a corporate card"
* "Where do I submit receipts?"
**Equipment & Supplies**
* "I need office supplies ordered"
* "How do I request new furniture?"
* "The coffee machine is broken"
These are just examples. Your organization may have custom workflows for specific requests—just ask naturally, and Serval will guide you through the process!
***
## Tips for Getting the Best Help
Include relevant details upfront. Instead of "I need access," try "I need access to the AWS production account for the analytics project."
Mention what you've already tried, any error messages you're seeing, or deadlines that are relevant. This helps get you a faster resolution.
If you have multiple unrelated requests, submit them separately so each gets tracked and resolved properly.
Continue your conversation in the same thread. Serval remembers context from earlier messages.
Serval uses emojis to show status:
* ⏳ Working on your request
* ✅ Successfully completed
* ❌ Cancelled or unable to complete
***
## What to Expect
### Instant Answers
For common questions, Serval pulls answers directly from your company's knowledge base. You'll get a response in seconds with links to relevant documentation.
### Automated Workflows
For requests like access provisioning, software installation, or common IT tasks, Serval can handle the entire process automatically—including getting approvals if needed.
### Human Support
When Serval can't resolve something automatically, it creates a ticket and routes it to the right team. You'll be notified when a human agent picks up your request, and you can continue the conversation naturally.
Even when a human takes over, everything stays in the same conversation thread. No need to repeat yourself!
***
## Checking Your Request Status
You can check on your requests in several ways:
* **Ask Serval directly**: "What's the status of my access request?"
* **Check your conversation thread**: Status updates appear in your original conversation
* **Web portal**: If your company has enabled it, visit the Serval web portal to see all your tickets
***
## Common Questions
When you DM Serval, your request is visible only to you and the support team handling it. Others cannot see your conversation.
Serval always identifies itself as an AI assistant. When a human agent joins the conversation, you'll receive a notification letting you know.
Yes! You can attach images, screenshots, logs, or documents directly in your conversation with Serval.
Try rephrasing your request with more specific details. If Serval still can't help, it will automatically escalate to a human agent.
Yes, just tag @Serval and say "cancel this request" or "never mind" in your conversation thread, and Serval will close the ticket.
Yes. In the web portal, click the globe icon in the top bar and choose a language. Available languages are English, German, Spanish, French, French (Canada), Japanese, Portuguese, Portuguese (Brazil), and Russian. Your choice is saved to your account.
# AI Tools (MCP)
Source: https://docs.serval.com/sections/documentation/end-user/mcp-quickstart
Connect Claude and other AI assistants to Serval
You can connect AI assistants like Claude directly to Serval. Once connected, you can create tickets, run workflows, check request status, look up people, and more — all through natural conversation with your AI assistant.
Your admin may need to enable MCP access for your organization. If you don't see a way to connect, ask your IT admin.
***
## How It Works
1. **Configure** your AI tool with Serval's server URL (one-time setup)
2. **Approve access** through your browser when the tool first connects
3. **Ask naturally** — your AI assistant calls Serval on your behalf
***
## Setup
### Find your server URL
Each Serval region runs its own MCP server. Pick the server URL that matches the address you use to sign in to Serval:
| Your Serval sign-in address | Server URL |
| - | - |
| `app.serval.com` or `.serval.com` | `https://public.api.serval.com/mcp/` |
| `app.eu1.serval.com` or `.eu1.serval.com` | `https://public.eu1.serval.com/mcp/` |
The US server URL sends EU organizations to `app.serval.com` for approval, where they cannot sign in. See [Data residency](/sections/documentation/platform/data-residency) for details on regions.
### Connect your AI tool
Your organization admin may have already added Serval as a connector. Check **Settings > Connectors** to see if it's available.
If you need to add it yourself:
1. Go to **Settings > Connectors**
2. Click **Add custom connector**
3. Enter a name (e.g., "Serval") and the server URL for your region:
```
https://public.api.serval.com/mcp/
```
EU organizations use `https://public.eu1.serval.com/mcp/` instead.
4. Your browser will open to approve access to your Serval account
5. After approval, Serval tools are available in your conversations
Custom connectors require a Pro, Team, or Enterprise plan.
Add the following to your Claude Desktop config file:
* **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
* **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
```json theme={null}
{
"mcpServers": {
"serval": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://public.api.serval.com/mcp/"]
}
}
}
```
EU organizations replace the server URL with `https://public.eu1.serval.com/mcp/`.
Restart Claude Desktop. On first use, your browser will open to approve access.
Node.js v18+ is required. Install it with `brew install node` (macOS) or `winget install OpenJS.NodeJS` (Windows) if you don't have it.
Any AI tool that supports MCP can connect to Serval. Set the server URL for your region:
```
https://public.api.serval.com/mcp/
```
EU organizations use `https://public.eu1.serval.com/mcp/` instead.
Your client will discover authentication endpoints automatically and open your browser to approve access.
***
## Approving Access
The first time your AI tool connects, your browser will open an approval page. Click **Approve** to grant access. Your AI tool can only do what you can do in Serval — it uses your account and permissions.
You won't need to re-approve unless you revoke access or your token expires.
***
## What You Can Ask
Once connected, just talk to your AI assistant naturally. For example:
* "Create a ticket — I can't connect to VPN"
* "What's the status of my laptop request?"
* "Show my pending access requests"
* "Update my ticket to say I've restarted the router"
If your role includes running workflows (team contributors and above), your assistant can also find and run them directly — for example, "Run the software license request workflow for Figma." Workflows that require approval still go through their normal approval process — your assistant starts the request, and approvers are notified as usual.
Your AI assistant uses your account and permissions, so it can only access your own tickets, requests, and data. The available actions depend on what your organization has configured.
***
## FAQ
No. Any Serval user can connect their AI tools. You'll use your own account and permissions.
The Serval MCP server is included with your Serval plan. You'll need your own AI tool subscription (e.g., Claude Pro).
No. Your AI tool has the same access you do. It cannot see tickets or data that you wouldn't normally have access to.
Remove the Serval configuration from your AI tool's settings. This immediately stops the connection.
MCP (Model Context Protocol) is an open standard that lets AI assistants connect to external services like Serval.
***
## Troubleshooting
Node.js is not installed or not visible to Claude Desktop. Install it globally (`brew install node` on macOS), then restart Claude Desktop.
Check MCP logs on macOS:
```bash theme={null}
tail -n 50 ~/Library/Logs/Claude/mcp-server-serval.log
```
Common causes: expired token or network issue reaching `public.api.serval.com` (or `public.eu1.serval.com` for EU organizations).
Your AI tool is configured with the US server URL. Change it to `https://public.eu1.serval.com/mcp/` and connect again. The approval page then opens on `app.eu1.serval.com`.
The same applies in reverse: a US organization configured with the EU server URL is sent to `app.eu1.serval.com`, where it cannot sign in.
***
## Related
Technical details and full tool list
Other ways to get help through Serval
# Slack for Users
Source: https://docs.serval.com/sections/documentation/end-user/slack-quickstart
Quick-start guide for getting help from Serval in Slack
## Quick Start
Serval provides AI-powered help desk support directly in Slack. Choose any of these methods to create a ticket and start a conversation with Serval:
**Use from anywhere in Slack**
Type `/serval help` followed by your request in any channel or DM:
```
/serval help I need access to the AWS production account
```
This works anywhere in Slack as long as Direct Messaging is enabled by your Serval administrators.
**Turn any message into a ticket**
1. Hover over any Slack message
2. Click the **...** (three dots) menu
3. Select **"Create a ticket"** using Serval
Perfect for when someone describes an issue in a message and you want to track it without asking them to retype it.
**Use your team's support channel**
If your organization has configured helpdesk channels (like `#it-support`):
1. Go to the helpdesk channel
2. Start a new thread with your request
3. Serval automatically responds and creates a ticket
No need to tag @Serval - it monitors all new threads in helpdesk channels.
Each of these methods will create a ticket for your IT request and start a conversation with Serval to help resolve your issue.
***
## Having a Conversation with Serval
Once Serval responds to your ticket, you can have a natural conversation:
### What You Can Do
* **Ask follow-up questions**: "What is the latest status of this request?"
* **Update status**: "This is resolved now, thanks!"
* **Share files**: Drag screenshots or logs directly into the thread
* **Mention teammates**: Tag others if they need to be involved
### Keep It in the Thread
* **Reply in the same thread** for follow-ups on the same topic
* Serval remembers the full conversation context
* Your support team can see what's been discussed
If you mention another person, Serval will step back to allow for discussion. Tag `@Serval` so it knows to re-engage!
### Track Progress
Watch for emoji reactions on your messages:
* ⏳ Serval is working on it
* ✅ Successfully completed
* ❌ Cancelled
Serval also updates the status in each Slack thread, and includes a ticket link so that you can see full details in the Serval web interface if needed.
***
## Tips for Best Results
Include key details right away: error messages, usernames, system names, what you've already tried.
**Example:** "I'm getting 'Invalid credentials' when logging into the customer portal with [john@company.com](mailto:john@company.com)"
Create separate tickets for different problems. This helps tracking and makes it easier for your support team.
Keep all conversation about one issue in the same thread. Serval and your support team maintain full context this way.
No special commands needed - just explain your issue as you would to a colleague.
***
## Want to Learn More?
Complete reference for all interaction methods, thread management, workflows, and advanced features
For administrators: How to configure Slack channels, Team Inbox, and integration settings
## Related Documentation
* [Comprehensive Guide to Slack](/sections/documentation/helpdesk/interacting-with-serval-in-slack) - Complete reference with advanced features
* [Ticketing Overview](/sections/documentation/ticketing/overview) - Understanding the ticket system
* [Slack Integration](/sections/integrations/slack) - Setup and configuration for administrators
# Submit a Request
Source: https://docs.serval.com/sections/documentation/end-user/submit-request
How to create tickets and get help from your IT, HR, or support teams
As an employee, you can submit requests to get help from your organization's support teams. Serval makes it easy to ask for what you need in plain language—no forms or ticket numbers required.
***
## Ways to Submit a Request
Submit requests through whichever channel your organization has enabled—Serval routes everything to the same ticketing system regardless of source.
See all available channels and how to configure them
***
## Submitting a Request in Slack or Teams
The fastest way to get help is through your messaging platform. Simply message the appropriate support channel with your request. The experience is the same in Slack and Microsoft Teams.
Look for channels like `#it-help`, `#hr-requests`, or `#facilities`. Your organization may have different channel names.
Write your request in plain language. Be specific about what you need and include any relevant details.
**Good examples:**
* "I need access to the Figma design files for the marketing team"
* "My laptop is running slow and apps keep crashing"
* "Can I get a standing desk for my home office?"
Include context like urgency, deadlines, or who else is affected. This helps your support team prioritize.
Serval will acknowledge your request and may:
* Resolve it automatically using available information or workflows
* Ask clarifying questions to better understand your needs
* Route it to the right team member if human assistance is needed
You'll receive updates in the same thread. You can also view all your requests at app.serval.com.
***
## Submitting a Request in the Web App
You can also submit requests directly at app.serval.com.
When **Home** is enabled for your organization, it replaces **New request** in
personal and global navigation. If you can create tickets, start and send a
request under **What do you need help with?** on Home. Use the request editor and
team picker, and select a team to attach files. The **Access**, **Service Catalog**,
and **Knowledge** shortcuts sit below the editor
and follow your permissions and organization settings. Ongoing issues and journeys
appear next. Your **My tickets** and **Assigned to me** tabs appear beside approvals
and Inbox updates on wide screens. On narrow screens, approvals and Inbox updates
appear before your tickets.
Active journey progress refreshes while you view Home, and completed journeys leave
the overview after the next refresh.
When Home isn't enabled, **New request** keeps its existing page or dialog
behavior. The separate request-dialog feature controls that choice and team
ticket creation. Enabling Home doesn't enable that dialog or change the existing
request page's catalog options. Home keeps its own request draft.
Log in with your company credentials.
Open **Home** where enabled, or **New request**. You have two options:
* **Describe your request**: Type what you need in the chat input using plain language. You can attach files, @mention users, add checklists, and insert tables.
* **Attach files**: Click the attachment icon to upload files relevant to your request (screenshots, documents, spreadsheets, or any other file type)
* **@mention users**: Type `@` to mention specific people who should be aware of your request
* **Insert tables**: Use standard Markdown pipe syntax (`| Column | Column |`) to create structured tables in your request
* **Browse the Catalog**: Select **Browse Catalog** to choose from predefined catalog items. Pick **Access** to request role-based access to applications, or **All Services** to browse catalog items like new laptop orders, software installations, or other structured requests.
Serval automatically routes your request to the right team based on your message. You can also manually select a team from the dropdown. If you're viewing a specific team's tickets, that team is pre-selected for you.
Your request is created and you can track its progress in the web app.
Use the Catalog when you know the type of request you need. Catalog items provide structured forms that capture the right information upfront, which helps your support team resolve requests faster.
***
## Tips for Faster Resolution
Include details like application names, error messages, or dates. The more context, the faster the resolution.
Submit separate requests for unrelated issues. This helps teams track and prioritize effectively.
Respond promptly when Serval or a team member asks follow-up questions.
IT issues go to IT channels, HR questions to HR channels. This ensures your request reaches the right team.
***
## What Happens Next
After you submit a request:
1. **Serval analyzes your request** - AI determines the type of request, priority, and which team should handle it
2. **Automatic resolution** - For common requests, Serval may resolve it immediately using knowledge base articles or workflows
3. **Human escalation** - Complex issues are assigned to a team member who will follow up with you
4. **Resolution** - You'll be notified when your request is complete
You'll receive all updates in the same place you submitted your request—the same thread, email chain, or web app view.
***
## Creating Standard Tickets for Testing
Team members can create standard help desk tickets (instead of internal execution tickets) for testing purposes. This is useful when you want to verify how the help desk agent handles a specific request—the ticket flows through the same routing, AI triage, and workflow logic that an end user's request would.
***
## Viewing Your Requests
To see all your submitted requests:
1. Go to **app.serval.com**
2. Click **My Requests** in the navigation
3. View status, updates, and history for each request
# Microsoft Teams for Users
Source: https://docs.serval.com/sections/documentation/end-user/teams-quickstart
Quick-start guide for getting help from Serval in Microsoft Teams
## Quick start
Serval provides AI-powered help desk support directly in Microsoft Teams. You can post in your team's support channel, summon Serval in a Silent Mode channel, and make a private request in DM. Each method creates a ticket for your request and starts a conversation with Serval to help resolve your issue.
**Post in your team's support channel**
In a Help Desk channel, post your request as a new message:
```text theme={null}
Can you help me reset my password?
```
Serval responds automatically and creates a ticket. Serval monitors every new message in Help Desk channels, so you don't need to tag `@Serval` directly.
If Serval doesn't respond, the channel may not be connected yet. An admin can add Serval and set the channel mode. For more information, see [Connect channels](/sections/integrations/microsoft-teams#connect-in-serval).
**Summon Serval in a Silent Mode channel**
In a Silent Mode channel, Serval files messages quietly and only replies when you ask. Mention `@Serval` to get a response:
```text theme={null}
@Serval can you help me reset my password?
```
**Make a private request in a DM**
For personal or sensitive requests, message Serval directly. Serval reads your message and routes it to a new or existing ticket.
To create a ticket using an explicit form, type `/create-ticket` in your DM. Serval opens a short form where you describe your request, pick a team (or leave it on **Auto-detect** to have Serval automatically select the correct team), and choose who the ticket is for.
## Having a conversation with Serval
Once Serval responds, you can have a natural conversation.
### What you can do
* **Escalate ticket to a human**: Simply say "Escalate"
* **Ask follow-up questions**: "What's the latest status of this request?"
* **Update status**: "This is resolved now, thanks!"
* **Share files**: Attach screenshots or logs directly in the conversation
* **Trigger workflows**: "Run the new user onboarding workflow for [jane@company.com](mailto:jane@company.com)" (For more information, see [Workflows](/sections/documentation/workflows/overview))
* **Handle approvals and forms**: Serval provides interactive cards with buttons and fields directly in your chat
### Keep it in the thread
For follow-ups on the same topic in a specific channel, reply in the same thread. Serval remembers the full conversation context, and your support team can see what's been discussed.
If another person replies in the thread, Serval steps back to let the humans talk. Tag `@Serval` so it knows to re-engage.
### In direct messages
Microsoft Teams doesn't support threads in direct messages, so a few habits help Serval route your messages to the right ticket:
* **Explicitly signal a new request** **when you want a new ticket.** For example, New request: I need a license for Figma.
* **Reference the existing issue** **when following up.** For example, Following up on my laptop replacement request.
* **Reply with quote** **on the Serval message for the ticket you mean**. Useful for short follow-ups like "any update?" when several tickets are open.
If your message could apply to more than one open ticket, Serval sends a card listing the tickets it thinks you mean, where you can select the right one or start a new ticket.
### Track progress
* While Serval is working on an issue in a conversation, a typing indicator or a progress card shows that it's active.
* Serval updates the ticket status in its messages and provides a ticket link.
## Tips for best results
* Include key details like error messages, usernames, system names, and what you've already tried. For example:
```text theme={null}
I'm getting 'Invalid credentials' when logging into the customer portal with john@company.com.
```
* Create separate tickets for different problems. This helps both Serval and your support team keep track of everything.
* In a channel, keep all conversation about one issue in the same thread.
* In a direct message, clearly signal when you're starting a new request so Serval doesn't fold it into an open ticket.
* Explain your issue conversationally, as you would to a colleague.
## Related documentation
* [Comprehensive Guide to Microsoft Teams](/sections/documentation/helpdesk/interacting-with-serval-in-microsoft-teams) - Complete reference with advanced features
* [Ticketing Overview](/sections/documentation/ticketing/overview) - Understanding the ticket system
* [Microsoft Teams Integration](/sections/integrations/microsoft-teams) - Setup and configuration for administrators
# Track Your Requests
Source: https://docs.serval.com/sections/documentation/end-user/track-requests
View status updates and manage your submitted requests
After submitting a request, you can track its progress, add information, and communicate with the support team.
***
## Viewing Your Requests
### In Slack or Teams
If you submitted your request in Slack or Teams, all updates appear in the same thread:
* Status changes (for example, **In Progress** or **Resolved**)
* Messages from support team members
* Requests for additional information
* Resolution details
Turn on notifications for the thread to stay updated on your request.
### In the Web App
For a complete view of all your requests:
1. Go to **app.serval.com**
2. Navigate to **My Requests**
3. See all your tickets with current status
Where enabled, **Home** replaces **New request** in personal and global navigation. Select **My tickets** on Home to review your requests.
Use **Search tickets** or the filters to narrow the list, and scroll within the
ticket list to load more results. Open a ticket to view its details or add a reply.
On **Home**, select **View all** to open the full ticket list with the same **My tickets** or
**Assigned to me** selection, search text, and filters. You can change or remove
those filters in the full list without changing your saved Tickets view. When Home
isn't enabled, Tickets continues to use your existing saved view.
On **Home**, select **Ongoing issues** to view details for up to three active major
incidents you have access to, with the most recently updated first. Select an
incident card to open it. Ticket search and filters don't change this section.
Resolved and canceled incidents no longer appear.
***
## Viewing Your Conversations with Serval
Where your organization has enabled the personal help desk, the direct-message conversations you have with Serval in Microsoft Teams also appear in the web app under **Conversations**, next to **Tickets** in your personal sidebar.
A conversation isn't a ticket. It's the ongoing chat you have with Serval, and it's where tickets get raised from. When Serval hands your request to a team, the resulting ticket appears next to the message that raised it, so you can jump straight to the request itself. Only tickets you have access to are shown. A ticket that no message in the conversation raised, such as one linked when Serval continued the conversation from a notification, appears at the top under **Tickets from this conversation**.
### One conversation, two places
The web view and the Teams chat are the same conversation, not two copies of it:
* **Messages you send in Teams**: appear in the web app.
* **Messages you send in the web app**: appear in the Teams chat, so your history stays in one piece and Serval answers in both places.
A conversation closes once it's been idle for a while. You can still read a closed conversation, but you can't reply to it. Message Serval in Teams to start a new one.
***
## Understanding Request Status
Your request moves through different stages as it's being handled:
| Status | What It Means |
| :- | :- |
| **New** | Your request was received and is awaiting review |
| **In Progress** | A team member or Serval is actively working on it |
| **Waiting on You** | The team needs more information from you |
| **Resolved** | Your request has been completed |
| **Canceled** | The request was closed without completion |
Status names may vary depending on how your organization has configured their ticketing workflow.
***
## Connect an account to continue a request
Some integrations, including external agents, need permission to act through your own account. When Serval asks you to connect an account, open the connection link and complete the authorization.
If your request is still open and the AI agent is active, it continues automatically after you connect all the required accounts. You don't need to return to the ticket and send another message. This works for requests in the web app, Slack, Microsoft Teams, and WhatsApp, even if you close the authorization tab afterward.
Automatic continuation is available for seven days after the workflow asks you to connect. It doesn't restart a resolved, canceled, archived, or deleted ticket, take over from a paused AI agent, or repeat a workflow you've already retried. If someone else posts or edits a reply while authorization is pending, automatic continuation stops; the original requester can send a new message to continue. Workflows you run outside a ticket still need to be run again after connecting.
***
## Adding Information to a Request
If you need to provide more details or the team asks for additional information:
### In Slack or Teams
Simply reply in the same thread where you submitted the request. Your message will be added to the ticket.
### In the Web App
1. Open your request from **My Requests**
2. Type your message in the conversation area
3. Send to add it to the ticket
If you start a new thread or message instead of replying to the original, it may create a new request instead of updating the existing one.
***
## Common Actions
Look for the SLA indicator on your ticket. This shows the expected resolution time frame based on priority. Higher priority requests are resolved faster.
If your request is time-sensitive, reply in the thread or ticket and explain the urgency. Include details like:
* Why it's urgent
* What deadline you're facing
* Who else is impacted
The support team will adjust priority accordingly.
If your issue resolved itself or you no longer need help, let the team know by replying "This is no longer needed" or "I figured it out, thanks!" The team will close the request.
If your issue comes back after being marked resolved, reply to the original thread or ticket. The request will be reopened for the team to investigate.
***
## Getting Help Faster
When the team asks for information, responding promptly keeps your request moving forward
If you'll be out of office, mention it so the team can plan accordingly
Screenshots, error messages, and specific details help the team resolve issues faster
When asked for feedback, your response helps improve the support process
# Create a form
Source: https://docs.serval.com/sections/documentation/forms/create-a-form
Describe a form to Catalyst, preview it live, and publish it to the service catalog.
## Build it
Go to **Service Management → Forms → New form**. Serval opens the **Create a new form** gallery with three ways to start:
* Describe your form in the top **Create a form that…** box and let Catalyst build it (the path this guide follows).
* Under **Or start from a working form**, pick a ready-made template such as a laptop request, expense claim, or discount approval. Each template comes with a working submit workflow, so you can submit the new form right away and edit it from there.
* Choose **Create blank form** to open an empty **Untitled form**.
Whichever you choose, Serval opens the workspace on your new form.
Be specific about the questions, the options, and what happens on submit:
> Create a laptop request form. Options should be MacBook Air, MacBook Pro 14-inch, Lenovo ThinkPad, and Dell Latitude, shown as cards with product photos. Require a business justification. Let people optionally say who it's for and when they need it. On submit, file an IT ticket with the chosen model.
Keep talking to Catalyst: "make the justification field longer," "only ask for a manager if it's for someone else." Each change re-renders the preview.
Name the form before publishing. The name is what employees see in the catalog and what the Help Desk Agent reads to decide the form fits a request. "Laptop Request" beats "IT Form 2."
## The workspace
| Area | What it does |
| :- | :- |
| **Preview** | The real form, rendered by the real engine |
| **Can be opened by** | Which employees may open and submit it. See [audience](/sections/documentation/forms/share-and-fill#control-who-can-open-a-form) |
| **Runs inside the form** | Workflows called while the form is open, to fetch live data |
| **Runs on submit** | The workflow that receives the answers |
| **Version selector** | Switch versions, and see which one is published |
| **Publish** | Deploys the current draft |
| **Run history** | Every session, and the runs it started |
| **Open in service catalog** | The published form, exactly as employees see it |
| **Code (`>`)** | The form's source |
## Preview and publish
The preview is a live session against your draft. Conditional fields appear, validation fires, and live-data workflows run.
A preview submit runs the latest submit workflow **for real**, even as an unpublished draft. It doesn't publish your drafts, but side effects still happen: a ticket, provisioned access, a message.
Edits autosave to a draft. The action bar shows **Unpublished changes** when your draft differs from what's live. Click **Publish** to deploy it.
Publishing never disturbs a submission in progress. A session stays on the version it opened against.
If a publish fails, the error names the problem in the code: an unknown option, an invalid icon name, a workflow reference that doesn't resolve.
## The code behind a form
Catalyst writes it, and most builders never open it. It's under the `>` button when you want it.
```tsx theme={null}
import { view, field, Form } from "serval/forms";
import orderLaptop from "@serval/workflows/order-laptop";
export const main = view({
fn: () => {
const [model, Model] = field.cards("model", [
{ value: "mba", label: "MacBook Air (M-series)", description: "Lightweight macOS laptop for everyday work and travel." },
{ value: "mbp", label: "MacBook Pro 14-inch", description: "High-performance macOS laptop for engineering and design." },
], { label: "Choose your laptop" });
const [justification, Justification] = field.text("justification", {
label: "Business justification",
multiline: true,
maxLength: 500,
});
return (
);
},
});
```
* **`field.(key, …)`**: declares a question, returns `[value, Component]`
* **`
```
Colors and icons come from fixed lists, so forms match the rest of the product and render correctly everywhere, including Slack. An unrecognized name fails at publish instead of rendering nothing.
***
Conditional fields and live data from your systems.
Where forms appear and how each surface renders them.
# Logic and workflows
Source: https://docs.serval.com/sections/documentation/forms/logic-and-workflows
Show fields conditionally, pull live data while the form is open, and hand the answers to a workflow.
A form re-renders every time an answer changes, so it can ask different questions, fetch real data, and validate across fields before anything is submitted.
Two kinds of workflow connect to a form, and the workspace shows both:
| Workspace card | When it runs | What it's for |
| :- | :- | :- |
| **Runs inside the form** | While the form is being filled in | Fetching live data to show or shape the questions |
| **Runs on submit** | Once, on submit | Doing the work the request asked for |
## Conditional questions
A field's current answer is an ordinary value, so logic is ordinary code. No rule builder, no separate condition language.
```tsx theme={null}
const [forSomeoneElse, ForSomeoneElse] = field.boolean("for_someone_else", {
label: "Is this for someone else?",
});
const [recipient, Recipient] = field.user("recipient", { label: "Who's this for?" });
return (
);
```
| Goal | How |
| :- | :- |
| Show a field only when relevant | Render it inside a condition |
| Require a field only sometimes | `` |
| Narrow one field's options by another | Filter the entity or user picker on the other field's answer |
| Warn about a combination | Render a `` when it occurs |
| Reject a combination | Set `error` on the field. A non-empty error blocks submit |
Ask Catalyst for the behavior, not the code: "only ask for a manager when the request is for someone else." Then check it in the preview.
## Live data inside the form
A form can call one of your workflows while it's open and render the result: stock levels, license counts, an employee's current device, a price.
```tsx theme={null}
import { runWorkflowMemoized } from "serval/forms";
import checkLaptopStock from "@serval/workflows/check-laptop-stock";
const stock = runWorkflowMemoized(checkLaptopStock, { model });
return (
);
```
* **Results are cached per set of arguments.** The call runs once for each distinct set. Change the selected model and it runs again. Change an unrelated field and it doesn't run at all. Calling it from the render is cheap, not a request per keystroke.
* **The form stays usable while it's in flight**, then re-renders with the result.
Query workflows should be read-only. They run whenever their arguments change, including in previews, so anything that creates or modifies belongs in the submit workflow instead.
Every run a form starts, query runs included, appears under **Form activity**.
## The submit workflow
```tsx theme={null}