AI Integration & Data Handling
Integration design and exact data payloads for SN Utils AI features — written for security reviews and vendor onboarding.
Last updated: June 19, 2026
Last updated: June 19, 2026
This page is the integration design reference for the AI features in SN Utils. It is written for security reviewers, procurement, and vendor-onboarding teams who need to know exactly how the extension talks to a Large Language Model (LLM) and what data is included in each request. It complements the high-level Security & Privacy overview and the Privacy & Data Processing Agreement.
There are two user-facing AI features:
| Feature | Where it runs | What it's for |
|---|---|---|
| Sidekick AI | In-page assistant (Picture-in-Picture) on a ServiceNow tab | Scripting help and platform questions, aware of the current page |
| AI Command Builder | The SN Utils Manage page (an extension page) | Generating slash commands and code snippets from natural language |
Both follow the same integration principle:
ServiceNow tab / Manage page
│ (user clicks Send / Generate)
▼
SN Utils extension ──HTTPS + Bearer token──▶ https://snutils.com/api/extension/ai/*
│
▼
LLM provider (OpenAI / Anthropic / Google)
The extension's Content Security Policy restricts outbound connections to https://*.service-now.com (the user's own instance) and https://snutils.com. There is no LLM-provider host in the allow-list, which makes a direct call impossible by design.
| Endpoint | Method | Used by |
|---|---|---|
https://snutils.com/api/extension/ai/sidekick | POST | Sidekick AI |
https://snutils.com/api/extension/ai/generate | POST | AI Command Builder |
Both require a valid Authorization: Bearer <token> header, are served over TLS, stream their responses as Server-Sent Events, and are rate-limited to 50 requests per hour per user.
When Sidekick AI is enabled (it is opt-in, off by default), each request contains the chat messages plus a small metadata-only context object describing the current page. No field values or record data are included.
The context object can contain:
form, list, flow, script_editor, workspace, record, or unknown.incident, when detectable from the page.sys_*, sysparm_*) are filtered out. Names only, never values.Default).location.pathname only. Query strings, hash fragments, and any record sys_id in the URL are not included.dev12345 from dev12345.service-now.com), so the assistant can distinguish between instances. The full hostname is not sent.{
"messages": [
{
"role": "user",
"content": "Write a GlideRecord query for open incidents assigned to me"
}
],
"context": {
"pageType": "form",
"tableName": "incident",
"fieldNames": [
"number",
"short_description",
"state",
"assigned_to",
"priority"
],
"formView": "Default",
"urlPath": "/incident.do",
"hostname": "dev12345",
"tier": "metadata"
},
"model": "claude-sonnet-4-6"
}
The
hostnamefield carries only the instance subdomain label, not the fully qualified domain. Thetieris fixed tometadatain the current product; a future opt-in "full context" tier would be disabled by default and require explicit consent.
The AI Command Builder generates slash commands and snippets. A request contains:
The full prompt is capped at ~3,900 characters client-side.
When you generate a command whose URL targets a detectable table, the builder asks the LLM to use real field names. To do that it reads the table's field dictionary from an open ServiceNow tab — using your existing session and permissions — and includes a compact schema block in the prompt:
sys_dictionary for the table and its ancestors and sends field name, label, internal type, and the display flag — never any record values.{
"prompt": "TABLE METADATA — incident (live from instance)\nDisplay field: number\nAvailable fields (name [type] label):\n- number [string] Number *display*\n- short_description [string] Short description\n- state [integer] State\n- assignment_group [reference] Assignment group\nWhen generating \"fields\", use ONLY names from the list above.\n\nCURRENT COMMAND IN FORM:\n{\n \"command\": \"\",\n \"hint\": \"\",\n \"description\": \"Search incidents by assignment group\",\n \"script\": \"\",\n \"fields\": \"number,short_description\",\n \"overwrite_url\": \"\",\n \"inline_only\": false\n}\n\nUSER REQUEST: search incidents by assignment group and show priority",
"type": "command",
"stream": true,
"messages": [
{
"role": "user",
"content": "Create a command to search incidents by assignment group"
}
],
"model": ""
}
The schema block lists field names, labels, and types only. An empty
modelmeans the server picks the default model.
Across both features, the following never leaves the browser as part of an AI request:
GlideRecord values, no sys_ids, no field values from any record.If you want the AI to reason about a specific value, script, or error message, you paste it into the chat yourself — keeping you in control of exactly what is shared.
Bearer token. Tokens live in the browser's extension storage and are never exposed to the ServiceNow page context.The backend routes each request to an LLM provider based on the selected model. Providers currently include OpenAI, Anthropic, and Google. Users may pick a model (or leave it on Auto, the recommended default):
The authoritative list of sub-processors, along with their processing locations and retention terms, is maintained in the Privacy & Data Processing Agreement.
| Control | Behavior |
|---|---|
| Availability | Pro only; AI code is stripped from the Community build |
| Sidekick AI | Opt-in, off by default |
| Trigger | Explicit user action only — nothing sent in the background |
| Direct LLM access from extension | None — all traffic proxied through snutils.com |
| Record data to LLM | Never |
| Rate limit | 50 requests/hour/user |
| Fully disconnected option | Available for strict environments — see autonomous operation |